@expo/fingerprint 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,16 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 0.3.0 — 2023-09-20
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - This version includes fingerprint result breaking changes. ([#24520](https://github.com/expo/expo/pull/24520) by [@kudo](https://github.com/kudo))
18
+
19
+ ### 🎉 New features
20
+
21
+ - Improve fingerprint sourcing scope for local config-plugins. ([#24520](https://github.com/expo/expo/pull/24520) by [@kudo](https://github.com/kudo))
22
+
13
23
  ## 0.2.0 — 2023-09-08
14
24
 
15
25
  ### 🛠 Breaking changes
package/README.md CHANGED
@@ -116,3 +116,73 @@ console.log(result);
116
116
  ## CLI Usage
117
117
 
118
118
  `npx @expo/fingerprint /path/to/projectRoot`
119
+
120
+ ## Limitations
121
+
122
+ ## Limited support for [config-plugins raw functions](https://docs.expo.dev/config-plugins/plugins-and-mods/#raw-functions)
123
+
124
+ When using config-plugins with raw functions, it's essential to be aware of certain limitations, particularly in the context of fingerprinting. Expo makes its best effort to generate fingerprints for changes made through config-plugins; however, raw functions pose specific challenges. Raw functions are not serializable as fingerprints, which means they cannot be directly used for generating unique hashes.
125
+
126
+ To work around this limitation, Expo employs one of the following strategies to create serializable fingerprints for raw functions:
127
+
128
+ 1. **Using `Function.name`**: Expo utilizes the `Function.name` property if available for named raw functions. This property provides a recognizable name for the function, which can be used as a fingerprint property.
129
+
130
+ 2. **Using `withAnonymous`**: For anonymous raw functions without a `Function.name`, Expo resorts to using 'withAnonymous' as the fingerprint property. This is a generic identifier for anonymous functions.
131
+
132
+ Here's an example to illustrate these concepts:
133
+
134
+ ```javascript
135
+ // In app.config.js
136
+ const { withInfoPlist } = require('expo/config-plugins');
137
+
138
+ const withMyPlugin = (config) => {
139
+ return withInfoPlist(config, (config) => {
140
+ config.modResults.NSLocationWhenInUseUsageDescription = 'Allow $(PRODUCT_NAME) to use your location';
141
+ return config;
142
+ });
143
+ };
144
+
145
+ export default ({ config }) => {
146
+ config.plugins ||= [];
147
+ config.plugins.push(withMyPlugin);
148
+ config.plugins.push((config) => config);
149
+ return config;
150
+ };`
151
+ ```
152
+
153
+ In this example, Expo will use ['withMyPlugin', 'withAnonymous'] as plugin properties for fingerprint hashing.
154
+
155
+ It's important to note that due to this design, if you make changes to the implementation of raw config-plugins functions, such as altering the Info.plist value within 'withMyPlugin', the fingerprint will still generate the same hash value. To ensure unique fingerprints when modifying config-plugins implementations, consider the following options:
156
+
157
+ - **Avoid Anonymous Functions**: Avoid using anonymous raw config-plugins functions. Instead, use named functions whenever possible, and ensure that their names remain consistent as long as the implementation changes.
158
+
159
+ - **Use Local config-plugins**: Alternatively, you can create local config-plugins as separate modules, each with its own export. This approach allows you to specify a different function name when making changes to the config-plugins implementations.
160
+
161
+ Here's an example of using a local config-plugin:
162
+
163
+ ```javascript
164
+ // In ./plugins/withMyPlugin.js
165
+ const { withInfoPlist } = require('expo/config-plugins');
166
+
167
+ const withMyPlugin = (config) => {
168
+ return withInfoPlist(config, (config) => {
169
+ config.modResults.NSLocationWhenInUseUsageDescription =
170
+ 'Allow $(PRODUCT_NAME) to use your location';
171
+ return config;
172
+ });
173
+ };
174
+
175
+ module.exports = withMyPlugin;
176
+ ```
177
+
178
+ ```json
179
+ // in app.json
180
+ {
181
+ "expo": {
182
+ // ...
183
+ "plugins": "./plugins/withMyPlugin"
184
+ }
185
+ }
186
+ ```
187
+
188
+ By following these guidelines, you can effectively manage changes to config-plugins and ensure that fingerprinting remains consistent and reliable.
@@ -0,0 +1,30 @@
1
+ import spawnAsync from '@expo/spawn-async';
2
+ import { getConfig } from 'expo/config';
3
+ import path from 'path';
4
+
5
+ type SpawnAsyncType = typeof spawnAsync;
6
+
7
+ const origSpawnAsync = jest.requireActual('@expo/spawn-async') as SpawnAsyncType;
8
+ const mockSpawnAsync = jest
9
+ .fn()
10
+ .mockImplementation(
11
+ async (
12
+ command: Parameters<SpawnAsyncType>[0],
13
+ args: Parameters<SpawnAsyncType>[1],
14
+ options: Parameters<SpawnAsyncType>[2]
15
+ ) => {
16
+ if (args != null && args.length >= 2 && path.parse(args[0]).name === 'ExpoConfigLoader') {
17
+ // For unit tests, we don't really spawn a process to execute the ExpoConfigLoader because the file system is just a memfs.
18
+ // Rather than that, we just call `getConfig` directly.
19
+ const projectRoot = args[1];
20
+ const config = await getConfig(projectRoot, { skipSDKVersionRequirement: true });
21
+ const stdout = JSON.stringify({ config, loadedModules: [] });
22
+ return {
23
+ stdout,
24
+ };
25
+ }
26
+ return origSpawnAsync(command, args, options);
27
+ }
28
+ ) as SpawnAsyncType;
29
+
30
+ module.exports = mockSpawnAsync;
@@ -1,2 +1,17 @@
1
1
  import { fs } from 'memfs';
2
+ import path from 'path';
3
+
4
+ /**
5
+ * Further mock `fs.promises` to ensure the parent directory exists.
6
+ * We used to call `fs.promises.mkdtemp(path.join(os.tmpdir(), ...))`, so that we don't have to worry about os.tmpdir() exists.
7
+ */
8
+ const origMkdtemp = fs.promises.mkdtemp;
9
+ fs.promises.mkdtemp = (
10
+ prefix: string,
11
+ options?: Parameters<typeof origMkdtemp>[1]
12
+ ): ReturnType<typeof origMkdtemp> => {
13
+ fs.mkdirSync(path.dirname(prefix), { recursive: true });
14
+ return origMkdtemp(prefix, options);
15
+ };
16
+
2
17
  module.exports = fs.promises;
package/build/Options.js CHANGED
@@ -19,6 +19,30 @@ exports.DEFAULT_IGNORE_PATHS = [
19
19
  'app.config.js',
20
20
  'app.config.json',
21
21
  'app.json',
22
+ // Ignore default javascript files when calling `getConfig()`
23
+ '**/node_modules/@babel/**/*',
24
+ '**/node_modules/@expo/**/*',
25
+ '**/node_modules/@jridgewell/**/*',
26
+ '**/node_modules/expo/config.js',
27
+ '**/node_modules/expo/config-plugins.js',
28
+ `**/node_modules/{${[
29
+ 'debug',
30
+ 'escape-string-regexp',
31
+ 'getenv',
32
+ 'graceful-fs',
33
+ 'has-flag',
34
+ 'imurmurhash',
35
+ 'js-tokens',
36
+ 'json5',
37
+ 'lines-and-columns',
38
+ 'require-from-string',
39
+ 'resolve-from',
40
+ 'signal-exit',
41
+ 'sucrase',
42
+ 'supports-color',
43
+ 'ts-interface-checker',
44
+ 'write-file-atomic',
45
+ ].join(',')}}/**/*`,
22
46
  ];
23
47
  async function normalizeOptionsAsync(projectRoot, options) {
24
48
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"Options.js","sourceRoot":"","sources":["../src/Options.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAC7B,4CAAoB;AACpB,gDAAwB;AAIX,QAAA,2BAA2B,GAAG,oBAAoB,CAAC;AAEnD,QAAA,oBAAoB,GAAG;IAClC,mCAA2B;IAC3B,uBAAuB;IACvB,2BAA2B;IAC3B,0BAA0B;IAC1B,kBAAkB;IAElB,2FAA2F;IAC3F,eAAe;IACf,eAAe;IACf,iBAAiB;IACjB,UAAU;CACX,CAAC;AAEK,KAAK,UAAU,qBAAqB,CACzC,WAAmB,EACnB,OAAiB;IAEjB,OAAO;QACL,GAAG,OAAO;QACV,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;QACnD,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,IAAI,YAAE,CAAC,IAAI,EAAE,CAAC,MAAM;QACjE,aAAa,EAAE,OAAO,EAAE,aAAa,IAAI,MAAM;QAC/C,WAAW,EAAE,MAAM,uBAAuB,CAAC,WAAW,EAAE,OAAO,CAAC;KACjE,CAAC;AACJ,CAAC;AAXD,sDAWC;AAED,KAAK,UAAU,uBAAuB,CAAC,WAAmB,EAAE,OAAiB;IAC3E,MAAM,WAAW,GAAG;QAClB,GAAG,4BAAoB;QACvB,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;QAC/B,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC;KAC3E,CAAC;IAEF,MAAM,qBAAqB,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,mCAA2B,CAAC,CAAC;IAClF,IAAI;QACF,MAAM,iBAAiB,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE;YACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,WAAW,EAAE;gBACf,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/B;SACF;KACF;IAAC,MAAM,GAAE;IAEV,OAAO,WAAW,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"Options.js","sourceRoot":"","sources":["../src/Options.ts"],"names":[],"mappings":";;;;;;AAAA,2DAA6B;AAC7B,4CAAoB;AACpB,gDAAwB;AAIX,QAAA,2BAA2B,GAAG,oBAAoB,CAAC;AAEnD,QAAA,oBAAoB,GAAG;IAClC,mCAA2B;IAC3B,uBAAuB;IACvB,2BAA2B;IAC3B,0BAA0B;IAC1B,kBAAkB;IAElB,2FAA2F;IAC3F,eAAe;IACf,eAAe;IACf,iBAAiB;IACjB,UAAU;IAEV,6DAA6D;IAC7D,6BAA6B;IAC7B,4BAA4B;IAC5B,kCAAkC;IAClC,gCAAgC;IAChC,wCAAwC;IACxC,oBAAoB;QAClB,OAAO;QACP,sBAAsB;QACtB,QAAQ;QACR,aAAa;QACb,UAAU;QACV,aAAa;QACb,WAAW;QACX,OAAO;QACP,mBAAmB;QACnB,qBAAqB;QACrB,cAAc;QACd,aAAa;QACb,SAAS;QACT,gBAAgB;QAChB,sBAAsB;QACtB,mBAAmB;KACpB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ;CACpB,CAAC;AAEK,KAAK,UAAU,qBAAqB,CACzC,WAAmB,EACnB,OAAiB;IAEjB,OAAO;QACL,GAAG,OAAO;QACV,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;QACnD,iBAAiB,EAAE,OAAO,EAAE,iBAAiB,IAAI,YAAE,CAAC,IAAI,EAAE,CAAC,MAAM;QACjE,aAAa,EAAE,OAAO,EAAE,aAAa,IAAI,MAAM;QAC/C,WAAW,EAAE,MAAM,uBAAuB,CAAC,WAAW,EAAE,OAAO,CAAC;KACjE,CAAC;AACJ,CAAC;AAXD,sDAWC;AAED,KAAK,UAAU,uBAAuB,CAAC,WAAmB,EAAE,OAAiB;IAC3E,MAAM,WAAW,GAAG;QAClB,GAAG,4BAAoB;QACvB,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,EAAE,CAAC;QAC/B,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,GAAG,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC;KAC3E,CAAC;IAEF,MAAM,qBAAqB,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,mCAA2B,CAAC,CAAC;IAClF,IAAI;QACF,MAAM,iBAAiB,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE;YACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,WAAW,EAAE;gBACf,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/B;SACF;KACF;IAAC,MAAM,GAAE;IAEV,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -1,4 +1,3 @@
1
- import minimatch from 'minimatch';
2
1
  import pLimit from 'p-limit';
3
2
  import type { Fingerprint, FingerprintSource, HashResult, HashSource, HashSourceContents, NormalizedOptions } from '../Fingerprint.types';
4
3
  /**
@@ -14,10 +13,6 @@ export declare function createFingerprintSourceAsync(source: HashSource, limiter
14
13
  * Create a `HashResult` from a file
15
14
  */
16
15
  export declare function createFileHashResultsAsync(filePath: string, limiter: pLimit.Limit, projectRoot: string, options: NormalizedOptions): Promise<HashResult | null>;
17
- /**
18
- * Indicate the given `filePath` should be excluded by `ignorePaths`
19
- */
20
- export declare function isIgnoredPath(filePath: string, ignorePaths: string[], minimatchOptions?: minimatch.IOptions): boolean;
21
16
  /**
22
17
  * Create `HashResult` for a dir.
23
18
  * If the dir is excluded, returns null rather than a HashResult
@@ -3,13 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createSourceId = exports.createContentsHashResultsAsync = exports.createDirHashResultsAsync = exports.isIgnoredPath = exports.createFileHashResultsAsync = exports.createFingerprintSourceAsync = exports.createFingerprintFromSourcesAsync = void 0;
6
+ exports.createSourceId = exports.createContentsHashResultsAsync = exports.createDirHashResultsAsync = exports.createFileHashResultsAsync = exports.createFingerprintSourceAsync = exports.createFingerprintFromSourcesAsync = void 0;
7
7
  const crypto_1 = require("crypto");
8
8
  const fs_1 = require("fs");
9
9
  const promises_1 = __importDefault(require("fs/promises"));
10
- const minimatch_1 = __importDefault(require("minimatch"));
11
10
  const p_limit_1 = __importDefault(require("p-limit"));
12
11
  const path_1 = __importDefault(require("path"));
12
+ const Path_1 = require("../utils/Path");
13
13
  const Profile_1 = require("../utils/Profile");
14
14
  /**
15
15
  * Create a `Fingerprint` from `HashSources` array
@@ -80,7 +80,7 @@ async function createFileHashResultsAsync(filePath, limiter, projectRoot, option
80
80
  */
81
81
  return limiter(() => {
82
82
  return new Promise((resolve, reject) => {
83
- if (isIgnoredPath(filePath, options.ignorePaths)) {
83
+ if ((0, Path_1.isIgnoredPath)(filePath, options.ignorePaths)) {
84
84
  return resolve(null);
85
85
  }
86
86
  let resolved = false;
@@ -103,30 +103,12 @@ async function createFileHashResultsAsync(filePath, limiter, projectRoot, option
103
103
  });
104
104
  }
105
105
  exports.createFileHashResultsAsync = createFileHashResultsAsync;
106
- /**
107
- * Indicate the given `filePath` should be excluded by `ignorePaths`
108
- */
109
- function isIgnoredPath(filePath, ignorePaths, minimatchOptions = { dot: true }) {
110
- const minimatchObjs = ignorePaths.map((ignorePath) => new minimatch_1.default.Minimatch(ignorePath, minimatchOptions));
111
- let result = false;
112
- for (const minimatchObj of minimatchObjs) {
113
- const currMatch = minimatchObj.match(filePath);
114
- if (minimatchObj.negate && result && !currMatch) {
115
- // Special handler for negate (!pattern).
116
- // As long as previous match result is true and not matched from the current negate pattern, we should early return.
117
- return false;
118
- }
119
- result || (result = currMatch);
120
- }
121
- return result;
122
- }
123
- exports.isIgnoredPath = isIgnoredPath;
124
106
  /**
125
107
  * Create `HashResult` for a dir.
126
108
  * If the dir is excluded, returns null rather than a HashResult
127
109
  */
128
110
  async function createDirHashResultsAsync(dirPath, limiter, projectRoot, options, depth = 0) {
129
- if (isIgnoredPath(dirPath, options.ignorePaths)) {
111
+ if ((0, Path_1.isIgnoredPath)(dirPath, options.ignorePaths)) {
130
112
  return null;
131
113
  }
132
114
  const dirents = (await promises_1.default.readdir(path_1.default.join(projectRoot, dirPath), { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
@@ -1 +1 @@
1
- {"version":3,"file":"Hash.js","sourceRoot":"","sources":["../../src/hash/Hash.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Hash.js","sourceRoot":"","sources":["../../src/hash/Hash.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAoC;AACpC,2BAAsC;AACtC,2DAA6B;AAC7B,sDAA6B;AAC7B,gDAAwB;AAUxB,wCAA8C;AAC9C,8CAA2C;AAE3C;;GAEG;AACI,KAAK,UAAU,iCAAiC,CACrD,OAAqB,EACrB,WAAmB,EACnB,OAA0B;IAE1B,MAAM,OAAO,GAAG,IAAA,iBAAM,EAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,GAAG,CAC1C,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAC7F,CAAC;IAEF,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACjD,KAAK,MAAM,MAAM,IAAI,kBAAkB,EAAE;QACvC,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE;YACvB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;YACtC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SAC5B;KACF;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAElC,OAAO;QACL,OAAO,EAAE,kBAAkB;QAC3B,IAAI;KACL,CAAC;AACJ,CAAC;AAvBD,8EAuBC;AAED;;;GAGG;AACI,KAAK,UAAU,4BAA4B,CAChD,MAAkB,EAClB,OAAqB,EACrB,WAAmB,EACnB,OAA0B;IAE1B,IAAI,MAAM,GAAsB,IAAI,CAAC;IACrC,QAAQ,MAAM,CAAC,IAAI,EAAE;QACnB,KAAK,UAAU;YACb,MAAM,GAAG,MAAM,8BAA8B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC/D,MAAM;QACR,KAAK,MAAM;YACT,MAAM,GAAG,MAAM,0BAA0B,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAC1F,MAAM;QACR,KAAK,KAAK;YACR,MAAM,GAAG,MAAM,IAAA,iBAAO,EACpB,yBAAyB,EACzB,6BAA6B,MAAM,CAAC,QAAQ,GAAG,CAChD,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC9C;IAED,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;AAClD,CAAC;AAzBD,oEAyBC;AAED;;GAEG;AACI,KAAK,UAAU,0BAA0B,CAC9C,QAAgB,EAChB,OAAqB,EACrB,WAAmB,EACnB,OAA0B;IAE1B,iCAAiC;IACjC;;;;;;;;;;;;;;;;;;;MAmBE;IAEF,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,OAAO,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxD,IAAI,IAAA,oBAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE;gBAChD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;aACtB;YAED,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAA,qBAAgB,EAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;YAClE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACtB,IAAI,CAAC,QAAQ,EAAE;oBACb,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACjC,OAAO,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;oBAC/B,QAAQ,GAAG,IAAI,CAAC;iBACjB;YACH,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gBACvB,MAAM,CAAC,CAAC,CAAC,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AApDD,gEAoDC;AAED;;;GAGG;AACI,KAAK,UAAU,yBAAyB,CAC7C,OAAe,EACf,OAAqB,EACrB,WAAmB,EACnB,OAA0B,EAC1B,QAAgB,CAAC;IAEjB,IAAI,IAAA,oBAAa,EAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE;QAC/C,OAAO,IAAI,CAAC;KACb;IACD,MAAM,OAAO,GAAG,CAAC,MAAM,kBAAE,CAAC,OAAO,CAAC,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAC/F,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CACvC,CAAC;IACF,MAAM,QAAQ,GAAiC,EAAE,CAAC;IAClD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE;YACxB,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;SAC9F;aAAM,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE;YAC1B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;SACpF;KACF;IAED,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAClD,CAAC,MAAM,EAAwB,EAAE,CAAC,MAAM,IAAI,IAAI,CACjD,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE;QACxB,OAAO,IAAI,CAAC;KACb;IACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;KAC3B;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AAC9B,CAAC;AAtCD,8DAsCC;AAED;;GAEG;AACI,KAAK,UAAU,8BAA8B,CAClD,MAA0B,EAC1B,OAA0B;IAE1B,MAAM,GAAG,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpF,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC;AAChC,CAAC;AAND,wEAMC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,MAAkB;IAC/C,QAAQ,MAAM,CAAC,IAAI,EAAE;QACnB,KAAK,UAAU;YACb,OAAO,MAAM,CAAC,EAAE,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC9C;AACH,CAAC;AAXD,wCAWC"}
@@ -5,19 +5,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.sortExpoAutolinkingAndroidConfig = exports.getExpoAutolinkingIosSourcesAsync = exports.getExpoAutolinkingAndroidSourcesAsync = exports.getEasBuildSourcesAsync = exports.getExpoConfigSourcesAsync = void 0;
7
7
  const spawn_async_1 = __importDefault(require("@expo/spawn-async"));
8
- const assert_1 = __importDefault(require("assert"));
9
8
  const chalk_1 = __importDefault(require("chalk"));
10
- const find_up_1 = __importDefault(require("find-up"));
9
+ const promises_1 = __importDefault(require("fs/promises"));
10
+ const os_1 = __importDefault(require("os"));
11
11
  const path_1 = __importDefault(require("path"));
12
12
  const resolve_from_1 = __importDefault(require("resolve-from"));
13
+ const ExpoConfigLoader_1 = require("./ExpoConfigLoader");
13
14
  const Utils_1 = require("./Utils");
14
15
  const debug = require('debug')('expo:fingerprint:sourcer:Expo');
15
16
  async function getExpoConfigSourcesAsync(projectRoot, options) {
17
+ if (!resolve_from_1.default.silent(path_1.default.resolve(projectRoot), 'expo/config')) {
18
+ return [];
19
+ }
16
20
  const results = [];
17
21
  let config;
22
+ let loadedModules = [];
23
+ const ignoredFile = await createTempIgnoredFileAsync(options);
18
24
  try {
19
- const { getConfig } = require((0, resolve_from_1.default)(path_1.default.resolve(projectRoot), 'expo/config'));
20
- config = await getConfig(projectRoot, { skipSDKVersionRequirement: true });
25
+ const { stdout } = await (0, spawn_async_1.default)('node', [(0, ExpoConfigLoader_1.getExpoConfigLoaderPath)(), path_1.default.resolve(projectRoot), ignoredFile], { cwd: __dirname });
26
+ const stdoutJson = JSON.parse(stdout);
27
+ config = stdoutJson.config;
28
+ loadedModules = stdoutJson.loadedModules;
21
29
  results.push({
22
30
  type: 'contents',
23
31
  id: 'expoConfig',
@@ -26,7 +34,9 @@ async function getExpoConfigSourcesAsync(projectRoot, options) {
26
34
  });
27
35
  }
28
36
  catch (e) {
29
- debug('Cannot get Expo config: ' + e);
37
+ if (e instanceof Error) {
38
+ console.warn(`Cannot get Expo config from an Expo project - ${e.message}: `, e.stack);
39
+ }
30
40
  return [];
31
41
  }
32
42
  // external files in config
@@ -63,17 +73,15 @@ async function getExpoConfigSourcesAsync(projectRoot, options) {
63
73
  }))).filter(Boolean);
64
74
  results.push(...externalFileSources);
65
75
  // config plugins
66
- const configPluginSources = getConfigPluginSourcesAsync(projectRoot, config.exp.plugins);
67
- results.push(...configPluginSources);
76
+ const configPluginModules = loadedModules.map((modulePath) => ({
77
+ type: 'file',
78
+ filePath: modulePath,
79
+ reasons: ['expoConfigPlugins'],
80
+ }));
81
+ results.push(...configPluginModules);
68
82
  return results;
69
83
  }
70
84
  exports.getExpoConfigSourcesAsync = getExpoConfigSourcesAsync;
71
- function findUpPluginRoot(entryFile) {
72
- const entryRoot = path_1.default.dirname(entryFile);
73
- const packageJson = find_up_1.default.sync('package.json', { cwd: path_1.default.dirname(entryFile) });
74
- (0, assert_1.default)(packageJson, `No package.json found for module "${entryRoot}"`);
75
- return path_1.default.dirname(packageJson);
76
- }
77
85
  function normalizeExpoConfig(config) {
78
86
  // Deep clone by JSON.parse/stringify that assumes the config is serializable.
79
87
  const normalizedConfig = JSON.parse(JSON.stringify(config));
@@ -81,27 +89,14 @@ function normalizeExpoConfig(config) {
81
89
  delete normalizedConfig._internal;
82
90
  return (0, Utils_1.stringifyJsonSorted)(normalizedConfig);
83
91
  }
84
- function getConfigPluginSourcesAsync(projectRoot, plugins) {
85
- if (plugins == null) {
86
- return [];
87
- }
88
- const reasons = ['expoConfigPlugins'];
89
- const nullableResults = plugins.map((plugin) => {
90
- const pluginPackageName = Array.isArray(plugin) ? plugin[0] : plugin;
91
- if (typeof pluginPackageName === 'string') {
92
- const pluginPackageEntryFile = resolve_from_1.default.silent(projectRoot, pluginPackageName);
93
- const pluginPackageRoot = pluginPackageEntryFile
94
- ? findUpPluginRoot(pluginPackageEntryFile)
95
- : null;
96
- if (pluginPackageRoot) {
97
- debug(`Adding config-plugin root - ${chalk_1.default.dim(pluginPackageRoot)}`);
98
- return { type: 'dir', filePath: path_1.default.relative(projectRoot, pluginPackageRoot), reasons };
99
- }
100
- }
101
- return null;
102
- });
103
- const results = nullableResults.filter(Boolean);
104
- return results;
92
+ /**
93
+ * Create a temporary file with ignored paths from options that will be read by the ExpoConfigLoader.
94
+ */
95
+ async function createTempIgnoredFileAsync(options) {
96
+ await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'expo-fingerprint-'));
97
+ const ignoredFile = path_1.default.join(os_1.default.tmpdir(), '.fingerprintignore');
98
+ await promises_1.default.writeFile(ignoredFile, options.ignorePaths.join('\n'));
99
+ return ignoredFile;
105
100
  }
106
101
  async function getEasBuildSourcesAsync(projectRoot, options) {
107
102
  const files = ['eas.json', '.easignore'];
@@ -1 +1 @@
1
- {"version":3,"file":"Expo.js","sourceRoot":"","sources":["../../src/sourcer/Expo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Expo.js","sourceRoot":"","sources":["../../src/sourcer/Expo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A helper script to load the Expo config and loaded plugins from a project
3
+ */
4
+ /**
5
+ * Get the path to the ExpoConfigLoader file.
6
+ */
7
+ export declare function getExpoConfigLoaderPath(): string;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * A helper script to load the Expo config and loaded plugins from a project
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getExpoConfigLoaderPath = void 0;
10
+ const promises_1 = __importDefault(require("fs/promises"));
11
+ const module_1 = __importDefault(require("module"));
12
+ const path_1 = __importDefault(require("path"));
13
+ const resolve_from_1 = __importDefault(require("resolve-from"));
14
+ const Options_1 = require("../Options");
15
+ const Path_1 = require("../utils/Path");
16
+ async function runAsync(programName, args = []) {
17
+ if (args.length < 1) {
18
+ console.log(`Usage: ${programName} <projectRoot> [ignoredFile]`);
19
+ return;
20
+ }
21
+ const projectRoot = path_1.default.resolve(args[0]);
22
+ const ignoredFile = args[1] ? path_1.default.resolve(args[1]) : null;
23
+ // @ts-expect-error: module internal _cache
24
+ const loadedModulesBefore = new Set(Object.keys(module_1.default._cache));
25
+ const { getConfig } = require((0, resolve_from_1.default)(path_1.default.resolve(projectRoot), 'expo/config'));
26
+ const config = await getConfig(projectRoot, { skipSDKVersionRequirement: true });
27
+ // @ts-expect-error: module internal _cache
28
+ const loadedModules = Object.keys(module_1.default._cache)
29
+ .filter((modulePath) => !loadedModulesBefore.has(modulePath))
30
+ .map((modulePath) => path_1.default.relative(projectRoot, modulePath));
31
+ const ignoredPaths = await loadIgnoredPathsAsync(ignoredFile);
32
+ const filteredLoadedModules = loadedModules.filter((modulePath) => !(0, Path_1.isIgnoredPath)(modulePath, ignoredPaths));
33
+ console.log(JSON.stringify({ config, loadedModules: filteredLoadedModules }));
34
+ }
35
+ // If running from the command line
36
+ if (require.main?.filename === __filename) {
37
+ (async () => {
38
+ const programIndex = process.argv.findIndex((arg) => arg === __filename);
39
+ try {
40
+ await runAsync(process.argv[programIndex], process.argv.slice(programIndex + 1));
41
+ }
42
+ catch (e) {
43
+ console.error('Uncaught Error', e);
44
+ process.exit(1);
45
+ }
46
+ })();
47
+ }
48
+ /**
49
+ * Load the generated ignored paths file from caller and remove the file after loading
50
+ */
51
+ async function loadIgnoredPathsAsync(ignoredFile) {
52
+ if (!ignoredFile) {
53
+ return Options_1.DEFAULT_IGNORE_PATHS;
54
+ }
55
+ const ignorePaths = [];
56
+ try {
57
+ const fingerprintIgnore = await promises_1.default.readFile(ignoredFile, 'utf8');
58
+ const fingerprintIgnoreLines = fingerprintIgnore.split('\n');
59
+ for (const line of fingerprintIgnoreLines) {
60
+ const trimmedLine = line.trim();
61
+ if (trimmedLine) {
62
+ ignorePaths.push(trimmedLine);
63
+ }
64
+ }
65
+ }
66
+ catch { }
67
+ try {
68
+ await promises_1.default.rm(ignoredFile);
69
+ }
70
+ catch { }
71
+ return ignorePaths;
72
+ }
73
+ /**
74
+ * Get the path to the ExpoConfigLoader file.
75
+ */
76
+ function getExpoConfigLoaderPath() {
77
+ return path_1.default.join(__dirname, 'ExpoConfigLoader.js');
78
+ }
79
+ exports.getExpoConfigLoaderPath = getExpoConfigLoaderPath;
80
+ //# sourceMappingURL=ExpoConfigLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoConfigLoader.js","sourceRoot":"","sources":["../../src/sourcer/ExpoConfigLoader.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;AAEH,2DAA6B;AAC7B,oDAA4B;AAC5B,gDAAwB;AACxB,gEAAuC;AAEvC,wCAAkD;AAClD,wCAA8C;AAE9C,KAAK,UAAU,QAAQ,CAAC,WAAmB,EAAE,OAAiB,EAAE;IAC9D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,UAAU,WAAW,8BAA8B,CAAC,CAAC;QACjE,OAAO;KACR;IAED,MAAM,WAAW,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3D,2CAA2C;IAC3C,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhE,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAA,sBAAW,EAAC,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,EAAE,yBAAyB,EAAE,IAAI,EAAE,CAAC,CAAC;IACjF,2CAA2C;IAC3C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAM,CAAC,MAAM,CAAC;SAC7C,MAAM,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;SAC5D,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,cAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,MAAM,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC9D,MAAM,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAChD,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAA,oBAAa,EAAC,UAAU,EAAE,YAAY,CAAC,CACzD,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,mCAAmC;AACnC,IAAI,OAAO,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,EAAE;IACzC,CAAC,KAAK,IAAI,EAAE;QACV,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC;QACzE,IAAI;YACF,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC;SAClF;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;IACH,CAAC,CAAC,EAAE,CAAC;CACN;AAED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,WAA0B;IAC7D,IAAI,CAAC,WAAW,EAAE;QAChB,OAAO,8BAAoB,CAAC;KAC7B;IAED,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,IAAI;QACF,MAAM,iBAAiB,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACjE,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7D,KAAK,MAAM,IAAI,IAAI,sBAAsB,EAAE;YACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,IAAI,WAAW,EAAE;gBACf,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/B;SACF;KACF;IAAC,MAAM,GAAE;IAEV,IAAI;QACF,MAAM,kBAAE,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;KAC1B;IAAC,MAAM,GAAE;IAEV,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB;IACrC,OAAO,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC;AACrD,CAAC;AAFD,0DAEC"}
@@ -0,0 +1,5 @@
1
+ import minimatch from 'minimatch';
2
+ /**
3
+ * Indicate the given `filePath` should be excluded by `ignorePaths`
4
+ */
5
+ export declare function isIgnoredPath(filePath: string, ignorePaths: string[], minimatchOptions?: minimatch.IOptions): boolean;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isIgnoredPath = void 0;
7
+ const minimatch_1 = __importDefault(require("minimatch"));
8
+ /**
9
+ * Indicate the given `filePath` should be excluded by `ignorePaths`
10
+ */
11
+ function isIgnoredPath(filePath, ignorePaths, minimatchOptions = { dot: true }) {
12
+ const minimatchObjs = ignorePaths.map((ignorePath) => new minimatch_1.default.Minimatch(ignorePath, minimatchOptions));
13
+ let result = false;
14
+ for (const minimatchObj of minimatchObjs) {
15
+ const currMatch = minimatchObj.match(filePath);
16
+ if (minimatchObj.negate && result && !currMatch) {
17
+ // Special handler for negate (!pattern).
18
+ // As long as previous match result is true and not matched from the current negate pattern, we should early return.
19
+ return false;
20
+ }
21
+ result || (result = currMatch);
22
+ }
23
+ return result;
24
+ }
25
+ exports.isIgnoredPath = isIgnoredPath;
26
+ //# sourceMappingURL=Path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Path.js","sourceRoot":"","sources":["../../src/utils/Path.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAkC;AAElC;;GAEG;AACH,SAAgB,aAAa,CAC3B,QAAgB,EAChB,WAAqB,EACrB,mBAAuC,EAAE,GAAG,EAAE,IAAI,EAAE;IAEpD,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CACnC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,mBAAS,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,CAAC,CACtE,CAAC;IAEF,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE;QACxC,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,YAAY,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE;YAC/C,yCAAyC;YACzC,oHAAoH;YACpH,OAAO,KAAK,CAAC;SACd;QACD,MAAM,KAAN,MAAM,GAAK,SAAS,EAAC;KACtB;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AApBD,sCAoBC"}
@@ -6,6 +6,13 @@ import rimraf from 'rimraf';
6
6
 
7
7
  import { createProjectHashAsync } from '../../src/Fingerprint';
8
8
 
9
+ jest.mock('../../src/sourcer/ExpoConfigLoader', () => ({
10
+ // Mock the getExpoConfigLoaderPath to use the built version rather than the typescript version from src
11
+ getExpoConfigLoaderPath: jest.fn(() =>
12
+ path.resolve(__dirname, '..', '..', 'build', 'sourcer', 'ExpoConfigLoader.js')
13
+ ),
14
+ }));
15
+
9
16
  describe('bare project test', () => {
10
17
  jest.setTimeout(600000);
11
18
  const tmpDir = os.tmpdir();
@@ -11,6 +11,13 @@ import {
11
11
  import { normalizeOptionsAsync } from '../../src/Options';
12
12
  import { getHashSourcesAsync } from '../../src/sourcer/Sourcer';
13
13
 
14
+ jest.mock('../../src/sourcer/ExpoConfigLoader', () => ({
15
+ // Mock the getExpoConfigLoaderPath to use the built version rather than the typescript version from src
16
+ getExpoConfigLoaderPath: jest.fn(() =>
17
+ path.resolve(__dirname, '..', '..', 'build', 'sourcer', 'ExpoConfigLoader.js')
18
+ ),
19
+ }));
20
+
14
21
  describe('managed project test', () => {
15
22
  jest.setTimeout(600000);
16
23
  const tmpDir = require('temp-dir');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/fingerprint",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A library to generate a fingerprint from a React Native project",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  "clean": "rimraf build ./tsconfig.tsbuildinfo",
12
12
  "lint": "eslint .",
13
13
  "test": "jest",
14
- "test:e2e": "jest --config e2e/jest.config.js"
14
+ "test:e2e": "yarn prepare && jest --config e2e/jest.config.js"
15
15
  },
16
16
  "bin": {
17
17
  "fingerprint": "bin/cli.js"
@@ -48,5 +48,5 @@
48
48
  "glob": "^7.1.7",
49
49
  "temp-dir": "^2.0.0"
50
50
  },
51
- "gitHead": "431682b5adf82c17d11da7dc9b4648801299f520"
51
+ "gitHead": "039366f050814a220cf31f87e0fbdf27416bb478"
52
52
  }
package/src/Options.ts CHANGED
@@ -18,6 +18,31 @@ export const DEFAULT_IGNORE_PATHS = [
18
18
  'app.config.js',
19
19
  'app.config.json',
20
20
  'app.json',
21
+
22
+ // Ignore default javascript files when calling `getConfig()`
23
+ '**/node_modules/@babel/**/*',
24
+ '**/node_modules/@expo/**/*',
25
+ '**/node_modules/@jridgewell/**/*',
26
+ '**/node_modules/expo/config.js',
27
+ '**/node_modules/expo/config-plugins.js',
28
+ `**/node_modules/{${[
29
+ 'debug',
30
+ 'escape-string-regexp',
31
+ 'getenv',
32
+ 'graceful-fs',
33
+ 'has-flag',
34
+ 'imurmurhash',
35
+ 'js-tokens',
36
+ 'json5',
37
+ 'lines-and-columns',
38
+ 'require-from-string',
39
+ 'resolve-from',
40
+ 'signal-exit',
41
+ 'sucrase',
42
+ 'supports-color',
43
+ 'ts-interface-checker',
44
+ 'write-file-atomic',
45
+ ].join(',')}}/**/*`,
21
46
  ];
22
47
 
23
48
  export async function normalizeOptionsAsync(
package/src/hash/Hash.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { createHash } from 'crypto';
2
2
  import { createReadStream } from 'fs';
3
3
  import fs from 'fs/promises';
4
- import minimatch from 'minimatch';
5
4
  import pLimit from 'p-limit';
6
5
  import path from 'path';
7
6
 
@@ -13,6 +12,7 @@ import type {
13
12
  HashSourceContents,
14
13
  NormalizedOptions,
15
14
  } from '../Fingerprint.types';
15
+ import { isIgnoredPath } from '../utils/Path';
16
16
  import { profile } from '../utils/Profile';
17
17
 
18
18
  /**
@@ -131,31 +131,6 @@ export async function createFileHashResultsAsync(
131
131
  });
132
132
  }
133
133
 
134
- /**
135
- * Indicate the given `filePath` should be excluded by `ignorePaths`
136
- */
137
- export function isIgnoredPath(
138
- filePath: string,
139
- ignorePaths: string[],
140
- minimatchOptions: minimatch.IOptions = { dot: true }
141
- ): boolean {
142
- const minimatchObjs = ignorePaths.map(
143
- (ignorePath) => new minimatch.Minimatch(ignorePath, minimatchOptions)
144
- );
145
-
146
- let result = false;
147
- for (const minimatchObj of minimatchObjs) {
148
- const currMatch = minimatchObj.match(filePath);
149
- if (minimatchObj.negate && result && !currMatch) {
150
- // Special handler for negate (!pattern).
151
- // As long as previous match result is true and not matched from the current negate pattern, we should early return.
152
- return false;
153
- }
154
- result ||= currMatch;
155
- }
156
- return result;
157
- }
158
-
159
134
  /**
160
135
  * Create `HashResult` for a dir.
161
136
  * If the dir is excluded, returns null rather than a HashResult
@@ -12,7 +12,6 @@ import {
12
12
  createFingerprintFromSourcesAsync,
13
13
  createFingerprintSourceAsync,
14
14
  createSourceId,
15
- isIgnoredPath,
16
15
  } from '../Hash';
17
16
 
18
17
  jest.mock('fs');
@@ -237,38 +236,3 @@ describe(createSourceId, () => {
237
236
  expect(createSourceId(source)).toBe('foo');
238
237
  });
239
238
  });
240
-
241
- describe(isIgnoredPath, () => {
242
- it('should support file pattern', () => {
243
- expect(isIgnoredPath('app.json', ['app.json'])).toBe(true);
244
- expect(isIgnoredPath('app.ts', ['*.{js,ts}'])).toBe(true);
245
- expect(isIgnoredPath('/dir/app.json', ['/dir/*.json'])).toBe(true);
246
- });
247
-
248
- it('should support directory pattern', () => {
249
- expect(isIgnoredPath('/app/ios/Podfile', ['**/ios/**/*'])).toBe(true);
250
- });
251
-
252
- it('case sensitive by design', () => {
253
- expect(isIgnoredPath('app.json', ['APP.JSON'])).toBe(false);
254
- });
255
-
256
- it('should include dot files from wildcard pattern', () => {
257
- expect(isIgnoredPath('.bashrc', ['*'])).toBe(true);
258
- });
259
-
260
- it('no `matchBase` and `partial` by design', () => {
261
- expect(isIgnoredPath('/dir/app.json', ['app.json'])).toBe(false);
262
- });
263
-
264
- it('match a file inside a dir should use a globstar', () => {
265
- expect(isIgnoredPath('/dir/app.ts', ['*'])).toBe(false);
266
- expect(isIgnoredPath('/dir/app.ts', ['**/*'])).toBe(true);
267
- });
268
-
269
- it('should use `!` to override default ignorePaths', () => {
270
- const ignorePaths = ['**/ios/**/*', '!**/ios/Podfile', '**/android/**/*'];
271
- expect(isIgnoredPath('/app/ios/Podfile', ignorePaths)).toBe(false);
272
- expect(isIgnoredPath('/app/ios/Podfile.lock', ignorePaths)).toBe(true);
273
- });
274
- });
@@ -1,11 +1,12 @@
1
1
  import spawnAsync from '@expo/spawn-async';
2
- import assert from 'assert';
3
2
  import chalk from 'chalk';
4
3
  import type { ExpoConfig, ProjectConfig } from 'expo/config';
5
- import findUp from 'find-up';
4
+ import fs from 'fs/promises';
5
+ import os from 'os';
6
6
  import path from 'path';
7
7
  import resolveFrom from 'resolve-from';
8
8
 
9
+ import { getExpoConfigLoaderPath } from './ExpoConfigLoader';
9
10
  import { getFileBasedHashSourceAsync, stringifyJsonSorted } from './Utils';
10
11
  import type { HashSource, NormalizedOptions } from '../Fingerprint.types';
11
12
 
@@ -15,12 +16,23 @@ export async function getExpoConfigSourcesAsync(
15
16
  projectRoot: string,
16
17
  options: NormalizedOptions
17
18
  ): Promise<HashSource[]> {
18
- const results: HashSource[] = [];
19
+ if (!resolveFrom.silent(path.resolve(projectRoot), 'expo/config')) {
20
+ return [];
21
+ }
19
22
 
23
+ const results: HashSource[] = [];
20
24
  let config: ProjectConfig;
25
+ let loadedModules: string[] = [];
26
+ const ignoredFile = await createTempIgnoredFileAsync(options);
21
27
  try {
22
- const { getConfig } = require(resolveFrom(path.resolve(projectRoot), 'expo/config'));
23
- config = await getConfig(projectRoot, { skipSDKVersionRequirement: true });
28
+ const { stdout } = await spawnAsync(
29
+ 'node',
30
+ [getExpoConfigLoaderPath(), path.resolve(projectRoot), ignoredFile],
31
+ { cwd: __dirname }
32
+ );
33
+ const stdoutJson = JSON.parse(stdout);
34
+ config = stdoutJson.config;
35
+ loadedModules = stdoutJson.loadedModules;
24
36
  results.push({
25
37
  type: 'contents',
26
38
  id: 'expoConfig',
@@ -28,7 +40,9 @@ export async function getExpoConfigSourcesAsync(
28
40
  reasons: ['expoConfig'],
29
41
  });
30
42
  } catch (e: unknown) {
31
- debug('Cannot get Expo config: ' + e);
43
+ if (e instanceof Error) {
44
+ console.warn(`Cannot get Expo config from an Expo project - ${e.message}: `, e.stack);
45
+ }
32
46
  return [];
33
47
  }
34
48
 
@@ -77,19 +91,16 @@ export async function getExpoConfigSourcesAsync(
77
91
  results.push(...externalFileSources);
78
92
 
79
93
  // config plugins
80
- const configPluginSources = getConfigPluginSourcesAsync(projectRoot, config.exp.plugins);
81
- results.push(...configPluginSources);
94
+ const configPluginModules: HashSource[] = loadedModules.map((modulePath) => ({
95
+ type: 'file',
96
+ filePath: modulePath,
97
+ reasons: ['expoConfigPlugins'],
98
+ }));
99
+ results.push(...configPluginModules);
82
100
 
83
101
  return results;
84
102
  }
85
103
 
86
- function findUpPluginRoot(entryFile: string): string {
87
- const entryRoot = path.dirname(entryFile);
88
- const packageJson = findUp.sync('package.json', { cwd: path.dirname(entryFile) });
89
- assert(packageJson, `No package.json found for module "${entryRoot}"`);
90
- return path.dirname(packageJson);
91
- }
92
-
93
104
  function normalizeExpoConfig(config: ExpoConfig): string {
94
105
  // Deep clone by JSON.parse/stringify that assumes the config is serializable.
95
106
  const normalizedConfig: ExpoConfig = JSON.parse(JSON.stringify(config));
@@ -98,31 +109,14 @@ function normalizeExpoConfig(config: ExpoConfig): string {
98
109
  return stringifyJsonSorted(normalizedConfig);
99
110
  }
100
111
 
101
- function getConfigPluginSourcesAsync(
102
- projectRoot: string,
103
- plugins: ExpoConfig['plugins']
104
- ): HashSource[] {
105
- if (plugins == null) {
106
- return [];
107
- }
108
-
109
- const reasons = ['expoConfigPlugins'];
110
- const nullableResults: (HashSource | null)[] = plugins.map((plugin) => {
111
- const pluginPackageName = Array.isArray(plugin) ? plugin[0] : plugin;
112
- if (typeof pluginPackageName === 'string') {
113
- const pluginPackageEntryFile = resolveFrom.silent(projectRoot, pluginPackageName);
114
- const pluginPackageRoot = pluginPackageEntryFile
115
- ? findUpPluginRoot(pluginPackageEntryFile)
116
- : null;
117
- if (pluginPackageRoot) {
118
- debug(`Adding config-plugin root - ${chalk.dim(pluginPackageRoot)}`);
119
- return { type: 'dir', filePath: path.relative(projectRoot, pluginPackageRoot), reasons };
120
- }
121
- }
122
- return null;
123
- });
124
- const results = nullableResults.filter(Boolean) as HashSource[];
125
- return results;
112
+ /**
113
+ * Create a temporary file with ignored paths from options that will be read by the ExpoConfigLoader.
114
+ */
115
+ async function createTempIgnoredFileAsync(options: NormalizedOptions): Promise<string> {
116
+ await fs.mkdtemp(path.join(os.tmpdir(), 'expo-fingerprint-'));
117
+ const ignoredFile = path.join(os.tmpdir(), '.fingerprintignore');
118
+ await fs.writeFile(ignoredFile, options.ignorePaths.join('\n'));
119
+ return ignoredFile;
126
120
  }
127
121
 
128
122
  export async function getEasBuildSourcesAsync(projectRoot: string, options: NormalizedOptions) {
@@ -0,0 +1,84 @@
1
+ /**
2
+ * A helper script to load the Expo config and loaded plugins from a project
3
+ */
4
+
5
+ import fs from 'fs/promises';
6
+ import module from 'module';
7
+ import path from 'path';
8
+ import resolveFrom from 'resolve-from';
9
+
10
+ import { DEFAULT_IGNORE_PATHS } from '../Options';
11
+ import { isIgnoredPath } from '../utils/Path';
12
+
13
+ async function runAsync(programName: string, args: string[] = []) {
14
+ if (args.length < 1) {
15
+ console.log(`Usage: ${programName} <projectRoot> [ignoredFile]`);
16
+ return;
17
+ }
18
+
19
+ const projectRoot = path.resolve(args[0]);
20
+ const ignoredFile = args[1] ? path.resolve(args[1]) : null;
21
+
22
+ // @ts-expect-error: module internal _cache
23
+ const loadedModulesBefore = new Set(Object.keys(module._cache));
24
+
25
+ const { getConfig } = require(resolveFrom(path.resolve(projectRoot), 'expo/config'));
26
+ const config = await getConfig(projectRoot, { skipSDKVersionRequirement: true });
27
+ // @ts-expect-error: module internal _cache
28
+ const loadedModules = Object.keys(module._cache)
29
+ .filter((modulePath) => !loadedModulesBefore.has(modulePath))
30
+ .map((modulePath) => path.relative(projectRoot, modulePath));
31
+
32
+ const ignoredPaths = await loadIgnoredPathsAsync(ignoredFile);
33
+ const filteredLoadedModules = loadedModules.filter(
34
+ (modulePath) => !isIgnoredPath(modulePath, ignoredPaths)
35
+ );
36
+ console.log(JSON.stringify({ config, loadedModules: filteredLoadedModules }));
37
+ }
38
+
39
+ // If running from the command line
40
+ if (require.main?.filename === __filename) {
41
+ (async () => {
42
+ const programIndex = process.argv.findIndex((arg) => arg === __filename);
43
+ try {
44
+ await runAsync(process.argv[programIndex], process.argv.slice(programIndex + 1));
45
+ } catch (e) {
46
+ console.error('Uncaught Error', e);
47
+ process.exit(1);
48
+ }
49
+ })();
50
+ }
51
+
52
+ /**
53
+ * Load the generated ignored paths file from caller and remove the file after loading
54
+ */
55
+ async function loadIgnoredPathsAsync(ignoredFile: string | null) {
56
+ if (!ignoredFile) {
57
+ return DEFAULT_IGNORE_PATHS;
58
+ }
59
+
60
+ const ignorePaths = [];
61
+ try {
62
+ const fingerprintIgnore = await fs.readFile(ignoredFile, 'utf8');
63
+ const fingerprintIgnoreLines = fingerprintIgnore.split('\n');
64
+ for (const line of fingerprintIgnoreLines) {
65
+ const trimmedLine = line.trim();
66
+ if (trimmedLine) {
67
+ ignorePaths.push(trimmedLine);
68
+ }
69
+ }
70
+ } catch {}
71
+
72
+ try {
73
+ await fs.rm(ignoredFile);
74
+ } catch {}
75
+
76
+ return ignorePaths;
77
+ }
78
+
79
+ /**
80
+ * Get the path to the ExpoConfigLoader file.
81
+ */
82
+ export function getExpoConfigLoaderPath() {
83
+ return path.join(__dirname, 'ExpoConfigLoader.js');
84
+ }
@@ -1,5 +1,5 @@
1
1
  import spawnAsync from '@expo/spawn-async';
2
- import findUp from 'find-up';
2
+ import { getConfig } from 'expo/config';
3
3
  import fs from 'fs';
4
4
  import { vol, fs as volFS } from 'memfs';
5
5
  import path from 'path';
@@ -148,9 +148,9 @@ describe(getExpoConfigSourcesAsync, () => {
148
148
 
149
149
  it('should return empty array when expo package is not installed', async () => {
150
150
  vol.fromJSON(require('./fixtures/BareReactNative70Project.json'));
151
- const mockedResolveFrom = resolveFrom as jest.MockedFunction<typeof resolveFrom>;
151
+ const mockedResolveFrom = resolveFrom.silent as jest.MockedFunction<typeof resolveFrom.silent>;
152
152
  mockedResolveFrom.mockImplementationOnce((fromDirectory: string, moduleId: string) => {
153
- const actualResolver = jest.requireActual('resolve-from');
153
+ const actualResolver = jest.requireActual('resolve-from').silent;
154
154
  // To fake the case as no expo installed, trying to resolve as **nonexist/expo/config** module
155
155
  return actualResolver(fromDirectory, 'nonexist/expo/config');
156
156
  });
@@ -222,115 +222,39 @@ export default ({ config }) => {
222
222
  })
223
223
  );
224
224
  });
225
- });
226
-
227
- describe(`getExpoConfigSourcesAsync - config-plugins`, () => {
228
- let baseAppJson: { expo: any };
229
-
230
- function setupThirdPartyPlugin() {
231
- vol.mkdirSync('/app/node_modules/third-party', { recursive: true });
232
-
233
- // package.json
234
- vol.writeFileSync('/app/node_modules/third-party/package.json', '{}');
235
- const mockFindUpSync = findUp.sync as jest.MockedFunction<typeof findUp.sync>;
236
- mockFindUpSync.mockReturnValue('/app/node_modules/third-party/package.json');
237
225
 
238
- // entry file
239
- const withNoopPlugin = (config: any) => config;
240
- jest.mock('/app/node_modules/third-party/index.js', () => ({ default: withNoopPlugin }), {
241
- virtual: true,
242
- });
243
- const mockResolveFrom = resolveFrom.silent as jest.MockedFunction<typeof resolveFrom.silent>;
244
- mockResolveFrom.mockReturnValue('/app/node_modules/third-party/index.js');
245
- }
246
-
247
- beforeEach(() => {
248
- jest.doMock('fs', () => volFS);
226
+ it('should contain extra files from config plugins', async () => {
249
227
  vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
250
- baseAppJson = JSON.parse(vol.readFileSync('/app/app.json', 'utf8').toString());
251
- });
252
-
253
- afterEach(() => {
254
- vol.reset();
255
- const mockResolveFrom = resolveFrom.silent as jest.MockedFunction<typeof resolveFrom.silent>;
256
- mockResolveFrom.mockReset();
257
- });
258
-
259
- it('should contain external config-plugin dir', async () => {
260
- setupThirdPartyPlugin();
261
-
262
- vol.writeFileSync(
263
- '/app/app.json',
264
- JSON.stringify({
265
- ...baseAppJson,
266
- expo: {
267
- ...baseAppJson.expo,
268
- plugins: ['third-party'],
269
- },
270
- })
271
- );
228
+ const config = await getConfig('/app', { skipSDKVersionRequirement: true });
229
+ const mockSpawnAsync = spawnAsync as jest.MockedFunction<typeof spawnAsync>;
230
+ const stdout = JSON.stringify({
231
+ config,
232
+ loadedModules: [
233
+ 'node_modules/third-party/index.js',
234
+ 'node_modules/third-party/node_modules/transitive-third-party/index.js',
235
+ ],
236
+ });
237
+ mockSpawnAsync.mockResolvedValueOnce({
238
+ output: [],
239
+ stdout,
240
+ stderr: '',
241
+ signal: null,
242
+ status: 0,
243
+ });
272
244
  const sources = await getExpoConfigSourcesAsync('/app', await normalizeOptionsAsync('/app'));
273
245
  expect(sources).toContainEqual(
274
246
  expect.objectContaining({
275
- type: 'dir',
276
- filePath: 'node_modules/third-party',
277
- })
278
- );
279
- });
280
-
281
- it('should contain external config-plugin dir from plugin with parameters', async () => {
282
- setupThirdPartyPlugin();
283
-
284
- vol.writeFileSync(
285
- '/app/app.json',
286
- JSON.stringify({
287
- ...baseAppJson,
288
- expo: {
289
- ...baseAppJson.expo,
290
- plugins: [['third-party', { parameter: 'foo' }]],
291
- },
247
+ type: 'file',
248
+ filePath: 'node_modules/third-party/index.js',
292
249
  })
293
250
  );
294
- const sources = await getExpoConfigSourcesAsync('/app', await normalizeOptionsAsync('/app'));
295
251
  expect(sources).toContainEqual(
296
252
  expect.objectContaining({
297
- type: 'dir',
298
- filePath: 'node_modules/third-party',
253
+ type: 'file',
254
+ filePath: 'node_modules/third-party/node_modules/transitive-third-party/index.js',
299
255
  })
300
256
  );
301
257
  });
302
-
303
- it('should not contain external config-plugin dir from raw function plugins', async () => {
304
- vol.writeFileSync(
305
- '/app/app.config.js',
306
- `\
307
- export default ({ config }) => {
308
- return config;
309
- };`
310
- );
311
- const sources = await getExpoConfigSourcesAsync('/app', await normalizeOptionsAsync('/app'));
312
-
313
- vol.writeFileSync(
314
- '/app/app.config.js',
315
- `\
316
- export default ({ config }) => {
317
- config.plugins ||= [];
318
- const withNoopPlugin = (config: any) => config;
319
- config.plugins.push(withNoopPlugin);
320
- return config;
321
- };`
322
- );
323
- const sources2 = await getExpoConfigSourcesAsync('/app', await normalizeOptionsAsync('/app'));
324
-
325
- // sources2 will contain the plugins from expo config, but sources will not.
326
- const sourcesWithoutExpoConfig = sources.filter(
327
- (item) => item.type !== 'contents' || item.id !== 'expoConfig'
328
- );
329
- const sources2WithoutExpoConfig = sources2.filter(
330
- (item) => item.type !== 'contents' || item.id !== 'expoConfig'
331
- );
332
- expect(sourcesWithoutExpoConfig).toEqual(sources2WithoutExpoConfig);
333
- });
334
258
  });
335
259
 
336
260
  describe('sortExpoAutolinkingConfig', () => {
@@ -4,6 +4,8 @@ import { normalizeOptionsAsync } from '../../Options';
4
4
  import { getPatchPackageSourcesAsync } from '../PatchPackage';
5
5
  import { getHashSourcesAsync } from '../Sourcer';
6
6
 
7
+ jest.mock('@expo/spawn-async');
8
+ jest.mock('fs');
7
9
  jest.mock('fs/promises');
8
10
  jest.mock('/app/package.json', () => ({}), { virtual: true });
9
11
 
@@ -28,6 +30,7 @@ describe(getPatchPackageSourcesAsync, () => {
28
30
 
29
31
  describe('patch-package postinstall', () => {
30
32
  it('should contain `package.json` scripts block for lifecycle patches', async () => {
33
+ vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
31
34
  const scriptsBlock = {
32
35
  postinstall: 'npx patch-package',
33
36
  };
@@ -1,8 +1,15 @@
1
+ import { vol } from 'memfs';
2
+
1
3
  import { normalizeOptionsAsync } from '../../Options';
2
4
  import { getHashSourcesAsync } from '../Sourcer';
3
5
 
6
+ jest.mock('@expo/spawn-async');
7
+ jest.mock('fs');
8
+ jest.mock('fs/promises');
9
+
4
10
  describe(getHashSourcesAsync, () => {
5
11
  it('should include `extraSources` from input parameter', async () => {
12
+ vol.fromJSON(require('./fixtures/ExpoManaged47Project.json'));
6
13
  const sources = await getHashSourcesAsync(
7
14
  '/app',
8
15
  await normalizeOptionsAsync('/app', {
@@ -0,0 +1,26 @@
1
+ import minimatch from 'minimatch';
2
+
3
+ /**
4
+ * Indicate the given `filePath` should be excluded by `ignorePaths`
5
+ */
6
+ export function isIgnoredPath(
7
+ filePath: string,
8
+ ignorePaths: string[],
9
+ minimatchOptions: minimatch.IOptions = { dot: true }
10
+ ): boolean {
11
+ const minimatchObjs = ignorePaths.map(
12
+ (ignorePath) => new minimatch.Minimatch(ignorePath, minimatchOptions)
13
+ );
14
+
15
+ let result = false;
16
+ for (const minimatchObj of minimatchObjs) {
17
+ const currMatch = minimatchObj.match(filePath);
18
+ if (minimatchObj.negate && result && !currMatch) {
19
+ // Special handler for negate (!pattern).
20
+ // As long as previous match result is true and not matched from the current negate pattern, we should early return.
21
+ return false;
22
+ }
23
+ result ||= currMatch;
24
+ }
25
+ return result;
26
+ }
@@ -0,0 +1,36 @@
1
+ import { isIgnoredPath } from '../Path';
2
+
3
+ describe(isIgnoredPath, () => {
4
+ it('should support file pattern', () => {
5
+ expect(isIgnoredPath('app.json', ['app.json'])).toBe(true);
6
+ expect(isIgnoredPath('app.ts', ['*.{js,ts}'])).toBe(true);
7
+ expect(isIgnoredPath('/dir/app.json', ['/dir/*.json'])).toBe(true);
8
+ });
9
+
10
+ it('should support directory pattern', () => {
11
+ expect(isIgnoredPath('/app/ios/Podfile', ['**/ios/**/*'])).toBe(true);
12
+ });
13
+
14
+ it('case sensitive by design', () => {
15
+ expect(isIgnoredPath('app.json', ['APP.JSON'])).toBe(false);
16
+ });
17
+
18
+ it('should include dot files from wildcard pattern', () => {
19
+ expect(isIgnoredPath('.bashrc', ['*'])).toBe(true);
20
+ });
21
+
22
+ it('no `matchBase` and `partial` by design', () => {
23
+ expect(isIgnoredPath('/dir/app.json', ['app.json'])).toBe(false);
24
+ });
25
+
26
+ it('match a file inside a dir should use a globstar', () => {
27
+ expect(isIgnoredPath('/dir/app.ts', ['*'])).toBe(false);
28
+ expect(isIgnoredPath('/dir/app.ts', ['**/*'])).toBe(true);
29
+ });
30
+
31
+ it('should use `!` to override default ignorePaths', () => {
32
+ const ignorePaths = ['**/ios/**/*', '!**/ios/Podfile', '**/android/**/*'];
33
+ expect(isIgnoredPath('/app/ios/Podfile', ignorePaths)).toBe(false);
34
+ expect(isIgnoredPath('/app/ios/Podfile.lock', ignorePaths)).toBe(true);
35
+ });
36
+ });