|
1 | 1 | import * as crypto from "crypto" |
2 | 2 | import * as fs from "fs" |
| 3 | +import * as path from "path" |
3 | 4 | import * as JavaScriptObfuscator from "javascript-obfuscator" |
| 5 | +import { path as appRootPath } from "app-root-path" |
| 6 | + |
| 7 | +import generate from "babel-generator" |
4 | 8 |
|
5 | 9 | import { getCallerFile } from "./getCallerFile" |
6 | | -import { MetroTransformer, getMetroTransformer } from "./getMetroTransformer" |
| 10 | +import { |
| 11 | + MetroTransformer, |
| 12 | + getMetroTransformer, |
| 13 | + MetroTransformerResult, |
| 14 | + maybeTransformMetroResult, |
| 15 | +} from "./getMetroTransformer" |
| 16 | +import { |
| 17 | + obfuscateCode, |
| 18 | + obfuscateCodePreservingSourceMap, |
| 19 | +} from "./obfuscateCode" |
7 | 20 |
|
8 | | -function getOwnCacheKey(upstreamCacheKey: string, callerFilename: string) { |
| 21 | +function getOwnCacheKey(upstreamCacheKey: string, configFilename: string) { |
9 | 22 | var key = crypto.createHash("md5") |
10 | 23 | key.update(upstreamCacheKey) |
11 | 24 | key.update(fs.readFileSync(__filename)) |
12 | | - key.update(fs.readFileSync(callerFilename)) |
| 25 | + key.update(fs.readFileSync(configFilename)) |
13 | 26 | return key.digest("hex") |
14 | 27 | } |
15 | 28 |
|
16 | 29 | export interface ObfuscatingTransformerOptions { |
17 | | - match?: RegExp |
| 30 | + filter?(filename: string, source: string): boolean |
18 | 31 | upstreamTransformer?: MetroTransformer |
19 | 32 | obfuscatorOptions?: JavaScriptObfuscator.Options |
| 33 | + trace?: boolean |
20 | 34 | } |
21 | 35 |
|
| 36 | +const sourceDir = path.join(appRootPath, "src") |
| 37 | + |
22 | 38 | export function obfuscatingTransformer({ |
23 | | - match = /.*.js/, |
| 39 | + filter = filename => filename.startsWith(sourceDir), |
24 | 40 | upstreamTransformer = getMetroTransformer(), |
25 | | - ..._options |
| 41 | + obfuscatorOptions: _obfuscatorOptions, |
| 42 | + ...otherOptions |
26 | 43 | }: ObfuscatingTransformerOptions): MetroTransformer { |
27 | 44 | const callerFilename = getCallerFile() |
28 | 45 |
|
| 46 | + const obfuscatorOptions: JavaScriptObfuscator.Options = { |
| 47 | + ..._obfuscatorOptions, |
| 48 | + sourceMap: true, |
| 49 | + sourceMapMode: "separate", |
| 50 | + stringArray: false, |
| 51 | + } |
| 52 | + |
29 | 53 | return { |
30 | 54 | transform(props) { |
31 | 55 | const result = upstreamTransformer.transform(props) |
32 | | - if (props.filename.match(match)) { |
33 | | - console.log("obfuscating", props.filename) |
| 56 | + const resultCanBeObfuscated = result.code || result.ast |
| 57 | + |
| 58 | + if (resultCanBeObfuscated && filter(props.filename, props.src)) { |
| 59 | + if (otherOptions.trace) { |
| 60 | + console.log("Obfuscating", props.filename) |
| 61 | + } |
| 62 | + |
| 63 | + const { code, map }: MetroTransformerResult = result.code |
| 64 | + ? result |
| 65 | + : result.ast |
| 66 | + ? (generate(result.ast, { |
| 67 | + filename: props.filename, |
| 68 | + retainLines: true, |
| 69 | + sourceMaps: true, |
| 70 | + sourceFileName: props.filename, |
| 71 | + }) as MetroTransformerResult) |
| 72 | + : { code: "", map: "" } |
| 73 | + |
| 74 | + if (!code) { |
| 75 | + return result |
| 76 | + } else if (!map) { |
| 77 | + return { |
| 78 | + code: obfuscateCode(code, obfuscatorOptions), |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + return maybeTransformMetroResult( |
| 83 | + obfuscateCodePreservingSourceMap( |
| 84 | + code, |
| 85 | + map, |
| 86 | + props.filename, |
| 87 | + props.src, |
| 88 | + obfuscatorOptions, |
| 89 | + ), |
| 90 | + ) |
34 | 91 | } |
| 92 | + |
35 | 93 | return result |
36 | 94 | }, |
| 95 | + |
37 | 96 | getCacheKey() { |
38 | 97 | return getOwnCacheKey( |
39 | 98 | upstreamTransformer.getCacheKey |
|
0 commit comments