Skip to content

Commit 04e6e55

Browse files
author
David Sheldrick
committed
set up initial transformer framework
0 parents  commit 04e6e55

File tree

9 files changed

+6079
-0
lines changed

9 files changed

+6079
-0
lines changed

.gitignore

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (http://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# Typescript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+
60+
dist

.vscode/settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
"search.exclude": {
4+
"**/node_modules": true,
5+
"**/bower_components": true,
6+
"dist": true
7+
},
8+
"editor.formatOnPaste": true,
9+
"prettier.semi": false,
10+
"prettier.trailingComma": "all",
11+
"editor.formatOnSave": true
12+
}

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 David Sheldrick
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

package.json

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "react-native-obfuscating-transformer",
3+
"version": "1.0.0-0",
4+
"description": "Obfuscating transformer for react-native",
5+
"main": "dist/index.js",
6+
"repository": "https://github.com/ds300/react-native-obfuscating-transformer",
7+
"author": "David Sheldrick",
8+
"license": "MIT",
9+
"dependencies": {
10+
"@types/babel-core": "^6.25.3",
11+
"@types/node": "^9.3.0",
12+
"@types/semver": "^5.4.0",
13+
"app-root-path": "^2.0.1",
14+
"jju": "^1.3.0",
15+
"semver": "^5.4.1",
16+
"source-map": "^0.6.1"
17+
},
18+
"peerDependencies": {
19+
"react-native": ">=0.45.0"
20+
},
21+
"scripts": {
22+
"precommit": "tsc && lint-staged",
23+
"test": "jest"
24+
},
25+
"lint-staged": {
26+
"*.ts": ["prettier --no-semi --single-quote --trailing-comma es5"]
27+
},
28+
"devDependencies": {
29+
"babel-preset-react-native": "^1.9.1",
30+
"husky": "^0.13.3",
31+
"jest": "^22.0.6",
32+
"lint-staged": "^3.4.1",
33+
"metro": "^0.24.3",
34+
"metro-bundler": "^0.9.0",
35+
"np": "^2.15.0",
36+
"prettier": "^1.10.2",
37+
"react-native": "^0.45.1",
38+
"ts-jest": "^22.0.1",
39+
"typescript": "^2.6.2"
40+
},
41+
"jest": {
42+
"transform": {
43+
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
44+
},
45+
"testRegex": "src/.*(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
46+
"moduleFileExtensions": ["ts", "tsx", "js"]
47+
}
48+
}

src/getCallerFile.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This code taken from https://stackoverflow.com/a/29581862/1382997
2+
// Question by einstein https://stackoverflow.com/users/449132/einstein
3+
// Answer by Rhionin https://stackoverflow.com/users/1751376/rhionin
4+
export function getCallerFile() {
5+
const originalFunc = Error.prepareStackTrace
6+
7+
let callerfile
8+
9+
try {
10+
const err = new Error() as any
11+
var currentfile
12+
13+
Error.prepareStackTrace = function(_, stack) {
14+
return stack
15+
}
16+
17+
currentfile = err.stack.shift().getFileName()
18+
19+
// go up two places in the stack trace. i.e. out of this file, and out of index.ts
20+
for (let i = 0; i < 2; i++) {
21+
while (err.stack.length) {
22+
callerfile = err.stack.shift().getFileName()
23+
24+
if (currentfile !== callerfile) break
25+
}
26+
27+
currentfile = callerfile
28+
}
29+
} catch (e) {}
30+
31+
Error.prepareStackTrace = originalFunc
32+
33+
return callerfile
34+
}

src/getMetroTransformer.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Node } from "babel-core"
2+
import { RawSourceMap } from "source-map"
3+
import * as semver from "semver"
4+
5+
export interface MetroTransformer {
6+
transform(props: {
7+
filename: string
8+
src: string
9+
options: object
10+
}): { ast?: Node; code?: string; map?: string | RawSourceMap }
11+
getCacheKey?(): string
12+
}
13+
14+
export function getMetroTransformer(): MetroTransformer {
15+
const reactNativeVersionString = require("react-native/package.json").version
16+
17+
const parseResult = semver.parse(reactNativeVersionString)
18+
19+
if (!parseResult) {
20+
throw new Error(
21+
`Can't parse react-native version string '${reactNativeVersionString}'`,
22+
)
23+
}
24+
25+
const reactNativeMinorVersion = parseResult.minor
26+
27+
if (reactNativeMinorVersion >= 52) {
28+
return require("metro/src/transformer")
29+
} else if (reactNativeMinorVersion >= 0.47) {
30+
return require("metro-bundler/src/transformer")
31+
} else if (reactNativeMinorVersion === 0.46) {
32+
return require("metro-bundler/build/transformer")
33+
} else {
34+
throw new Error(
35+
`react-native-obfuscating-transformer requires react-native >= 0.46, you are on version ${reactNativeVersionString}`,
36+
)
37+
}
38+
}

src/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import * as crypto from "crypto"
2+
import * as fs from "fs"
3+
4+
import { getCallerFile } from "./getCallerFile"
5+
import { MetroTransformer, getMetroTransformer } from "./getMetroTransformer"
6+
7+
function getOwnCacheKey(upstreamCacheKey: string, callerFilename: string) {
8+
var key = crypto.createHash("md5")
9+
key.update(upstreamCacheKey)
10+
key.update(fs.readFileSync(__filename))
11+
key.update(fs.readFileSync(callerFilename))
12+
return key.digest("hex")
13+
}
14+
15+
interface ObfuscationOptions {
16+
match?: RegExp
17+
upstreamTransformer?: MetroTransformer
18+
}
19+
20+
function obfuscatingTransformer({
21+
match = /.*.js/,
22+
upstreamTransformer = getMetroTransformer(),
23+
..._options
24+
}: ObfuscationOptions): MetroTransformer {
25+
const callerFilename = getCallerFile()
26+
27+
return {
28+
transform(props) {
29+
const result = upstreamTransformer.transform(props)
30+
if (props.filename.match(match)) {
31+
console.log("obfuscating", props.filename)
32+
}
33+
return result
34+
},
35+
getCacheKey() {
36+
return getOwnCacheKey(
37+
upstreamTransformer.getCacheKey
38+
? upstreamTransformer.getCacheKey()
39+
: "",
40+
callerFilename,
41+
)
42+
},
43+
}
44+
}
45+
46+
export = obfuscatingTransformer

tsconfig.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"module": "commonjs",
5+
"lib": [
6+
"es2015"
7+
],
8+
"strict": true,
9+
"outDir": "dist",
10+
"noUnusedLocals": true,
11+
"noUnusedParameters": true,
12+
"inlineSourceMap": true,
13+
"allowJs": true,
14+
"inlineSources": true
15+
},
16+
"include": [
17+
"typings/**/*.d.ts",
18+
"src/**/*.ts"
19+
],
20+
"compileOnSave": true
21+
}

0 commit comments

Comments
 (0)