create-expo 5.0.0 → 5.1.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.
Files changed (58) hide show
  1. package/build/{205.index.js → 589.index.js} +442 -128
  2. package/build/601.index.js +20 -11
  3. package/build/{525.index.js → 870.index.js} +423 -334
  4. package/build/Examples.d.ts +38 -0
  5. package/build/Template.d.ts +98 -0
  6. package/build/__mocks__/fs.d.ts +1 -0
  7. package/build/__mocks__/ora.d.ts +1 -0
  8. package/build/__tests__/Examples.test.d.ts +1 -0
  9. package/build/__tests__/Template.test.d.ts +1 -0
  10. package/build/__tests__/configureWorkspaces.test.d.ts +1 -0
  11. package/build/__tests__/createAsync.test.d.ts +1 -0
  12. package/build/__tests__/createExpoConfig.test.d.ts +1 -0
  13. package/build/__tests__/createFileTransformer.test.d.ts +1 -0
  14. package/build/__tests__/generateAgentFiles.test.d.ts +1 -0
  15. package/build/__tests__/promptSdkVersion.test.d.ts +1 -0
  16. package/build/__tests__/resolvePackageManager.test.d.ts +1 -0
  17. package/build/__tests__/sanitizeTemplate.test.d.ts +1 -0
  18. package/build/__tests__/telemetry.test.d.ts +1 -0
  19. package/build/agent-files/AGENTS.md +41 -0
  20. package/build/agent-files/CLAUDE.md +1 -0
  21. package/build/cli.d.ts +1 -0
  22. package/build/configureWorkspaces.d.ts +9 -0
  23. package/build/createAsync.d.ts +11 -0
  24. package/build/createExpoConfig.d.ts +38 -0
  25. package/build/createFileTransform.d.ts +5 -0
  26. package/build/error.d.ts +9 -0
  27. package/build/generateAgentFiles.d.ts +1 -0
  28. package/build/index.d.ts +1 -0
  29. package/build/index.js +38 -10
  30. package/build/legacyTemplates.d.ts +7 -0
  31. package/build/log.d.ts +12 -0
  32. package/build/paths.d.ts +2 -0
  33. package/build/promptSdkVersion.d.ts +23 -0
  34. package/build/resolvePackageManager.d.ts +12 -0
  35. package/build/resolveProjectRoot.d.ts +3 -0
  36. package/build/sessionStorage.d.ts +8 -0
  37. package/build/telemetry.d.ts +29 -0
  38. package/build/utils/__tests__/args.test.d.ts +1 -0
  39. package/build/utils/__tests__/array.test.d.ts +1 -0
  40. package/build/utils/__tests__/log.test.d.ts +1 -0
  41. package/build/utils/__tests__/npm.test.d.ts +1 -0
  42. package/build/utils/__tests__/obj.test.d.ts +1 -0
  43. package/build/utils/args.d.ts +33 -0
  44. package/build/utils/array.d.ts +1 -0
  45. package/build/utils/dir.d.ts +1 -0
  46. package/build/utils/env.d.ts +14 -0
  47. package/build/utils/fetch.d.ts +2 -0
  48. package/build/utils/git.d.ts +1 -0
  49. package/build/utils/github.d.ts +2 -0
  50. package/build/utils/log.d.ts +6 -0
  51. package/build/utils/npm.d.ts +52 -0
  52. package/build/utils/obj.d.ts +1 -0
  53. package/build/utils/tar.d.ts +10 -0
  54. package/build/utils/update-check.d.ts +2 -0
  55. package/package.json +33 -21
  56. package/template/agent-files/AGENTS.md +41 -0
  57. package/template/agent-files/CLAUDE.md +1 -0
  58. package/build/517.index.js +0 -1380
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- exports.id = 205;
3
- exports.ids = [205,601];
2
+ exports.id = 589;
3
+ exports.ids = [589,601];
4
4
  exports.modules = {
5
5
 
6
- /***/ 8205:
6
+ /***/ 589:
7
7
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
8
 
9
9
 
@@ -12,7 +12,7 @@ __webpack_require__.d(__webpack_exports__, {
12
12
  createAsync: () => (/* binding */ createAsync)
13
13
  });
14
14
 
15
- // UNUSED EXPORTS: logNodeInstallWarning
15
+ // UNUSED EXPORTS: logNodeInstallWarning, setupDependenciesAsync
16
16
 
17
17
  // EXTERNAL MODULE: ../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js
18
18
  var source = __webpack_require__(2314);
@@ -25,7 +25,6 @@ var external_path_ = __webpack_require__(6928);
25
25
  var external_path_default = /*#__PURE__*/__webpack_require__.n(external_path_);
26
26
  // EXTERNAL MODULE: ../@expo/json-file/build/JsonFile.js
27
27
  var JsonFile = __webpack_require__(3064);
28
- var JsonFile_default = /*#__PURE__*/__webpack_require__.n(JsonFile);
29
28
  // EXTERNAL MODULE: ../../node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/index.js
30
29
  var prompts = __webpack_require__(6133);
31
30
  var prompts_default = /*#__PURE__*/__webpack_require__.n(prompts);
@@ -36,8 +35,69 @@ var index_min = __webpack_require__(9337);
36
35
  // EXTERNAL MODULE: ../../node_modules/.pnpm/ora@3.4.0/node_modules/ora/index.js
37
36
  var ora = __webpack_require__(5344);
38
37
  var ora_default = /*#__PURE__*/__webpack_require__.n(ora);
39
- // EXTERNAL MODULE: ../../node_modules/.pnpm/multitars@1.0.0/node_modules/multitars/dist/multitars.mjs
40
- var multitars = __webpack_require__(912);
38
+ // EXTERNAL MODULE: ./src/log.ts
39
+ var log = __webpack_require__(1545);
40
+ ;// CONCATENATED MODULE: ./src/createExpoConfig.ts
41
+
42
+
43
+
44
+ const debug = __webpack_require__(6675)('expo:init:monorepo-config');
45
+ const CREATE_EXPO_CONFIG_NAME = '.create-expo.json';
46
+ /**
47
+ * Read `.create-expo.json` from the project root and immediately
48
+ * delete the file from disk so it doesn't leak into the user's project.
49
+ * Returns the parsed config (or `undefined` if there's no file / it's
50
+ * malformed). This is the "use it once" entry point that template-extraction
51
+ * code paths should call — every downstream consumer takes the parsed
52
+ * object in memory.
53
+ */
54
+ async function consumeMonorepoConfigAsync(projectRoot) {
55
+ const config = await loadMonorepoConfigAsync(projectRoot);
56
+ await external_fs_default().promises
57
+ .rm(external_path_default().join(projectRoot, CREATE_EXPO_CONFIG_NAME), { force: true })
58
+ .catch(() => undefined);
59
+ return config;
60
+ }
61
+ /**
62
+ * Reads `.create-expo.json` from the project root without touching
63
+ * the file. Returns `undefined` if the file is missing, unreadable, or
64
+ * malformed — a missing file is the common case (single-app templates) and
65
+ * shouldn't warn.
66
+ *
67
+ * Prefer `consumeMonorepoConfigAsync` for the create-expo flow so the
68
+ * template-only config doesn't leak into the user's project. This function
69
+ * stays exported for tests and any other read-only callers.
70
+ */
71
+ async function loadMonorepoConfigAsync(projectRoot) {
72
+ const configPath = external_path_default().join(projectRoot, CREATE_EXPO_CONFIG_NAME);
73
+ let contents;
74
+ try {
75
+ contents = await external_fs_default().promises.readFile(configPath, { encoding: 'utf-8' });
76
+ }
77
+ catch (error) {
78
+ if (error?.code !== 'ENOENT') {
79
+ log/* Log */.tG.log(`Could not read ${CREATE_EXPO_CONFIG_NAME}; ignoring: ${error?.message ?? error}`);
80
+ }
81
+ return undefined;
82
+ }
83
+ let parsed;
84
+ try {
85
+ parsed = JSON.parse(contents);
86
+ }
87
+ catch (error) {
88
+ log/* Log */.tG.log(`${CREATE_EXPO_CONFIG_NAME} could not be parsed as JSON; ignoring: ${error?.message ?? error}`);
89
+ return undefined;
90
+ }
91
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
92
+ log/* Log */.tG.log(`${CREATE_EXPO_CONFIG_NAME} did not parse as a JSON object; ignoring.`);
93
+ return undefined;
94
+ }
95
+ debug(`Loaded ${CREATE_EXPO_CONFIG_NAME}`);
96
+ return parsed;
97
+ }
98
+
99
+ // EXTERNAL MODULE: ../../node_modules/.pnpm/multitars@1.0.2/node_modules/multitars/dist/multitars.mjs
100
+ var multitars = __webpack_require__(6378);
41
101
  // EXTERNAL MODULE: ../../node_modules/.pnpm/picomatch@2.3.2/node_modules/picomatch/index.js
42
102
  var picomatch = __webpack_require__(3268);
43
103
  var picomatch_default = /*#__PURE__*/__webpack_require__.n(picomatch);
@@ -45,7 +105,7 @@ var picomatch_default = /*#__PURE__*/__webpack_require__.n(picomatch);
45
105
 
46
106
 
47
107
 
48
- const debug = __webpack_require__(6675)('expo:init:fileTransform');
108
+ const createFileTransform_debug = __webpack_require__(6675)('expo:init:fileTransform');
49
109
  function sanitizedName(name) {
50
110
  return name
51
111
  .replace(/[\W_]+/g, '')
@@ -87,16 +147,14 @@ function createEntryRenamer(name) {
87
147
  }
88
148
  function createGlobFilter(globPattern, options) {
89
149
  const matcher = picomatch_default()(globPattern, options);
90
- debug('filter: created for pattern %s (%s)', globPattern);
150
+ createFileTransform_debug('filter: created for pattern %s (%s)', globPattern);
91
151
  return (path) => {
92
152
  const included = matcher(path);
93
- debug('filter: %s - %s', included ? 'include' : 'exclude', path);
153
+ createFileTransform_debug('filter: %s - %s', included ? 'include' : 'exclude', path);
94
154
  return included;
95
155
  };
96
156
  }
97
157
 
98
- // EXTERNAL MODULE: ./src/log.ts
99
- var log = __webpack_require__(1545);
100
158
  // EXTERNAL MODULE: ./src/resolvePackageManager.ts
101
159
  var resolvePackageManager = __webpack_require__(9560);
102
160
  // EXTERNAL MODULE: ./src/utils/env.ts
@@ -131,6 +189,57 @@ var external_os_ = __webpack_require__(857);
131
189
  var external_os_default = /*#__PURE__*/__webpack_require__.n(external_os_);
132
190
  // EXTERNAL MODULE: external "stream"
133
191
  var external_stream_ = __webpack_require__(2203);
192
+ ;// CONCATENATED MODULE: ./src/legacyTemplates.ts
193
+
194
+
195
+
196
+ const LEGACY_TEMPLATES = [
197
+ {
198
+ title: 'Default',
199
+ value: 'expo-template-default',
200
+ description: 'includes tools recommended for most app developers',
201
+ },
202
+ {
203
+ title: 'Blank',
204
+ value: 'expo-template-blank',
205
+ description: 'a minimal app as clean as an empty canvas',
206
+ },
207
+ {
208
+ title: 'Blank (TypeScript)',
209
+ value: 'expo-template-blank-typescript',
210
+ description: 'blank app with TypeScript enabled',
211
+ },
212
+ {
213
+ title: 'Navigation (TypeScript)',
214
+ value: 'expo-template-tabs',
215
+ description: 'File-based routing with TypeScript enabled',
216
+ },
217
+ {
218
+ title: 'Blank (Bare)',
219
+ value: 'expo-template-bare-minimum',
220
+ description: 'blank app with the native code exposed (expo prebuild)',
221
+ },
222
+ ];
223
+ const ALIASES = LEGACY_TEMPLATES.map(({ value }) => value);
224
+ async function promptTemplateAsync() {
225
+ if (env.env.CI) {
226
+ throw new Error('Cannot prompt for template in CI');
227
+ }
228
+ const { answer } = await prompts_default()({
229
+ type: 'select',
230
+ name: 'answer',
231
+ message: 'Choose a template:',
232
+ choices: LEGACY_TEMPLATES,
233
+ });
234
+ if (!answer) {
235
+ console.log();
236
+ console.log(source_default() `Specify the template name, example: {cyan --template expo-template-blank}`);
237
+ console.log();
238
+ process.exit(1);
239
+ }
240
+ return answer;
241
+ }
242
+
134
243
  // EXTERNAL MODULE: external "node:crypto"
135
244
  var external_node_crypto_ = __webpack_require__(5217);
136
245
  var external_node_crypto_default = /*#__PURE__*/__webpack_require__.n(external_node_crypto_);
@@ -262,57 +371,6 @@ async function extractAsync(input, output, options) {
262
371
  await extractStream(Readable.toWeb(fs.createReadStream(input)), output, options);
263
372
  }
264
373
 
265
- ;// CONCATENATED MODULE: ./src/legacyTemplates.ts
266
-
267
-
268
-
269
- const LEGACY_TEMPLATES = [
270
- {
271
- title: 'Default',
272
- value: 'expo-template-default',
273
- description: 'includes tools recommended for most app developers',
274
- },
275
- {
276
- title: 'Blank',
277
- value: 'expo-template-blank',
278
- description: 'a minimal app as clean as an empty canvas',
279
- },
280
- {
281
- title: 'Blank (TypeScript)',
282
- value: 'expo-template-blank-typescript',
283
- description: 'blank app with TypeScript enabled',
284
- },
285
- {
286
- title: 'Navigation (TypeScript)',
287
- value: 'expo-template-tabs',
288
- description: 'File-based routing with TypeScript enabled',
289
- },
290
- {
291
- title: 'Blank (Bare)',
292
- value: 'expo-template-bare-minimum',
293
- description: 'blank app with the native code exposed (expo prebuild)',
294
- },
295
- ];
296
- const ALIASES = LEGACY_TEMPLATES.map(({ value }) => value);
297
- async function promptTemplateAsync() {
298
- if (env.env.CI) {
299
- throw new Error('Cannot prompt for template in CI');
300
- }
301
- const { answer } = await prompts_default()({
302
- type: 'select',
303
- name: 'answer',
304
- message: 'Choose a template:',
305
- choices: LEGACY_TEMPLATES,
306
- });
307
- if (!answer) {
308
- console.log();
309
- console.log(source_default() `Specify the template name, example: {cyan --template expo-template-blank}`);
310
- console.log();
311
- process.exit(1);
312
- }
313
- return answer;
314
- }
315
-
316
374
  ;// CONCATENATED MODULE: ./src/utils/npm.ts
317
375
 
318
376
 
@@ -424,8 +482,9 @@ async function npmPackAsync(packageName, cwd = undefined, ...props) {
424
482
  }
425
483
  try {
426
484
  const json = JSON.parse(results);
427
- if (Array.isArray(json) && json.every(isNpmPackageInfo)) {
428
- return json.map(sanitizeNpmPackageFilename);
485
+ const packages = normalizeNpmPackResult(json);
486
+ if (packages?.every(isNpmPackageInfo)) {
487
+ return packages.map(sanitizeNpmPackageFilename);
429
488
  }
430
489
  else {
431
490
  throw new Error(`Invalid response from npm: ${results}`);
@@ -435,6 +494,18 @@ async function npmPackAsync(packageName, cwd = undefined, ...props) {
435
494
  throw new Error(`Could not parse JSON returned from "${cmdString}".\n\n${results}\n\nError: ${error.message}`);
436
495
  }
437
496
  }
497
+ /** Normalize the npm pack JSON formats used before and after npm 12 */
498
+ function normalizeNpmPackResult(result) {
499
+ if (Array.isArray(result)) {
500
+ return result;
501
+ }
502
+ else if (result && typeof result === 'object') {
503
+ return Object.values(result);
504
+ }
505
+ else {
506
+ return null;
507
+ }
508
+ }
438
509
  function getNpmBin() {
439
510
  return process.platform === 'win32' ? 'npm.cmd' : 'npm';
440
511
  }
@@ -507,6 +578,7 @@ async function downloadAndExtractNpmModuleAsync(npmName, output, props) {
507
578
 
508
579
 
509
580
 
581
+
510
582
  const github_debug = __webpack_require__(6675)('expo:init:github');
511
583
  // See: https://github.com/expo/expo/blob/a5a6eecb082b2c7a7fc9956141738231c7df473f/packages/%40expo/cli/src/prebuild/resolveTemplate.ts#L60-L84
512
584
  async function getGitHubRepoAsync(url) {
@@ -552,9 +624,15 @@ async function extractRemoteGitHubTarballAsync(url, repo, output, props) {
552
624
  const strip = directory.length + 1;
553
625
  // Only extract the relevant (sub)directories, ignoring irrelevant files
554
626
  // The filter auto-ignores dotfiles, unless explicitly included
555
- const filter = createGlobFilter(!directory.length
556
- ? ['*/**', '*/ios/.xcode.env']
557
- : [`*/${directory.join('/')}/**`, `*/${directory.join('/')}/ios/.xcode.env`], {
627
+ const subDirPrefix = directory.length ? `*/${directory.join('/')}` : '*';
628
+ const filter = createGlobFilter([
629
+ `${subDirPrefix}/**`,
630
+ `${subDirPrefix}/ios/.xcode.env`,
631
+ // Templates ship their monorepo config as a root-level dotfile; without
632
+ // an explicit allow-list entry, picomatch's default `dot: false` drops
633
+ // it during extraction so downstream consumers see no config at all.
634
+ `${subDirPrefix}/${CREATE_EXPO_CONFIG_NAME}`,
635
+ ], {
558
636
  // Always ignore the `.xcworkspace` folder
559
637
  ignore: ['**/ios/*.xcworkspace/**'],
560
638
  });
@@ -569,7 +647,7 @@ async function downloadAndExtractGitHubRepositoryAsync(repoUrl, output, props) {
569
647
  const info = await getGitHubRepoAsync(repoUrl);
570
648
  const isValid = await isValidGitHubRepoAsync(info);
571
649
  if (!isValid) {
572
- throw new Error(`Could not to locate repository for "${repoUrl}", ensure this repository exists`);
650
+ throw new Error(`Could not locate repository for "${repoUrl}", ensure this repository exists`);
573
651
  }
574
652
  const url = `https://codeload.github.com/${info.owner}/${info.name}/tar.gz/${info.branch}`;
575
653
  github_debug('Resolved GitHub repository', info);
@@ -591,6 +669,7 @@ async function downloadAndExtractGitHubRepositoryAsync(repoUrl, output, props) {
591
669
 
592
670
 
593
671
 
672
+
594
673
  const Template_debug = __webpack_require__(6675)('expo:init:template');
595
674
  const isMacOS = process.platform === 'darwin';
596
675
  // keep this list in sync with the validation helper in WWW: src/utils/experienceParser.ts
@@ -675,6 +754,11 @@ function resolvePackageModuleId(moduleId) {
675
754
  /**
676
755
  * Extract a template app to a given file path and clean up any properties left over from npm to
677
756
  * prepare it for usage.
757
+ *
758
+ * If the template ships a `.create-expo.json`, its `renamePatterns`
759
+ * field overrides the default rename config used by the HelloWorld
760
+ * find-and-replace pass. The config file is read once and deleted from disk
761
+ * immediately so it can never leak into the user's project.
678
762
  */
679
763
  async function extractAndPrepareTemplateAppAsync(projectRoot, { npmPackage }) {
680
764
  const projectName = external_path_default().basename(projectRoot);
@@ -692,8 +776,12 @@ async function extractAndPrepareTemplateAppAsync(projectRoot, { npmPackage }) {
692
776
  disableCache: type === 'file',
693
777
  });
694
778
  }
779
+ const monorepoConfig = await consumeMonorepoConfigAsync(projectRoot);
695
780
  try {
696
- const files = await getTemplateFilesToRenameAsync({ cwd: projectRoot });
781
+ const files = await getTemplateFilesToRenameAsync({
782
+ cwd: projectRoot,
783
+ renameConfig: monorepoConfig?.renamePatterns,
784
+ });
697
785
  await renameTemplateAppNameAsync({
698
786
  cwd: projectRoot,
699
787
  files,
@@ -745,8 +833,8 @@ function escapeXMLCharacters(original) {
745
833
  * Whitespace is trimmed and whitespace-only lines are ignored.
746
834
  *
747
835
  * If no rename config has been passed directly to
748
- * `getTemplateFilesToRenameAsync()` then this default rename config will be
749
- * used instead.
836
+ * `getTemplateFilesToRenameAsync()`, then this default
837
+ * rename config will be used instead.
750
838
  */
751
839
  const defaultRenameConfig = [
752
840
  // Common
@@ -805,7 +893,9 @@ async function renameTemplateAppNameAsync({ cwd, name, files, }) {
805
893
  const absoluteFilePath = external_path_default().resolve(cwd, file);
806
894
  let contents;
807
895
  try {
808
- contents = await external_fs_default().promises.readFile(absoluteFilePath, { encoding: 'utf-8' });
896
+ contents = await external_fs_default().promises.readFile(absoluteFilePath, {
897
+ encoding: 'utf-8',
898
+ });
809
899
  }
810
900
  catch (error) {
811
901
  throw new Error(`Failed to read template file: "${absoluteFilePath}". Was it removed mid-operation?`, { cause: error });
@@ -861,12 +951,14 @@ async function sanitizeTemplateAsync(projectRoot) {
861
951
  name: projectName,
862
952
  slug: projectName,
863
953
  };
864
- const appFile = new (JsonFile_default())(external_path_default().join(projectRoot, 'app.json'), { default: {} });
954
+ const appFile = new JsonFile["default"](external_path_default().join(projectRoot, 'app.json'), {
955
+ default: {},
956
+ });
865
957
  const appContent = (await appFile.readAsync());
866
958
  const appJson = deepMerge(appContent, 'expo' in appContent ? { expo: defaultConfig } : defaultConfig);
867
959
  await appFile.writeAsync(appJson);
868
960
  Template_debug(`Created app.json:\n%O`, appJson);
869
- const packageFile = new (JsonFile_default())(external_path_default().join(projectRoot, 'package.json'));
961
+ const packageFile = new JsonFile["default"](external_path_default().join(projectRoot, 'package.json'));
870
962
  const packageJson = await packageFile.readAsync();
871
963
  // name and version are required for yarn workspaces (monorepos)
872
964
  const inputName = 'name' in appJson ? appJson.name : appJson.expo.name;
@@ -1011,6 +1103,7 @@ function logNewSection(title) {
1011
1103
 
1012
1104
 
1013
1105
 
1106
+
1014
1107
  const Examples_debug = __webpack_require__(6675)('expo:init:template');
1015
1108
  /** List all existing examples directory from https://github.com/expo/examples. */
1016
1109
  async function listExamplesAsync() {
@@ -1066,7 +1159,14 @@ async function promptExamplesAsync() {
1066
1159
  }
1067
1160
  return answer;
1068
1161
  }
1069
- /** Download and move the selected example from https://github.com/expo/examples. */
1162
+ /**
1163
+ * Download and move the selected example from https://github.com/expo/examples.
1164
+ *
1165
+ * If the example ships a `.create-expo.json`, its `renamePatterns`
1166
+ * field overrides the default rename config used by the HelloWorld
1167
+ * find-and-replace pass. The config file is read once and deleted from disk
1168
+ * immediately so it can never leak into the user's project.
1169
+ */
1070
1170
  async function downloadAndExtractExampleAsync(root, name) {
1071
1171
  const projectName = external_path_default().basename(root);
1072
1172
  const response = await fetch_fetch('https://codeload.github.com/expo/examples/tar.gz/master');
@@ -1084,7 +1184,11 @@ async function downloadAndExtractExampleAsync(root, name) {
1084
1184
  strip: 2,
1085
1185
  filter: (entryName) => entryName.startsWith(prefix),
1086
1186
  });
1087
- const files = await getTemplateFilesToRenameAsync({ cwd: root });
1187
+ const monorepoConfig = await consumeMonorepoConfigAsync(root);
1188
+ const files = await getTemplateFilesToRenameAsync({
1189
+ cwd: root,
1190
+ renameConfig: monorepoConfig?.renamePatterns,
1191
+ });
1088
1192
  await renameTemplateAppNameAsync({
1089
1193
  cwd: root,
1090
1194
  files,
@@ -1110,61 +1214,235 @@ async function sanitizeScriptsAsync(root) {
1110
1214
  ios: 'expo start --ios',
1111
1215
  web: 'expo start --web',
1112
1216
  };
1113
- const packageFile = new (JsonFile_default())(external_path_default().join(root, 'package.json'));
1217
+ const packageFile = new JsonFile["default"](external_path_default().join(root, 'package.json'));
1114
1218
  const packageJson = await packageFile.readAsync();
1115
1219
  const scripts = (packageJson.scripts ?? {});
1116
1220
  packageJson.scripts = { ...defaultScripts, ...scripts };
1117
1221
  await packageFile.writeAsync(packageJson);
1118
1222
  }
1119
1223
 
1120
- ;// CONCATENATED MODULE: ./src/generateAgentFiles.ts
1224
+ // EXTERNAL MODULE: ../../node_modules/.pnpm/resolve-workspace-root@2.0.1/node_modules/resolve-workspace-root/build/index.js
1225
+ var resolve_workspace_root_build = __webpack_require__(8665);
1226
+ ;// CONCATENATED MODULE: ./src/configureWorkspaces.ts
1121
1227
 
1122
1228
 
1123
- function getExpoSdkVersion(root) {
1229
+
1230
+ const configureWorkspaces_debug = __webpack_require__(6675)('expo:init:workspaces');
1231
+ const PNPM_WORKSPACE_FILENAME = 'pnpm-workspace.yaml';
1232
+ const WORKSPACE_DEP_FIELDS = [
1233
+ 'dependencies',
1234
+ 'devDependencies',
1235
+ 'peerDependencies',
1236
+ 'optionalDependencies',
1237
+ ];
1238
+ /**
1239
+ * Normalize a monorepo template's workspace-package dependency specs to the
1240
+ * chosen package manager's convention, and — for pnpm — write a
1241
+ * `pnpm-workspace.yaml` listing the workspace packages so they're picked up
1242
+ * regardless of the root `package.json` `workspaces` field.
1243
+ */
1244
+ async function configureWorkspacesAsync(projectRoot, packageManager) {
1245
+ const workspacePatterns = (await (0,resolve_workspace_root_build.getWorkspaceGlobsAsync)(projectRoot)) ?? [];
1246
+ if (!workspacePatterns.length) {
1247
+ configureWorkspaces_debug(`No workspaces declared at ${projectRoot}; skipping workspace configuration`);
1248
+ return;
1249
+ }
1250
+ const memberPaths = await resolveWorkspaceMemberPathsAsync(projectRoot, workspacePatterns);
1251
+ configureWorkspaces_debug(`Found ${memberPaths.length} workspace member(s): ${memberPaths.join(', ')}`);
1252
+ const targetSpec = packageManager === 'npm' ? '*' : 'workspace:*';
1253
+ for (const memberPath of memberPaths) {
1254
+ await normalizeWorkspaceDepsAsync(memberPath, targetSpec);
1255
+ }
1256
+ if (packageManager === 'pnpm') {
1257
+ await ensurePnpmWorkspaceYamlAsync(projectRoot, workspacePatterns);
1258
+ }
1259
+ }
1260
+ async function resolveWorkspaceMemberPathsAsync(projectRoot, patterns) {
1261
+ const members = [];
1262
+ const seen = new Set();
1263
+ for (const pattern of patterns) {
1264
+ const expanded = await expandPatternAsync(projectRoot, pattern);
1265
+ for (const member of expanded) {
1266
+ if (!seen.has(member)) {
1267
+ seen.add(member);
1268
+ members.push(member);
1269
+ }
1270
+ }
1271
+ }
1272
+ return members;
1273
+ }
1274
+ async function expandPatternAsync(projectRoot, pattern) {
1275
+ const segments = pattern.split('/').filter((s) => s.length > 0);
1276
+ if (segments.length === 0) {
1277
+ return [];
1278
+ }
1279
+ // Literal path (no wildcards anywhere) — return it if its package.json exists.
1280
+ if (!segments.some((s) => s.includes('*'))) {
1281
+ const memberDir = external_path_default().resolve(projectRoot, ...segments);
1282
+ return (await packageJsonExistsAsync(memberDir)) ? [memberDir] : [];
1283
+ }
1284
+ // Single trailing wildcard segment — read the parent dir, keep children
1285
+ // whose package.json exists.
1286
+ if (segments[segments.length - 1] === '*' &&
1287
+ !segments.slice(0, -1).some((s) => s.includes('*'))) {
1288
+ const parentDir = external_path_default().resolve(projectRoot, ...segments.slice(0, -1));
1289
+ let entries;
1290
+ try {
1291
+ entries = await external_fs_default().promises.readdir(parentDir, { withFileTypes: true });
1292
+ }
1293
+ catch (error) {
1294
+ configureWorkspaces_debug(`Could not read workspace parent ${parentDir}: ${error?.message ?? error}`);
1295
+ return [];
1296
+ }
1297
+ const matches = [];
1298
+ for (const entry of entries) {
1299
+ if (!entry.isDirectory())
1300
+ continue;
1301
+ const memberDir = external_path_default().join(parentDir, entry.name);
1302
+ if (await packageJsonExistsAsync(memberDir)) {
1303
+ matches.push(memberDir);
1304
+ }
1305
+ }
1306
+ return matches;
1307
+ }
1308
+ configureWorkspaces_debug(`Unsupported workspace pattern "${pattern}" (only literal paths and trailing /* are handled)`);
1309
+ return [];
1310
+ }
1311
+ async function packageJsonExistsAsync(memberDir) {
1124
1312
  try {
1125
- const pkg = JSON.parse(external_fs_default().readFileSync(external_path_default().join(root, 'package.json'), 'utf-8'));
1126
- const expoVersion = (pkg.dependencies?.expo ?? pkg.devDependencies?.expo);
1127
- if (!expoVersion)
1128
- return null;
1129
- const match = expoVersion.match(/(\d+)\./);
1130
- return match?.[1] ?? null;
1313
+ const stat = await external_fs_default().promises.stat(external_path_default().join(memberDir, 'package.json'));
1314
+ return stat.isFile();
1131
1315
  }
1132
1316
  catch {
1133
- return null;
1317
+ return false;
1134
1318
  }
1135
1319
  }
1136
- function getAgentsMdContent(sdkVersion) {
1137
- const docsUrl = sdkVersion
1138
- ? `https://docs.expo.dev/versions/v${sdkVersion}.0.0/`
1139
- : 'https://docs.expo.dev';
1140
- return `# Expo HAS CHANGED
1320
+ async function normalizeWorkspaceDepsAsync(memberDir, targetSpec) {
1321
+ const pkgPath = external_path_default().join(memberDir, 'package.json');
1322
+ const pkg = await readJsonFileAsync(pkgPath);
1323
+ if (!pkg) {
1324
+ configureWorkspaces_debug(`Skipping ${pkgPath} (not readable)`);
1325
+ return;
1326
+ }
1327
+ let changed = false;
1328
+ for (const field of WORKSPACE_DEP_FIELDS) {
1329
+ const deps = pkg[field];
1330
+ if (!deps) {
1331
+ continue;
1332
+ }
1333
+ for (const [name, spec] of Object.entries(deps)) {
1334
+ if ((spec === 'workspace:*' || spec === '*') && spec !== targetSpec) {
1335
+ deps[name] = targetSpec;
1336
+ changed = true;
1337
+ }
1338
+ }
1339
+ }
1340
+ if (changed) {
1341
+ await external_fs_default().promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf-8');
1342
+ configureWorkspaces_debug(`Normalized workspace deps in ${pkgPath} → "${targetSpec}"`);
1343
+ }
1344
+ }
1345
+ async function readJsonFileAsync(filePath) {
1346
+ try {
1347
+ const contents = await external_fs_default().promises.readFile(filePath, 'utf-8');
1348
+ return JSON.parse(contents);
1349
+ }
1350
+ catch {
1351
+ return undefined;
1352
+ }
1353
+ }
1354
+ /**
1355
+ * Ensure `pnpm-workspace.yaml` contains a `packages:` block listing our
1356
+ * workspace patterns. If the file doesn't exist we write it from scratch. If
1357
+ * it does exist (e.g. the template ships its own with extra pnpm settings),
1358
+ * we preserve all existing content and only append `packages:`
1359
+ */
1360
+ async function ensurePnpmWorkspaceYamlAsync(projectRoot, patterns) {
1361
+ if (patterns.length === 0) {
1362
+ return;
1363
+ }
1364
+ const yamlPath = external_path_default().join(projectRoot, PNPM_WORKSPACE_FILENAME);
1365
+ let existing;
1366
+ try {
1367
+ existing = await external_fs_default().promises.readFile(yamlPath, 'utf-8');
1368
+ }
1369
+ catch (error) {
1370
+ if (error?.code !== 'ENOENT') {
1371
+ configureWorkspaces_debug(`Could not read existing ${yamlPath}: ${error?.message ?? error}`);
1372
+ }
1373
+ }
1374
+ const packagesBlock = [
1375
+ 'packages:',
1376
+ ...patterns.map((pattern) => ` - ${quoteIfNeeded(pattern)}`),
1377
+ ].join('\n');
1378
+ if (existing === undefined) {
1379
+ await external_fs_default().promises.writeFile(yamlPath, `${packagesBlock}\n`, 'utf-8');
1380
+ configureWorkspaces_debug(`Wrote ${yamlPath}`);
1381
+ return;
1382
+ }
1383
+ if (/^packages:/m.test(existing)) {
1384
+ configureWorkspaces_debug(`Existing ${yamlPath} already declares packages; leaving it alone`);
1385
+ return;
1386
+ }
1387
+ const needsLeadingNewline = existing.length > 0 && !existing.endsWith('\n');
1388
+ const updated = `${existing}${needsLeadingNewline ? '\n' : ''}${packagesBlock}\n`;
1389
+ await external_fs_default().promises.writeFile(yamlPath, updated, 'utf-8');
1390
+ configureWorkspaces_debug(`Appended packages: to existing ${yamlPath}`);
1391
+ }
1392
+ function quoteIfNeeded(value) {
1393
+ // Quote glob patterns that begin with `*`, `?`, `!`, or `&` so YAML doesn't
1394
+ // mis-parse them as tags or anchors.
1395
+ return /^[!*?&]/.test(value) ? `"${value}"` : value;
1396
+ }
1141
1397
 
1142
- Read the exact versioned docs at ${docsUrl} before writing any code.
1143
- `;
1398
+ ;// CONCATENATED MODULE: ./src/generateAgentFiles.ts
1399
+
1400
+
1401
+
1402
+ const AGENT_TEMPLATE_FILE_NAMES = (/* unused pure expression or super */ null && (['AGENTS.md', 'CLAUDE.md']));
1403
+ // Agent templates are synced from `expo/llm-configs` at publish time (see
1404
+ // `scripts/sync-agent-templates.js`) and bundled under `template/agent-files`, so project
1405
+ // creation works offline. `__dirname` is the build output directory, one level below the
1406
+ // package root in both the source tree and the published package.
1407
+ const AGENT_TEMPLATES_DIR = __webpack_require__.ab + "agent-files";
1408
+ function resolveAgentTemplatePath(fileName) {
1409
+ return __webpack_require__.ab + "agent-files/" + fileName;
1144
1410
  }
1145
- const CLAUDE_MD_CONTENT = `@AGENTS.md
1146
- `;
1147
1411
  const CLAUDE_SETTINGS_CONTENT = `{
1148
1412
  "enabledPlugins": {
1149
1413
  "expo@claude-plugins-official": true
1150
1414
  }
1151
1415
  }
1152
1416
  `;
1153
- function generateAgentFiles(root) {
1154
- const sdkVersion = getExpoSdkVersion(root);
1155
- const files = [
1156
- { filePath: external_path_default().join(root, 'AGENTS.md'), content: getAgentsMdContent(sdkVersion) },
1157
- { filePath: external_path_default().join(root, 'CLAUDE.md'), content: CLAUDE_MD_CONTENT },
1158
- { filePath: external_path_default().join(root, '.claude', 'settings.json'), content: CLAUDE_SETTINGS_CONTENT },
1417
+ function isClaudeCodeInstalled() {
1418
+ const home = external_os_default().homedir();
1419
+ return (!!home &&
1420
+ (external_fs_default().existsSync(external_path_default().join(home, '.claude.json')) || external_fs_default().existsSync(external_path_default().join(home, '.claude'))));
1421
+ }
1422
+ async function copyFileIfMissing(sourcePath, destinationPath) {
1423
+ if (external_fs_default().existsSync(destinationPath)) {
1424
+ return;
1425
+ }
1426
+ const dir = external_path_default().dirname(destinationPath);
1427
+ await external_fs_default().promises.mkdir(dir, { recursive: true });
1428
+ await external_fs_default().promises.copyFile(sourcePath, destinationPath);
1429
+ }
1430
+ async function writeFileIfMissing(filePath, content) {
1431
+ if (external_fs_default().existsSync(filePath)) {
1432
+ return;
1433
+ }
1434
+ const dir = external_path_default().dirname(filePath);
1435
+ await external_fs_default().promises.mkdir(dir, { recursive: true });
1436
+ await external_fs_default().promises.writeFile(filePath, content);
1437
+ }
1438
+ async function generateAgentFiles(root) {
1439
+ const tasks = [
1440
+ copyFileIfMissing(resolveAgentTemplatePath('AGENTS.md'), external_path_default().join(root, 'AGENTS.md')),
1159
1441
  ];
1160
- for (const { filePath, content } of files) {
1161
- if (external_fs_default().existsSync(filePath)) {
1162
- continue;
1163
- }
1164
- const dir = external_path_default().dirname(filePath);
1165
- external_fs_default().mkdirSync(dir, { recursive: true });
1166
- external_fs_default().writeFileSync(filePath, content);
1442
+ if (isClaudeCodeInstalled()) {
1443
+ tasks.push(copyFileIfMissing(resolveAgentTemplatePath('CLAUDE.md'), external_path_default().join(root, 'CLAUDE.md')), writeFileIfMissing(external_path_default().join(root, '.claude', 'settings.json'), CLAUDE_SETTINGS_CONTENT));
1167
1444
  }
1445
+ await Promise.all(tasks);
1168
1446
  }
1169
1447
 
1170
1448
  ;// CONCATENATED MODULE: ./src/promptSdkVersion.ts
@@ -1433,12 +1711,23 @@ async function resolveProjectRootAsync(input) {
1433
1711
 
1434
1712
  // EXTERNAL MODULE: ./src/telemetry.ts + 2 modules
1435
1713
  var telemetry = __webpack_require__(601);
1714
+ // EXTERNAL MODULE: ./src/utils/update-check.ts
1715
+ var update_check = __webpack_require__(7517);
1436
1716
  ;// CONCATENATED MODULE: ./src/utils/git.ts
1437
1717
 
1438
1718
 
1439
1719
 
1440
1720
 
1721
+
1441
1722
  const git_debug = __webpack_require__(6675)('expo:init:git');
1723
+ const getPackageJson = () => {
1724
+ try {
1725
+ return __webpack_require__(8330);
1726
+ }
1727
+ catch {
1728
+ return null;
1729
+ }
1730
+ };
1442
1731
  /** Check if the given directory is inside an existing git repository */
1443
1732
  async function isInsideGitRepoAsync(root) {
1444
1733
  try {
@@ -1487,12 +1776,12 @@ async function initGitRepoAsync(root) {
1487
1776
  // User explicitly chose not to skip, proceed with git init (creates nested repo)
1488
1777
  git_debug(source_default().dim('User chose to initialize git inside existing repo.'));
1489
1778
  }
1490
- const packageJSON = __webpack_require__(392);
1779
+ const packageJSON = getPackageJson();
1491
1780
  // not in git tree, so let's init
1492
1781
  try {
1493
1782
  await spawnAsync_default()('git', ['init'], { stdio: 'ignore', cwd: root });
1494
1783
  await spawnAsync_default()('git', ['add', '-A'], { stdio: 'ignore', cwd: root });
1495
- const commitMsg = `Initial commit\n\nGenerated by ${packageJSON.name} ${packageJSON.version}.`;
1784
+ const commitMsg = `Initial commit\n\nGenerated by ${packageJSON?.name ?? update_check.PACKAGE_NAME} ${packageJSON?.version ?? '0.0.0'}.`;
1496
1785
  await spawnAsync_default()('git', ['commit', '-m', commitMsg], {
1497
1786
  stdio: 'ignore',
1498
1787
  cwd: root,
@@ -1544,6 +1833,7 @@ function withSectionLog(action, message) {
1544
1833
 
1545
1834
 
1546
1835
 
1836
+
1547
1837
  const createAsync_debug = __webpack_require__(6675)('expo:init:create');
1548
1838
  async function resolveProjectRootArgAsync(inputPath, { yes }) {
1549
1839
  if (!inputPath && yes) {
@@ -1560,13 +1850,18 @@ async function resolveProjectRootArgAsync(inputPath, { yes }) {
1560
1850
  async function setupDependenciesAsync(projectRoot, props) {
1561
1851
  const shouldInstall = props.install;
1562
1852
  const packageManager = (0,resolvePackageManager/* resolvePackageManager */._c)();
1853
+ // For monorepo templates: normalize workspace-package dependency specs to
1854
+ // the chosen package manager's convention, and write a `pnpm-workspace.yaml`
1855
+ // when pnpm is the resolved manager. No-op for single-app templates.
1856
+ await configureWorkspacesAsync(projectRoot, packageManager);
1563
1857
  // Configure package manager, which is unrelated to installing or not
1564
1858
  await configureNodeDependenciesAsync(projectRoot, packageManager);
1565
1859
  // Install dependencies
1566
1860
  let podsInstalled = false;
1861
+ let nodeModulesInstalled = false;
1567
1862
  const needsPodsInstalled = await external_fs_default().existsSync(external_path_default().join(projectRoot, 'ios'));
1568
1863
  if (shouldInstall) {
1569
- await installNodeDependenciesAsync(projectRoot, packageManager);
1864
+ nodeModulesInstalled = await installNodeDependenciesAsync(projectRoot, packageManager);
1570
1865
  if (needsPodsInstalled) {
1571
1866
  podsInstalled = await installCocoaPodsAsync(projectRoot);
1572
1867
  }
@@ -1574,7 +1869,8 @@ async function setupDependenciesAsync(projectRoot, props) {
1574
1869
  const cdPath = getChangeDirectoryPath(projectRoot);
1575
1870
  console.log();
1576
1871
  logProjectReady({ cdPath, packageManager });
1577
- if (!shouldInstall) {
1872
+ // The install can also fail without stopping the command, so check the result and not the flag.
1873
+ if (!nodeModulesInstalled) {
1578
1874
  logNodeInstallWarning(cdPath, packageManager, needsPodsInstalled && !podsInstalled);
1579
1875
  }
1580
1876
  }
@@ -1612,14 +1908,18 @@ async function createTemplateAsync(inputPath, props) {
1612
1908
  event: telemetry.AnalyticsEventTypes.CREATE_EXPO_APP,
1613
1909
  properties: { phase: telemetry.AnalyticsEventPhases.ATTEMPT, template: resolvedTemplate },
1614
1910
  });
1615
- await withSectionLog(() => extractAndPrepareTemplateAppAsync(projectRoot, { npmPackage: resolvedTemplate }), {
1911
+ await withSectionLog(async () => {
1912
+ await extractAndPrepareTemplateAppAsync(projectRoot, {
1913
+ npmPackage: resolvedTemplate,
1914
+ });
1915
+ }, {
1616
1916
  pending: source_default().bold('Locating project files.'),
1617
1917
  success: 'Downloaded and extracted project files.',
1618
1918
  error: (error) => `Something went wrong in downloading and extracting the project files: ${error.message}`,
1619
1919
  });
1620
1920
  await setupDependenciesAsync(projectRoot, props);
1621
1921
  if (props.agentsMd) {
1622
- generateAgentFiles(projectRoot);
1922
+ await generateAgentFiles(projectRoot);
1623
1923
  }
1624
1924
  // for now, we will just init a git repo if they have git installed and the
1625
1925
  // project is not inside an existing git tree, and do it silently. we should
@@ -1686,14 +1986,16 @@ async function createExampleAsync(inputPath, props) {
1686
1986
  event: telemetry.AnalyticsEventTypes.CREATE_EXPO_APP,
1687
1987
  properties: { phase: telemetry.AnalyticsEventPhases.ATTEMPT, example: resolvedExample },
1688
1988
  });
1689
- await withSectionLog(() => downloadAndExtractExampleAsync(projectRoot, resolvedExample), {
1989
+ await withSectionLog(async () => {
1990
+ await downloadAndExtractExampleAsync(projectRoot, resolvedExample);
1991
+ }, {
1690
1992
  pending: source_default().bold('Locating example files...'),
1691
1993
  success: 'Downloaded and extracted example files.',
1692
1994
  error: (error) => `Something went wrong in downloading and extracting the example files: ${error.message}`,
1693
1995
  });
1694
1996
  await setupDependenciesAsync(projectRoot, props);
1695
1997
  if (props.agentsMd) {
1696
- generateAgentFiles(projectRoot);
1998
+ await generateAgentFiles(projectRoot);
1697
1999
  }
1698
2000
  // for now, we will just init a git repo if they have git installed and the
1699
2001
  // project is not inside an existing git tree, and do it silently. we should
@@ -1726,14 +2028,17 @@ async function configureNodeDependenciesAsync(projectRoot, packageManager) {
1726
2028
  log/* Log */.tG.exception(error);
1727
2029
  }
1728
2030
  }
2031
+ /** Install the node modules. Returns `false` when the package manager failed. */
1729
2032
  async function installNodeDependenciesAsync(projectRoot, packageManager) {
1730
2033
  try {
1731
2034
  await (0,resolvePackageManager/* installDependenciesAsync */.DC)(projectRoot, packageManager, { silent: false });
2035
+ return true;
1732
2036
  }
1733
2037
  catch (error) {
1734
2038
  createAsync_debug(`Error installing node modules: %O`, error);
1735
2039
  log/* Log */.tG.error(`Something went wrong installing JavaScript dependencies. Check your ${packageManager} logs. Continuing to create the app.`);
1736
2040
  log/* Log */.tG.exception(error);
2041
+ return false;
1737
2042
  }
1738
2043
  }
1739
2044
  async function installCocoaPodsAsync(projectRoot) {
@@ -1788,7 +2093,6 @@ __webpack_require__.d(__webpack_exports__, {
1788
2093
 
1789
2094
  // EXTERNAL MODULE: ../@expo/json-file/build/JsonFile.js
1790
2095
  var JsonFile = __webpack_require__(3064);
1791
- var JsonFile_default = /*#__PURE__*/__webpack_require__.n(JsonFile);
1792
2096
  // EXTERNAL MODULE: external "crypto"
1793
2097
  var external_crypto_ = __webpack_require__(6982);
1794
2098
  var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto_);
@@ -1830,7 +2134,7 @@ const getStateJsonPath = () => external_path_default().join(dotExpoHomeDirectory
1830
2134
 
1831
2135
  function getSession() {
1832
2136
  try {
1833
- return JsonFile_default().read(getStateJsonPath())?.auth ?? null;
2137
+ return JsonFile["default"].read(getStateJsonPath())?.auth ?? null;
1834
2138
  }
1835
2139
  catch (error) {
1836
2140
  if (error.code === 'ENOENT') {
@@ -1842,6 +2146,8 @@ function getSession() {
1842
2146
 
1843
2147
  // EXTERNAL MODULE: ./src/utils/env.ts
1844
2148
  var utils_env = __webpack_require__(4342);
2149
+ // EXTERNAL MODULE: ./src/utils/update-check.ts
2150
+ var update_check = __webpack_require__(7517);
1845
2151
  ;// CONCATENATED MODULE: ./src/telemetry.ts
1846
2152
 
1847
2153
 
@@ -1850,11 +2156,19 @@ var utils_env = __webpack_require__(4342);
1850
2156
 
1851
2157
 
1852
2158
 
1853
- const packageJSON = __webpack_require__(8330);
2159
+
2160
+ const getPackageJson = () => {
2161
+ try {
2162
+ return __webpack_require__(8330);
2163
+ }
2164
+ catch {
2165
+ return null;
2166
+ }
2167
+ };
1854
2168
  const xdlUnifiedWriteKey = '1wabJGd5IiuF9Q8SGlcI90v8WTs';
1855
2169
  const analyticsEndpoint = 'https://cdp.expo.dev/v1/batch';
1856
2170
  const version = '1.0.0';
1857
- const library = packageJSON.name;
2171
+ const library = update_check.PACKAGE_NAME;
1858
2172
  const messageBatch = [];
1859
2173
  let analyticsIdentity = null;
1860
2174
  // jest does not clear global variables inbetween tests so we need this helper
@@ -1911,7 +2225,7 @@ function enqueue(type, message) {
1911
2225
  message.originalTimestamp = new Date();
1912
2226
  }
1913
2227
  if (!message.messageId) {
1914
- // We md5 the messaage to add more randomness. This is primarily meant
2228
+ // We md5 the message to add more randomness. This is primarily meant
1915
2229
  // for use in the browser where the uuid package falls back to Math.random()
1916
2230
  // which is not a great source of randomness.
1917
2231
  // Borrowed from analytics.js (https://github.com/segment-integrations/analytics.js-integration-segmentio/blob/a20d2a2d222aeb3ab2a8c7e72280f1df2618440e/lib/index.js#L255-L256).
@@ -1921,7 +2235,7 @@ function enqueue(type, message) {
1921
2235
  }
1922
2236
  messageBatch.push(message);
1923
2237
  }
1924
- // very barebones implemention...
2238
+ // very barebones implementation...
1925
2239
  // does not support multiple concurrent flushes or large numbers of messages
1926
2240
  async function flushAsync() {
1927
2241
  if (utils_env.env.EXPO_NO_TELEMETRY)
@@ -1947,7 +2261,7 @@ async function flushAsync() {
1947
2261
  await fetch(analyticsEndpoint, request);
1948
2262
  }
1949
2263
  catch {
1950
- // supress errors - likely due to network connectivity or endpoint health
2264
+ // suppress errors - likely due to network connectivity or endpoint health
1951
2265
  }
1952
2266
  // clear array so we don't resend events in subsequent flushes
1953
2267
  messageBatch.splice(0, messageBatch.length);
@@ -1964,7 +2278,7 @@ function getAnalyticsContext() {
1964
2278
  return {
1965
2279
  os: { name: platform, version: external_os_default().release() },
1966
2280
  device: { type: platform, model: platform },
1967
- app: { name: library, version: packageJSON.version },
2281
+ app: { name: library, version: getPackageJson()?.version ?? undefined },
1968
2282
  };
1969
2283
  }
1970
2284
  //#endregion
@@ -1975,7 +2289,7 @@ function uuidv4() {
1975
2289
  return external_crypto_default().randomUUID();
1976
2290
  }
1977
2291
  catch {
1978
- // supress errors due to node 13 or less not having randomUUID
2292
+ // suppress errors due to node 13 or less not having randomUUID
1979
2293
  return null;
1980
2294
  }
1981
2295
  }
@@ -1996,14 +2310,14 @@ async function getAnalyticsIdentityAsync() {
1996
2310
  if (!external_fs_default().existsSync(getStateJsonPath())) {
1997
2311
  external_fs_default().writeFileSync(getStateJsonPath(), JSON.stringify({}));
1998
2312
  }
1999
- const savedDeviceId = await JsonFile_default().getAsync(getStateJsonPath(), 'analyticsDeviceId', null);
2313
+ const savedDeviceId = await JsonFile["default"].getAsync(getStateJsonPath(), 'analyticsDeviceId', null);
2000
2314
  const deviceId = savedDeviceId ?? uuidv4();
2001
2315
  if (!deviceId) {
2002
2316
  // unable to generate an id or load one from disk
2003
2317
  return null;
2004
2318
  }
2005
2319
  if (!savedDeviceId) {
2006
- await JsonFile_default().setAsync(getStateJsonPath(), 'analyticsDeviceId', deviceId);
2320
+ await JsonFile["default"].setAsync(getStateJsonPath(), 'analyticsDeviceId', deviceId);
2007
2321
  }
2008
2322
  const userId = getSession()?.userId ?? null;
2009
2323
  return userId ? { anonymousId: deviceId, userId } : { anonymousId: deviceId };