|
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