@expo/cli 0.24.20 → 0.24.21

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/build/bin/cli CHANGED
@@ -123,7 +123,7 @@ const args = (0, _arg().default)({
123
123
  });
124
124
  if (args['--version']) {
125
125
  // Version is added in the build script.
126
- console.log("0.24.20");
126
+ console.log("0.24.21");
127
127
  process.exit(0);
128
128
  }
129
129
  if (args['--non-interactive']) {
@@ -16,6 +16,13 @@ _export(exports, {
16
16
  return getAssetSchemasAsync;
17
17
  }
18
18
  });
19
+ function _schemautils() {
20
+ const data = require("@expo/schema-utils");
21
+ _schemautils = function() {
22
+ return data;
23
+ };
24
+ return data;
25
+ }
19
26
  function _fs() {
20
27
  const data = /*#__PURE__*/ _interop_require_default(require("fs"));
21
28
  _fs = function() {
@@ -33,7 +40,6 @@ function _path() {
33
40
  const _client = require("./rest/client");
34
41
  const _env = require("../utils/env");
35
42
  const _errors = require("../utils/errors");
36
- const _jsonSchemaDeref = require("../utils/jsonSchemaDeref");
37
43
  function _interop_require_default(obj) {
38
44
  return obj && obj.__esModule ? obj : {
39
45
  default: obj
@@ -42,12 +48,7 @@ function _interop_require_default(obj) {
42
48
  const schemaJson = {};
43
49
  async function _getSchemaAsync(sdkVersion) {
44
50
  const json = await getSchemaJSONAsync(sdkVersion);
45
- // NOTE(@kitten): This is a replacement for the `json-schema-deref-sync` package.
46
- // We re-implemented it locally to remove it, since it comes with heavy dependencies
47
- // and a large install time impact.
48
- // The tests have been ported to match the behaviour closely, but we removed
49
- // local file ref support. For our purposes the behaviour should be identical.
50
- return (0, _jsonSchemaDeref.jsonSchemaDeref)(json.schema);
51
+ return (0, _schemautils().derefSchema)(json.schema);
51
52
  }
52
53
  async function getAssetSchemasAsync(sdkVersion = 'UNVERSIONED') {
53
54
  // If no SDK version is available then fall back to unversioned
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/api/getExpoSchema.ts"],"sourcesContent":["import { JSONObject } from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { createCachedFetch, getResponseDataOrThrow } from './rest/client';\nimport { env } from '../utils/env';\nimport { CommandError } from '../utils/errors';\nimport { jsonSchemaDeref } from '../utils/jsonSchemaDeref';\n\nexport type Schema = any;\n\nexport type AssetSchema = {\n fieldPath: string;\n};\n\nconst schemaJson: { [sdkVersion: string]: Schema } = {};\n\nexport async function _getSchemaAsync(sdkVersion: string): Promise<Schema> {\n const json = await getSchemaJSONAsync(sdkVersion);\n // NOTE(@kitten): This is a replacement for the `json-schema-deref-sync` package.\n // We re-implemented it locally to remove it, since it comes with heavy dependencies\n // and a large install time impact.\n // The tests have been ported to match the behaviour closely, but we removed\n // local file ref support. For our purposes the behaviour should be identical.\n return jsonSchemaDeref(json.schema);\n}\n\n/**\n * Array of schema nodes that refer to assets along with their field path (eg. 'notification.icon')\n *\n * @param sdkVersion\n */\nexport async function getAssetSchemasAsync(sdkVersion: string = 'UNVERSIONED'): Promise<string[]> {\n // If no SDK version is available then fall back to unversioned\n const schema = await _getSchemaAsync(sdkVersion);\n const assetSchemas: string[] = [];\n const visit = (node: Schema, fieldPath: string) => {\n if (node.meta && node.meta.asset) {\n assetSchemas.push(fieldPath);\n }\n const properties = node.properties;\n if (properties) {\n Object.keys(properties).forEach((property) =>\n visit(properties[property], `${fieldPath}${fieldPath.length > 0 ? '.' : ''}${property}`)\n );\n }\n };\n visit(schema, '');\n\n return assetSchemas;\n}\n\nasync function getSchemaJSONAsync(sdkVersion: string): Promise<{ schema: Schema }> {\n if (env.EXPO_UNIVERSE_DIR) {\n return JSON.parse(\n fs\n .readFileSync(\n path.join(\n env.EXPO_UNIVERSE_DIR,\n 'server',\n 'www',\n 'xdl-schemas',\n 'UNVERSIONED-schema.json'\n )\n )\n .toString()\n );\n }\n\n if (!schemaJson[sdkVersion]) {\n try {\n schemaJson[sdkVersion] = await getConfigurationSchemaAsync(sdkVersion);\n } catch (e: any) {\n if (e.code === 'INVALID_JSON') {\n throw new CommandError('INVALID_JSON', `Couldn't read schema from server`);\n }\n\n throw e;\n }\n }\n\n return schemaJson[sdkVersion];\n}\n\nasync function getConfigurationSchemaAsync(sdkVersion: string): Promise<JSONObject> {\n // Reconstruct the cached fetch since caching could be disabled.\n const fetchAsync = createCachedFetch({\n cacheDirectory: 'schema-cache',\n // We'll use a 1 week cache for versions so older versions get flushed out eventually.\n ttl: 1000 * 60 * 60 * 24 * 7,\n });\n const response = await fetchAsync(`project/configuration/schema/${sdkVersion}`);\n const json = await response.json();\n\n return getResponseDataOrThrow<JSONObject>(json);\n}\n"],"names":["_getSchemaAsync","getAssetSchemasAsync","schemaJson","sdkVersion","json","getSchemaJSONAsync","jsonSchemaDeref","schema","assetSchemas","visit","node","fieldPath","meta","asset","push","properties","Object","keys","forEach","property","length","env","EXPO_UNIVERSE_DIR","JSON","parse","fs","readFileSync","path","join","toString","getConfigurationSchemaAsync","e","code","CommandError","fetchAsync","createCachedFetch","cacheDirectory","ttl","response","getResponseDataOrThrow"],"mappings":";;;;;;;;;;;IAiBsBA,eAAe;eAAfA;;IAeAC,oBAAoB;eAApBA;;;;gEA/BP;;;;;;;gEACE;;;;;;wBAEyC;qBACtC;wBACS;iCACG;;;;;;AAQhC,MAAMC,aAA+C,CAAC;AAE/C,eAAeF,gBAAgBG,UAAkB;IACtD,MAAMC,OAAO,MAAMC,mBAAmBF;IACtC,iFAAiF;IACjF,oFAAoF;IACpF,mCAAmC;IACnC,4EAA4E;IAC5E,8EAA8E;IAC9E,OAAOG,IAAAA,gCAAe,EAACF,KAAKG,MAAM;AACpC;AAOO,eAAeN,qBAAqBE,aAAqB,aAAa;IAC3E,+DAA+D;IAC/D,MAAMI,SAAS,MAAMP,gBAAgBG;IACrC,MAAMK,eAAyB,EAAE;IACjC,MAAMC,QAAQ,CAACC,MAAcC;QAC3B,IAAID,KAAKE,IAAI,IAAIF,KAAKE,IAAI,CAACC,KAAK,EAAE;YAChCL,aAAaM,IAAI,CAACH;QACpB;QACA,MAAMI,aAAaL,KAAKK,UAAU;QAClC,IAAIA,YAAY;YACdC,OAAOC,IAAI,CAACF,YAAYG,OAAO,CAAC,CAACC,WAC/BV,MAAMM,UAAU,CAACI,SAAS,EAAE,GAAGR,YAAYA,UAAUS,MAAM,GAAG,IAAI,MAAM,KAAKD,UAAU;QAE3F;IACF;IACAV,MAAMF,QAAQ;IAEd,OAAOC;AACT;AAEA,eAAeH,mBAAmBF,UAAkB;IAClD,IAAIkB,QAAG,CAACC,iBAAiB,EAAE;QACzB,OAAOC,KAAKC,KAAK,CACfC,aAAE,CACCC,YAAY,CACXC,eAAI,CAACC,IAAI,CACPP,QAAG,CAACC,iBAAiB,EACrB,UACA,OACA,eACA,4BAGHO,QAAQ;IAEf;IAEA,IAAI,CAAC3B,UAAU,CAACC,WAAW,EAAE;QAC3B,IAAI;YACFD,UAAU,CAACC,WAAW,GAAG,MAAM2B,4BAA4B3B;QAC7D,EAAE,OAAO4B,GAAQ;YACf,IAAIA,EAAEC,IAAI,KAAK,gBAAgB;gBAC7B,MAAM,IAAIC,oBAAY,CAAC,gBAAgB,CAAC,gCAAgC,CAAC;YAC3E;YAEA,MAAMF;QACR;IACF;IAEA,OAAO7B,UAAU,CAACC,WAAW;AAC/B;AAEA,eAAe2B,4BAA4B3B,UAAkB;IAC3D,gEAAgE;IAChE,MAAM+B,aAAaC,IAAAA,yBAAiB,EAAC;QACnCC,gBAAgB;QAChB,sFAAsF;QACtFC,KAAK,OAAO,KAAK,KAAK,KAAK;IAC7B;IACA,MAAMC,WAAW,MAAMJ,WAAW,CAAC,6BAA6B,EAAE/B,YAAY;IAC9E,MAAMC,OAAO,MAAMkC,SAASlC,IAAI;IAEhC,OAAOmC,IAAAA,8BAAsB,EAAanC;AAC5C"}
1
+ {"version":3,"sources":["../../../src/api/getExpoSchema.ts"],"sourcesContent":["import type { JSONObject } from '@expo/json-file';\nimport { derefSchema } from '@expo/schema-utils';\nimport fs from 'fs';\nimport path from 'path';\n\nimport { createCachedFetch, getResponseDataOrThrow } from './rest/client';\nimport { env } from '../utils/env';\nimport { CommandError } from '../utils/errors';\n\nexport type Schema = any;\n\nexport type AssetSchema = {\n fieldPath: string;\n};\n\nconst schemaJson: { [sdkVersion: string]: Schema } = {};\n\nexport async function _getSchemaAsync(sdkVersion: string): Promise<Schema> {\n const json = await getSchemaJSONAsync(sdkVersion);\n return derefSchema(json.schema);\n}\n\n/**\n * Array of schema nodes that refer to assets along with their field path (eg. 'notification.icon')\n *\n * @param sdkVersion\n */\nexport async function getAssetSchemasAsync(sdkVersion: string = 'UNVERSIONED'): Promise<string[]> {\n // If no SDK version is available then fall back to unversioned\n const schema = await _getSchemaAsync(sdkVersion);\n const assetSchemas: string[] = [];\n const visit = (node: Schema, fieldPath: string) => {\n if (node.meta && node.meta.asset) {\n assetSchemas.push(fieldPath);\n }\n const properties = node.properties;\n if (properties) {\n Object.keys(properties).forEach((property) =>\n visit(properties[property], `${fieldPath}${fieldPath.length > 0 ? '.' : ''}${property}`)\n );\n }\n };\n visit(schema, '');\n\n return assetSchemas;\n}\n\nasync function getSchemaJSONAsync(sdkVersion: string): Promise<{ schema: Schema }> {\n if (env.EXPO_UNIVERSE_DIR) {\n return JSON.parse(\n fs\n .readFileSync(\n path.join(\n env.EXPO_UNIVERSE_DIR,\n 'server',\n 'www',\n 'xdl-schemas',\n 'UNVERSIONED-schema.json'\n )\n )\n .toString()\n );\n }\n\n if (!schemaJson[sdkVersion]) {\n try {\n schemaJson[sdkVersion] = await getConfigurationSchemaAsync(sdkVersion);\n } catch (e: any) {\n if (e.code === 'INVALID_JSON') {\n throw new CommandError('INVALID_JSON', `Couldn't read schema from server`);\n }\n\n throw e;\n }\n }\n\n return schemaJson[sdkVersion];\n}\n\nasync function getConfigurationSchemaAsync(sdkVersion: string): Promise<JSONObject> {\n // Reconstruct the cached fetch since caching could be disabled.\n const fetchAsync = createCachedFetch({\n cacheDirectory: 'schema-cache',\n // We'll use a 1 week cache for versions so older versions get flushed out eventually.\n ttl: 1000 * 60 * 60 * 24 * 7,\n });\n const response = await fetchAsync(`project/configuration/schema/${sdkVersion}`);\n const json = await response.json();\n\n return getResponseDataOrThrow<JSONObject>(json);\n}\n"],"names":["_getSchemaAsync","getAssetSchemasAsync","schemaJson","sdkVersion","json","getSchemaJSONAsync","derefSchema","schema","assetSchemas","visit","node","fieldPath","meta","asset","push","properties","Object","keys","forEach","property","length","env","EXPO_UNIVERSE_DIR","JSON","parse","fs","readFileSync","path","join","toString","getConfigurationSchemaAsync","e","code","CommandError","fetchAsync","createCachedFetch","cacheDirectory","ttl","response","getResponseDataOrThrow"],"mappings":";;;;;;;;;;;IAiBsBA,eAAe;eAAfA;;IAUAC,oBAAoB;eAApBA;;;;yBA1BM;;;;;;;gEACb;;;;;;;gEACE;;;;;;wBAEyC;qBACtC;wBACS;;;;;;AAQ7B,MAAMC,aAA+C,CAAC;AAE/C,eAAeF,gBAAgBG,UAAkB;IACtD,MAAMC,OAAO,MAAMC,mBAAmBF;IACtC,OAAOG,IAAAA,0BAAW,EAACF,KAAKG,MAAM;AAChC;AAOO,eAAeN,qBAAqBE,aAAqB,aAAa;IAC3E,+DAA+D;IAC/D,MAAMI,SAAS,MAAMP,gBAAgBG;IACrC,MAAMK,eAAyB,EAAE;IACjC,MAAMC,QAAQ,CAACC,MAAcC;QAC3B,IAAID,KAAKE,IAAI,IAAIF,KAAKE,IAAI,CAACC,KAAK,EAAE;YAChCL,aAAaM,IAAI,CAACH;QACpB;QACA,MAAMI,aAAaL,KAAKK,UAAU;QAClC,IAAIA,YAAY;YACdC,OAAOC,IAAI,CAACF,YAAYG,OAAO,CAAC,CAACC,WAC/BV,MAAMM,UAAU,CAACI,SAAS,EAAE,GAAGR,YAAYA,UAAUS,MAAM,GAAG,IAAI,MAAM,KAAKD,UAAU;QAE3F;IACF;IACAV,MAAMF,QAAQ;IAEd,OAAOC;AACT;AAEA,eAAeH,mBAAmBF,UAAkB;IAClD,IAAIkB,QAAG,CAACC,iBAAiB,EAAE;QACzB,OAAOC,KAAKC,KAAK,CACfC,aAAE,CACCC,YAAY,CACXC,eAAI,CAACC,IAAI,CACPP,QAAG,CAACC,iBAAiB,EACrB,UACA,OACA,eACA,4BAGHO,QAAQ;IAEf;IAEA,IAAI,CAAC3B,UAAU,CAACC,WAAW,EAAE;QAC3B,IAAI;YACFD,UAAU,CAACC,WAAW,GAAG,MAAM2B,4BAA4B3B;QAC7D,EAAE,OAAO4B,GAAQ;YACf,IAAIA,EAAEC,IAAI,KAAK,gBAAgB;gBAC7B,MAAM,IAAIC,oBAAY,CAAC,gBAAgB,CAAC,gCAAgC,CAAC;YAC3E;YAEA,MAAMF;QACR;IACF;IAEA,OAAO7B,UAAU,CAACC,WAAW;AAC/B;AAEA,eAAe2B,4BAA4B3B,UAAkB;IAC3D,gEAAgE;IAChE,MAAM+B,aAAaC,IAAAA,yBAAiB,EAAC;QACnCC,gBAAgB;QAChB,sFAAsF;QACtFC,KAAK,OAAO,KAAK,KAAK,KAAK;IAC7B;IACA,MAAMC,WAAW,MAAMJ,WAAW,CAAC,6BAA6B,EAAE/B,YAAY;IAC9E,MAAMC,OAAO,MAAMkC,SAASlC,IAAI;IAEhC,OAAOmC,IAAAA,8BAAsB,EAAanC;AAC5C"}
@@ -76,6 +76,23 @@ function _interop_require_default(obj) {
76
76
  default: obj
77
77
  };
78
78
  }
79
+ const PODFILE_HERMES_LHS = /(?::hermes_enabled\s*=>|hermes_enabled\s*:)/;
80
+ const PODFILE_HERMES_PROPS_REFERENCE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*podfile_properties\['expo\.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo\.jsEngine'\]\s*==\s*'hermes'\s*,?\s*(?:#.*)?$`, 'm');
81
+ const PODFILE_HERMES_TRUE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*true\s*(?:,\s*)?(?:[^\n]*)?$`, 'm');
82
+ const PODFILE_HERMES_FALSE_RE = new RegExp(String.raw`^\s*${PODFILE_HERMES_LHS.source}\s*false\s*(?:,\s*)?(?:[^\n]*)?$`, 'm');
83
+ function getLiteralHermesSettingFromPodfile(content) {
84
+ const isPropsReference = content.search(PODFILE_HERMES_PROPS_REFERENCE_RE) >= 0;
85
+ if (isPropsReference) {
86
+ return null;
87
+ }
88
+ if (PODFILE_HERMES_TRUE_RE.test(content)) {
89
+ return true;
90
+ }
91
+ if (PODFILE_HERMES_FALSE_RE.test(content)) {
92
+ return false;
93
+ }
94
+ return null;
95
+ }
79
96
  async function assertEngineMismatchAsync(projectRoot, exp, platform) {
80
97
  const isHermesManaged = isEnableHermesManaged(exp, platform);
81
98
  const paths = (0, _config().getConfigFilePaths)(projectRoot);
@@ -136,13 +153,15 @@ async function maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged)
136
153
  }
137
154
  function isHermesPossiblyEnabled(projectRoot) {
138
155
  // Trying best to check ios native project if by chance to be consistent between app config
139
- // Check ios/Podfile for ":hermes_enabled => true"
156
+ // Check ios/Podfile for a literal :hermes_enabled => (true|false) or hermes_enabled: (true|false)
140
157
  const podfilePath = _path().default.join(projectRoot, 'ios', 'Podfile');
141
158
  if (_fs().default.existsSync(podfilePath)) {
142
159
  const content = _fs().default.readFileSync(podfilePath, 'utf8');
143
- const isPropsReference = content.search(/^\s*:hermes_enabled\s*=>\s*podfile_properties\['expo.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo.jsEngine'\]\s*==\s*'hermes',?/m) >= 0;
144
- const isHermesBare = content.search(/^\s*:hermes_enabled\s*=>\s*true,?\s+/m) >= 0;
145
- if (!isPropsReference && isHermesBare) {
160
+ const literal = getLiteralHermesSettingFromPodfile(content);
161
+ if (literal != null) return literal;
162
+ // If there is no props reference and no literal, assume Hermes is enabled by default
163
+ const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);
164
+ if (!hasPropsReference) {
146
165
  return true;
147
166
  }
148
167
  }
@@ -160,14 +179,20 @@ function isHermesPossiblyEnabled(projectRoot) {
160
179
  }
161
180
  async function maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged) {
162
181
  // Trying best to check ios native project if by chance to be consistent between app config
163
- // Check ios/Podfile for ":hermes_enabled => true"
182
+ // Check ios/Podfile for a literal :hermes_enabled => (true|false)
164
183
  const podfilePath = _path().default.join(projectRoot, 'ios', 'Podfile');
165
184
  if (_fs().default.existsSync(podfilePath)) {
166
185
  const content = await _fs().default.promises.readFile(podfilePath, 'utf8');
167
- const isPropsReference = content.search(/^\s*:hermes_enabled\s*=>\s*podfile_properties\['expo.jsEngine'\]\s*==\s*nil\s*\|\|\s*podfile_properties\['expo.jsEngine'\]\s*==\s*'hermes',?/m) >= 0;
168
- const isHermesBare = content.search(/^\s*:hermes_enabled\s*=>\s*true,?\s+/m) >= 0;
169
- if (!isPropsReference && isHermesManaged !== isHermesBare) {
170
- return true;
186
+ const literal = getLiteralHermesSettingFromPodfile(content);
187
+ if (literal != null) {
188
+ if (isHermesManaged !== literal) return true;
189
+ } else {
190
+ // If there is no props reference and no literal, assume Hermes is enabled by default
191
+ const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);
192
+ if (!hasPropsReference) {
193
+ const assumedEnabled = true;
194
+ if (isHermesManaged !== assumedEnabled) return true;
195
+ }
171
196
  }
172
197
  }
173
198
  // Check Podfile.properties.json from prebuild template
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for \":hermes_enabled => true\"\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const isPropsReference =\n content.search(\n /^\\s*:hermes_enabled\\s*=>\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo.jsEngine'\\]\\s*==\\s*'hermes',?/m\n ) >= 0;\n const isHermesBare = content.search(/^\\s*:hermes_enabled\\s*=>\\s*true,?\\s+/m) >= 0;\n if (!isPropsReference && isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","content","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","isPropsReference","search","podfilePropertiesPath","JsonFile","read","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/export/exportHermes.ts"],"sourcesContent":["import { ExpoConfig, getConfigFilePaths, Platform } from '@expo/config';\nimport JsonFile from '@expo/json-file';\nimport fs from 'fs';\nimport path from 'path';\n\nconst PODFILE_HERMES_LHS = /(?::hermes_enabled\\s*=>|hermes_enabled\\s*:)/;\nconst PODFILE_HERMES_PROPS_REFERENCE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*podfile_properties\\['expo\\.jsEngine'\\]\\s*==\\s*nil\\s*\\|\\|\\s*podfile_properties\\['expo\\.jsEngine'\\]\\s*==\\s*'hermes'\\s*,?\\s*(?:#.*)?$`,\n 'm'\n);\nconst PODFILE_HERMES_TRUE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*true\\s*(?:,\\s*)?(?:[^\\n]*)?$`,\n 'm'\n);\nconst PODFILE_HERMES_FALSE_RE = new RegExp(\n String.raw`^\\s*${PODFILE_HERMES_LHS.source}\\s*false\\s*(?:,\\s*)?(?:[^\\n]*)?$`,\n 'm'\n);\n\nfunction getLiteralHermesSettingFromPodfile(content: string): boolean | null {\n const isPropsReference = content.search(PODFILE_HERMES_PROPS_REFERENCE_RE) >= 0;\n if (isPropsReference) {\n return null;\n }\n if (PODFILE_HERMES_TRUE_RE.test(content)) {\n return true;\n }\n if (PODFILE_HERMES_FALSE_RE.test(content)) {\n return false;\n }\n return null;\n}\n\nexport async function assertEngineMismatchAsync(\n projectRoot: string,\n exp: Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>,\n platform: Platform\n) {\n const isHermesManaged = isEnableHermesManaged(exp, platform);\n const paths = getConfigFilePaths(projectRoot);\n const configFilePath = paths.dynamicConfigPath ?? paths.staticConfigPath ?? 'app.json';\n await maybeThrowFromInconsistentEngineAsync(\n projectRoot,\n configFilePath,\n platform,\n isHermesManaged\n );\n}\n\nexport function isEnableHermesManaged(\n expoConfig: Partial<Pick<ExpoConfig, 'ios' | 'android' | 'jsEngine'>>,\n platform: string\n): boolean {\n switch (platform) {\n case 'android': {\n return (expoConfig.android?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n case 'ios': {\n return (expoConfig.ios?.jsEngine ?? expoConfig.jsEngine) !== 'jsc';\n }\n default:\n return false;\n }\n}\n\nexport function parseGradleProperties(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n for (let line of content.split('\\n')) {\n line = line.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const sepIndex = line.indexOf('=');\n const key = line.slice(0, sepIndex);\n const value = line.slice(sepIndex + 1);\n result[key] = value;\n }\n return result;\n}\n\nexport async function maybeThrowFromInconsistentEngineAsync(\n projectRoot: string,\n configFilePath: string,\n platform: string,\n isHermesManaged: boolean\n): Promise<void> {\n const configFileName = path.basename(configFilePath);\n if (\n platform === 'android' &&\n (await maybeInconsistentEngineAndroidAsync(projectRoot, isHermesManaged))\n ) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and Android native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In Android native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'android', 'gradle.properties')}\\n` +\n ` - ${path.join(projectRoot, 'android', 'app', 'build.gradle')}\\n` +\n 'Learn more: https://expo.fyi/hermes-android-config'\n );\n }\n\n if (platform === 'ios' && (await maybeInconsistentEngineIosAsync(projectRoot, isHermesManaged))) {\n throw new Error(\n `JavaScript engine configuration is inconsistent between ${configFileName} and iOS native project.\\n` +\n `In ${configFileName}: Hermes is ${isHermesManaged ? 'enabled' : 'not enabled'}\\n` +\n `In iOS native project: Hermes is ${isHermesManaged ? 'not enabled' : 'enabled'}\\n` +\n `Check the following files for inconsistencies:\\n` +\n ` - ${configFilePath}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile')}\\n` +\n ` - ${path.join(projectRoot, 'ios', 'Podfile.properties.json')}\\n` +\n 'Learn more: https://expo.fyi/hermes-ios-config'\n );\n }\n}\n\nexport async function maybeInconsistentEngineAndroidAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check android native project if by chance to be consistent between app config\n\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(await fs.promises.readFile(gradlePropertiesPath, 'utf8'));\n const isHermesBare = props['hermesEnabled'] === 'true';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function isHermesPossiblyEnabled(projectRoot: string): boolean | null {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for a literal :hermes_enabled => (true|false) or hermes_enabled: (true|false)\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = fs.readFileSync(podfilePath, 'utf8');\n const literal = getLiteralHermesSettingFromPodfile(content);\n if (literal != null) return literal;\n\n // If there is no props reference and no literal, assume Hermes is enabled by default\n const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);\n if (!hasPropsReference) {\n return true;\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n try {\n const props = JsonFile.read(podfilePropertiesPath);\n return props['expo.jsEngine'] === 'hermes';\n } catch {\n // ignore\n }\n }\n\n return null;\n}\n\nexport async function maybeInconsistentEngineIosAsync(\n projectRoot: string,\n isHermesManaged: boolean\n): Promise<boolean> {\n // Trying best to check ios native project if by chance to be consistent between app config\n\n // Check ios/Podfile for a literal :hermes_enabled => (true|false)\n const podfilePath = path.join(projectRoot, 'ios', 'Podfile');\n if (fs.existsSync(podfilePath)) {\n const content = await fs.promises.readFile(podfilePath, 'utf8');\n const literal = getLiteralHermesSettingFromPodfile(content);\n if (literal != null) {\n if (isHermesManaged !== literal) return true;\n } else {\n // If there is no props reference and no literal, assume Hermes is enabled by default\n const hasPropsReference = PODFILE_HERMES_PROPS_REFERENCE_RE.test(content);\n if (!hasPropsReference) {\n const assumedEnabled = true;\n if (isHermesManaged !== assumedEnabled) return true;\n }\n }\n }\n\n // Check Podfile.properties.json from prebuild template\n const podfilePropertiesPath = path.join(projectRoot, 'ios', 'Podfile.properties.json');\n if (fs.existsSync(podfilePropertiesPath)) {\n const props = await parsePodfilePropertiesAsync(podfilePropertiesPath);\n const isHermesBare = props['expo.jsEngine'] === 'hermes';\n if (isHermesManaged !== isHermesBare) {\n return true;\n }\n }\n\n return false;\n}\n\n// https://github.com/facebook/hermes/blob/release-v0.5/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25\nconst HERMES_MAGIC_HEADER = 'c61fbc03c103191f';\n\nexport async function isHermesBytecodeBundleAsync(file: string): Promise<boolean> {\n const header = await readHermesHeaderAsync(file);\n return header.subarray(0, 8).toString('hex') === HERMES_MAGIC_HEADER;\n}\n\nexport async function getHermesBytecodeBundleVersionAsync(file: string): Promise<number> {\n const header = await readHermesHeaderAsync(file);\n if (header.subarray(0, 8).toString('hex') !== HERMES_MAGIC_HEADER) {\n throw new Error('Invalid hermes bundle file');\n }\n return header.readUInt32LE(8);\n}\n\nasync function readHermesHeaderAsync(file: string): Promise<Buffer> {\n const fd = await fs.promises.open(file, 'r');\n const buffer = Buffer.alloc(12);\n await fd.read(buffer, 0, 12, null);\n await fd.close();\n return buffer;\n}\n\nasync function parsePodfilePropertiesAsync(\n podfilePropertiesPath: string\n): Promise<Record<string, string>> {\n try {\n return JSON.parse(await fs.promises.readFile(podfilePropertiesPath, 'utf8'));\n } catch {\n return {};\n }\n}\n\nexport function isAndroidUsingHermes(projectRoot: string) {\n // Check gradle.properties from prebuild template\n const gradlePropertiesPath = path.join(projectRoot, 'android', 'gradle.properties');\n if (fs.existsSync(gradlePropertiesPath)) {\n const props = parseGradleProperties(fs.readFileSync(gradlePropertiesPath, 'utf8'));\n return props['hermesEnabled'] === 'true';\n }\n\n // Assume Hermes is used by default.\n return true;\n}\n\nexport function isIosUsingHermes(projectRoot: string) {\n // If nullish, then assume Hermes is used.\n return isHermesPossiblyEnabled(projectRoot) !== false;\n}\n"],"names":["assertEngineMismatchAsync","getHermesBytecodeBundleVersionAsync","isAndroidUsingHermes","isEnableHermesManaged","isHermesBytecodeBundleAsync","isHermesPossiblyEnabled","isIosUsingHermes","maybeInconsistentEngineAndroidAsync","maybeInconsistentEngineIosAsync","maybeThrowFromInconsistentEngineAsync","parseGradleProperties","PODFILE_HERMES_LHS","PODFILE_HERMES_PROPS_REFERENCE_RE","RegExp","String","raw","source","PODFILE_HERMES_TRUE_RE","PODFILE_HERMES_FALSE_RE","getLiteralHermesSettingFromPodfile","content","isPropsReference","search","test","projectRoot","exp","platform","isHermesManaged","paths","getConfigFilePaths","configFilePath","dynamicConfigPath","staticConfigPath","expoConfig","android","jsEngine","ios","result","line","split","trim","startsWith","sepIndex","indexOf","key","slice","value","configFileName","path","basename","Error","join","gradlePropertiesPath","fs","existsSync","props","promises","readFile","isHermesBare","podfilePath","readFileSync","literal","hasPropsReference","podfilePropertiesPath","JsonFile","read","assumedEnabled","parsePodfilePropertiesAsync","HERMES_MAGIC_HEADER","file","header","readHermesHeaderAsync","subarray","toString","readUInt32LE","fd","open","buffer","Buffer","alloc","close","JSON","parse"],"mappings":"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"}
@@ -33,7 +33,7 @@ class FetchClient {
33
33
  this.headers = {
34
34
  accept: 'application/json',
35
35
  'content-type': 'application/json',
36
- 'user-agent': `expo-cli/${"0.24.20"}`,
36
+ 'user-agent': `expo-cli/${"0.24.21"}`,
37
37
  authorization: 'Basic ' + _nodebuffer().Buffer.from(`${target}:`).toString('base64')
38
38
  };
39
39
  }
@@ -83,7 +83,7 @@ function createContext() {
83
83
  cpu: summarizeCpuInfo(),
84
84
  app: {
85
85
  name: 'expo/cli',
86
- version: "0.24.20"
86
+ version: "0.24.21"
87
87
  },
88
88
  ci: _ciinfo().isCI ? {
89
89
  name: _ciinfo().name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/cli",
3
- "version": "0.24.20",
3
+ "version": "0.24.21",
4
4
  "description": "The Expo CLI",
5
5
  "main": "build/bin/cli",
6
6
  "bin": {
@@ -53,10 +53,11 @@
53
53
  "@expo/package-manager": "^1.8.6",
54
54
  "@expo/plist": "^0.3.5",
55
55
  "@expo/prebuild-config": "^9.0.11",
56
+ "@expo/schema-utils": "^0.1.0",
56
57
  "@expo/spawn-async": "^1.7.2",
57
58
  "@expo/ws-tunnel": "^1.0.1",
58
59
  "@expo/xcpretty": "^4.3.0",
59
- "@react-native/dev-middleware": "0.79.5",
60
+ "@react-native/dev-middleware": "0.79.6",
60
61
  "@urql/core": "^5.0.6",
61
62
  "@urql/exchange-retry": "^1.3.0",
62
63
  "accepts": "^1.3.8",
@@ -139,7 +140,7 @@
139
140
  "@types/ws": "^8.5.4",
140
141
  "devtools-protocol": "^0.0.1113120",
141
142
  "expo-atlas": "^0.4.1",
142
- "expo-module-scripts": "^4.1.9",
143
+ "expo-module-scripts": "^4.1.10",
143
144
  "find-process": "^1.4.7",
144
145
  "jest-runner-tsd": "^6.0.0",
145
146
  "klaw-sync": "^6.0.0",
@@ -152,5 +153,5 @@
152
153
  "tree-kill": "^1.2.2",
153
154
  "tsd": "^0.28.1"
154
155
  },
155
- "gitHead": "134c147ee4274f9688929ac66cfef950947659d0"
156
+ "gitHead": "85192ee6f5e76e0e81f91151c9c8aaca43c22c65"
156
157
  }
@@ -1,150 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "jsonSchemaDeref", {
6
- enumerable: true,
7
- get: function() {
8
- return jsonSchemaDeref;
9
- }
10
- });
11
- /** Return JSON schema ref if input is of `NodeRef` type */ const getRef = (node)=>node != null && typeof node === 'object' && '$ref' in node && typeof node.$ref === 'string' ? node.$ref : undefined;
12
- /** Parse a JSON schema ref into a path array, or return undefined */ const parseRefMaybe = (ref)=>{
13
- if (ref[0] !== '#') {
14
- return undefined;
15
- }
16
- const props = [];
17
- let startIndex = 1;
18
- let index = 1;
19
- let char;
20
- while(index < ref.length){
21
- while((char = ref.charCodeAt(index++)) && char !== 47 /*'/'*/ );
22
- const prop = ref.slice(startIndex, index - 1);
23
- startIndex = index;
24
- if (prop) props.push(prop);
25
- }
26
- return props.length ? props : undefined;
27
- };
28
- const NOT_FOUND_SYMBOL = Symbol();
29
- /** Get value at given JSON schema path or return `NOT_FOUND_SYMBOL` */ const getValueAtPath = (input, ref)=>{
30
- let node = input;
31
- for(let index = 0; index < ref.length; index++){
32
- const part = ref[index];
33
- if (node != null && typeof node === 'object' && part in node) {
34
- node = node[part];
35
- } else {
36
- node = NOT_FOUND_SYMBOL;
37
- break;
38
- }
39
- }
40
- return node;
41
- };
42
- /** Find all JSON schema refs recursively and add them to `refs` Map */ const findRefsRec = (node, refs, path)=>{
43
- if (node == null || typeof node !== 'object') {} else if (Array.isArray(node)) {
44
- for(let index = 0, l = node.length; index < l; index++){
45
- const value = node[index];
46
- const ref = getRef(value);
47
- if (ref) {
48
- const targetRef = parseRefMaybe(ref);
49
- if (targetRef) refs.set([
50
- ...path,
51
- index
52
- ], targetRef);
53
- } else if (value != null && typeof value === 'object') {
54
- path.push(index);
55
- findRefsRec(value, refs, path);
56
- path.pop();
57
- }
58
- }
59
- } else {
60
- const record = node;
61
- for(const key in record){
62
- const value = record[key];
63
- const ref = getRef(value);
64
- if (ref) {
65
- const targetRef = parseRefMaybe(ref);
66
- if (targetRef) refs.set([
67
- ...path,
68
- key
69
- ], targetRef);
70
- } else if (value != null && typeof value === 'object') {
71
- path.push(key);
72
- findRefsRec(value, refs, path);
73
- path.pop();
74
- }
75
- }
76
- }
77
- };
78
- /** Detect whether target (where we set the source value) is a nested path inside the source path */ const isSelfReferencingRefEntry = (target, source)=>{
79
- for(let index = 0; index < source.length; index++){
80
- if (source[index] !== target[index]) return false;
81
- }
82
- return true;
83
- };
84
- /** Return sorted refs entries. Longest target paths will be returned first */ const getSortedRefEntries = (refs)=>{
85
- const entries = [
86
- ...refs.entries()
87
- ].sort((a, b)=>b[1].length - a[1].length);
88
- // Filter out self-referenceing paths. If we set nested targets to source values, we'd
89
- // create unserializable circular references
90
- return entries.filter((entry)=>!isSelfReferencingRefEntry(entry[0], entry[1]));
91
- };
92
- function jsonSchemaDeref(input) {
93
- // Find all JSON schema refs paths
94
- const refs = new Map();
95
- findRefsRec(input, refs, []);
96
- // Shallow copy output
97
- const output = {
98
- ...input
99
- };
100
- // Process all ref entries with deepest targets first
101
- nextRef: for (const [target, source] of getSortedRefEntries(refs)){
102
- let inputNode = input;
103
- let outputNode = output;
104
- let targetIndex = 0;
105
- // For each path part on the target, traverse the output and clone the input
106
- // to not pollute it
107
- for(; targetIndex < target.length - 1; targetIndex++){
108
- const part = target[targetIndex];
109
- if (inputNode == null || typeof inputNode !== 'object' || !(part in inputNode)) {
110
- break;
111
- } else if (outputNode[part] === inputNode[part]) {
112
- // Copy the input on the output if references are equal
113
- outputNode[part] = Array.isArray(inputNode[part]) ? [
114
- ...inputNode[part]
115
- ] : {
116
- ...inputNode[part]
117
- };
118
- inputNode = inputNode[part];
119
- outputNode = outputNode[part];
120
- } else {
121
- break;
122
- }
123
- }
124
- // For each remaining part on the target, continue traversing the output
125
- for(; targetIndex < target.length - 1; targetIndex++){
126
- const part = target[targetIndex];
127
- if (outputNode == null || typeof outputNode !== 'object' || !(part in outputNode)) {
128
- continue nextRef;
129
- } else {
130
- outputNode = outputNode[part];
131
- }
132
- }
133
- // Get value from output
134
- let sourceValue = getValueAtPath(output, source);
135
- if (sourceValue === NOT_FOUND_SYMBOL) {
136
- // If no value was found, try to get a value from the input instead
137
- sourceValue = getValueAtPath(input, source);
138
- // Otherwise, skip this ref
139
- if (sourceValue === NOT_FOUND_SYMBOL) continue;
140
- }
141
- // Set the source value on the target path
142
- // The for-loops prior have made sure that the output has already been deeply
143
- // cloned and traversed for the entire path
144
- outputNode[target[target.length - 1]] = sourceValue;
145
- }
146
- // Return the output with resolved refs
147
- return output;
148
- }
149
-
150
- //# sourceMappingURL=jsonSchemaDeref.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/utils/jsonSchemaDeref.ts"],"sourcesContent":["type RefPath = readonly (string | number)[];\n\ninterface NodeRef {\n $ref: string;\n}\n\n/** Return JSON schema ref if input is of `NodeRef` type */\nconst getRef = (node: NodeRef | unknown): string | undefined =>\n node != null && typeof node === 'object' && '$ref' in node && typeof node.$ref === 'string'\n ? node.$ref\n : undefined;\n\n/** Parse a JSON schema ref into a path array, or return undefined */\nconst parseRefMaybe = (ref: string): RefPath | undefined => {\n if (ref[0] !== '#') {\n return undefined;\n }\n const props = [];\n let startIndex = 1;\n let index = 1;\n let char: number;\n while (index < ref.length) {\n while ((char = ref.charCodeAt(index++)) && char !== 47 /*'/'*/);\n const prop = ref.slice(startIndex, index - 1);\n startIndex = index;\n if (prop) props.push(prop);\n }\n return props.length ? props : undefined;\n};\n\nconst NOT_FOUND_SYMBOL = Symbol();\n\n/** Get value at given JSON schema path or return `NOT_FOUND_SYMBOL` */\nconst getValueAtPath = (input: unknown, ref: RefPath): unknown | typeof NOT_FOUND_SYMBOL => {\n let node = input;\n for (let index = 0; index < ref.length; index++) {\n const part = ref[index];\n if (node != null && typeof node === 'object' && part in node) {\n node = (node as Record<string, unknown>)[part];\n } else {\n node = NOT_FOUND_SYMBOL;\n break;\n }\n }\n return node;\n};\n\n/** Find all JSON schema refs recursively and add them to `refs` Map */\nconst findRefsRec = (\n node: unknown,\n refs: Map<RefPath, RefPath>,\n path: (string | number)[]\n): void => {\n if (node == null || typeof node !== 'object') {\n } else if (Array.isArray(node)) {\n for (let index = 0, l = node.length; index < l; index++) {\n const value = node[index];\n const ref = getRef(value);\n if (ref) {\n const targetRef = parseRefMaybe(ref);\n if (targetRef) refs.set([...path, index], targetRef);\n } else if (value != null && typeof value === 'object') {\n path.push(index);\n findRefsRec(value, refs, path);\n path.pop();\n }\n }\n } else {\n const record = node as Record<string, unknown>;\n for (const key in record) {\n const value = record[key];\n const ref = getRef(value);\n if (ref) {\n const targetRef = parseRefMaybe(ref);\n if (targetRef) refs.set([...path, key], targetRef);\n } else if (value != null && typeof value === 'object') {\n path.push(key);\n findRefsRec(value, refs, path);\n path.pop();\n }\n }\n }\n};\n\n/** Detect whether target (where we set the source value) is a nested path inside the source path */\nconst isSelfReferencingRefEntry = (target: RefPath, source: RefPath) => {\n for (let index = 0; index < source.length; index++) {\n if (source[index] !== target[index]) return false;\n }\n return true;\n};\n\n/** Return sorted refs entries. Longest target paths will be returned first */\nconst getSortedRefEntries = (refs: Map<RefPath, RefPath>): readonly [RefPath, RefPath][] => {\n const entries = [...refs.entries()].sort((a, b) => b[1].length - a[1].length);\n // Filter out self-referenceing paths. If we set nested targets to source values, we'd\n // create unserializable circular references\n return entries.filter((entry) => !isSelfReferencingRefEntry(entry[0], entry[1]));\n};\n\n/** Dereference JSON schema pointers.\n *\n * @remarks\n * This is a minimal reimplementation of `json-schema-deref-sync` without\n * file reference, URL/web reference, and loader support.\n *\n * @see https://github.com/cvent/json-schema-deref-sync\n */\nexport function jsonSchemaDeref(input: any): any {\n // Find all JSON schema refs paths\n const refs = new Map<RefPath, RefPath>();\n findRefsRec(input, refs, []);\n // Shallow copy output\n const output = { ...input };\n // Process all ref entries with deepest targets first\n nextRef: for (const [target, source] of getSortedRefEntries(refs)) {\n let inputNode = input;\n let outputNode = output;\n let targetIndex = 0;\n // For each path part on the target, traverse the output and clone the input\n // to not pollute it\n for (; targetIndex < target.length - 1; targetIndex++) {\n const part = target[targetIndex];\n if (inputNode == null || typeof inputNode !== 'object' || !(part in inputNode)) {\n // If the part doesn't exist, we abort\n break;\n } else if (outputNode[part] === inputNode[part]) {\n // Copy the input on the output if references are equal\n outputNode[part] = Array.isArray(inputNode[part])\n ? [...inputNode[part]]\n : { ...inputNode[part] };\n inputNode = inputNode[part];\n outputNode = outputNode[part];\n } else {\n // If this part has already been copied, abort\n break;\n }\n }\n // For each remaining part on the target, continue traversing the output\n for (; targetIndex < target.length - 1; targetIndex++) {\n const part = target[targetIndex];\n if (outputNode == null || typeof outputNode !== 'object' || !(part in outputNode)) {\n // If the part doesn't exist, skip the entire ref\n continue nextRef;\n } else {\n outputNode = outputNode[part];\n }\n }\n // Get value from output\n let sourceValue = getValueAtPath(output, source);\n if (sourceValue === NOT_FOUND_SYMBOL) {\n // If no value was found, try to get a value from the input instead\n sourceValue = getValueAtPath(input, source);\n // Otherwise, skip this ref\n if (sourceValue === NOT_FOUND_SYMBOL) continue;\n }\n // Set the source value on the target path\n // The for-loops prior have made sure that the output has already been deeply\n // cloned and traversed for the entire path\n outputNode[target[target.length - 1]] = sourceValue;\n }\n // Return the output with resolved refs\n return output;\n}\n"],"names":["jsonSchemaDeref","getRef","node","$ref","undefined","parseRefMaybe","ref","props","startIndex","index","char","length","charCodeAt","prop","slice","push","NOT_FOUND_SYMBOL","Symbol","getValueAtPath","input","part","findRefsRec","refs","path","Array","isArray","l","value","targetRef","set","pop","record","key","isSelfReferencingRefEntry","target","source","getSortedRefEntries","entries","sort","a","b","filter","entry","Map","output","nextRef","inputNode","outputNode","targetIndex","sourceValue"],"mappings":"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"}