create-expo 5.0.2 → 5.1.1
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/{205.index.js → 589.index.js} +392 -91
- package/build/601.index.js +20 -11
- package/build/{223.index.js → 870.index.js} +2 -10
- package/build/Examples.d.ts +38 -0
- package/build/Template.d.ts +98 -0
- package/build/__mocks__/fs.d.ts +1 -0
- package/build/__mocks__/ora.d.ts +1 -0
- package/build/__tests__/Examples.test.d.ts +1 -0
- package/build/__tests__/Template.test.d.ts +1 -0
- package/build/__tests__/configureWorkspaces.test.d.ts +1 -0
- package/build/__tests__/createAsync.test.d.ts +1 -0
- package/build/__tests__/createExpoConfig.test.d.ts +1 -0
- package/build/__tests__/createFileTransformer.test.d.ts +1 -0
- package/build/__tests__/generateAgentFiles.test.d.ts +1 -0
- package/build/__tests__/promptSdkVersion.test.d.ts +1 -0
- package/build/__tests__/resolvePackageManager.test.d.ts +1 -0
- package/build/__tests__/sanitizeTemplate.test.d.ts +1 -0
- package/build/__tests__/telemetry.test.d.ts +1 -0
- package/build/cli.d.ts +1 -0
- package/build/configureWorkspaces.d.ts +9 -0
- package/build/createAsync.d.ts +11 -0
- package/build/createExpoConfig.d.ts +38 -0
- package/build/createFileTransform.d.ts +5 -0
- package/build/error.d.ts +9 -0
- package/build/generateAgentFiles.d.ts +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +38 -10
- package/build/legacyTemplates.d.ts +7 -0
- package/build/log.d.ts +12 -0
- package/build/paths.d.ts +2 -0
- package/build/promptSdkVersion.d.ts +23 -0
- package/build/resolvePackageManager.d.ts +12 -0
- package/build/resolveProjectRoot.d.ts +3 -0
- package/build/sessionStorage.d.ts +8 -0
- package/build/telemetry.d.ts +29 -0
- package/build/utils/__tests__/args.test.d.ts +1 -0
- package/build/utils/__tests__/array.test.d.ts +1 -0
- package/build/utils/__tests__/log.test.d.ts +1 -0
- package/build/utils/__tests__/npm.test.d.ts +1 -0
- package/build/utils/__tests__/obj.test.d.ts +1 -0
- package/build/utils/args.d.ts +33 -0
- package/build/utils/array.d.ts +1 -0
- package/build/utils/dir.d.ts +1 -0
- package/build/utils/env.d.ts +14 -0
- package/build/utils/fetch.d.ts +2 -0
- package/build/utils/git.d.ts +1 -0
- package/build/utils/github.d.ts +2 -0
- package/build/utils/log.d.ts +6 -0
- package/build/utils/npm.d.ts +52 -0
- package/build/utils/obj.d.ts +1 -0
- package/build/utils/tar.d.ts +10 -0
- package/build/utils/update-check.d.ts +2 -0
- package/package.json +31 -21
- package/build/517.index.js +0 -1380
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
exports.id =
|
|
3
|
-
exports.ids = [
|
|
2
|
+
exports.id = 589;
|
|
3
|
+
exports.ids = [589,601];
|
|
4
4
|
exports.modules = {
|
|
5
5
|
|
|
6
|
-
/***/
|
|
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,6 +35,67 @@ 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);
|
|
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
|
+
|
|
39
99
|
// EXTERNAL MODULE: ../../node_modules/.pnpm/multitars@1.0.2/node_modules/multitars/dist/multitars.mjs
|
|
40
100
|
var multitars = __webpack_require__(6378);
|
|
41
101
|
// EXTERNAL MODULE: ../../node_modules/.pnpm/picomatch@2.3.2/node_modules/picomatch/index.js
|
|
@@ -45,7 +105,7 @@ var picomatch_default = /*#__PURE__*/__webpack_require__.n(picomatch);
|
|
|
45
105
|
|
|
46
106
|
|
|
47
107
|
|
|
48
|
-
const
|
|
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
|
-
|
|
150
|
+
createFileTransform_debug('filter: created for pattern %s (%s)', globPattern);
|
|
91
151
|
return (path) => {
|
|
92
152
|
const included = matcher(path);
|
|
93
|
-
|
|
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
|
|
|
@@ -520,6 +578,7 @@ async function downloadAndExtractNpmModuleAsync(npmName, output, props) {
|
|
|
520
578
|
|
|
521
579
|
|
|
522
580
|
|
|
581
|
+
|
|
523
582
|
const github_debug = __webpack_require__(6675)('expo:init:github');
|
|
524
583
|
// See: https://github.com/expo/expo/blob/a5a6eecb082b2c7a7fc9956141738231c7df473f/packages/%40expo/cli/src/prebuild/resolveTemplate.ts#L60-L84
|
|
525
584
|
async function getGitHubRepoAsync(url) {
|
|
@@ -565,9 +624,15 @@ async function extractRemoteGitHubTarballAsync(url, repo, output, props) {
|
|
|
565
624
|
const strip = directory.length + 1;
|
|
566
625
|
// Only extract the relevant (sub)directories, ignoring irrelevant files
|
|
567
626
|
// The filter auto-ignores dotfiles, unless explicitly included
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
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
|
+
], {
|
|
571
636
|
// Always ignore the `.xcworkspace` folder
|
|
572
637
|
ignore: ['**/ios/*.xcworkspace/**'],
|
|
573
638
|
});
|
|
@@ -582,7 +647,7 @@ async function downloadAndExtractGitHubRepositoryAsync(repoUrl, output, props) {
|
|
|
582
647
|
const info = await getGitHubRepoAsync(repoUrl);
|
|
583
648
|
const isValid = await isValidGitHubRepoAsync(info);
|
|
584
649
|
if (!isValid) {
|
|
585
|
-
throw new Error(`Could not
|
|
650
|
+
throw new Error(`Could not locate repository for "${repoUrl}", ensure this repository exists`);
|
|
586
651
|
}
|
|
587
652
|
const url = `https://codeload.github.com/${info.owner}/${info.name}/tar.gz/${info.branch}`;
|
|
588
653
|
github_debug('Resolved GitHub repository', info);
|
|
@@ -604,6 +669,7 @@ async function downloadAndExtractGitHubRepositoryAsync(repoUrl, output, props) {
|
|
|
604
669
|
|
|
605
670
|
|
|
606
671
|
|
|
672
|
+
|
|
607
673
|
const Template_debug = __webpack_require__(6675)('expo:init:template');
|
|
608
674
|
const isMacOS = process.platform === 'darwin';
|
|
609
675
|
// keep this list in sync with the validation helper in WWW: src/utils/experienceParser.ts
|
|
@@ -688,6 +754,11 @@ function resolvePackageModuleId(moduleId) {
|
|
|
688
754
|
/**
|
|
689
755
|
* Extract a template app to a given file path and clean up any properties left over from npm to
|
|
690
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.
|
|
691
762
|
*/
|
|
692
763
|
async function extractAndPrepareTemplateAppAsync(projectRoot, { npmPackage }) {
|
|
693
764
|
const projectName = external_path_default().basename(projectRoot);
|
|
@@ -705,8 +776,12 @@ async function extractAndPrepareTemplateAppAsync(projectRoot, { npmPackage }) {
|
|
|
705
776
|
disableCache: type === 'file',
|
|
706
777
|
});
|
|
707
778
|
}
|
|
779
|
+
const monorepoConfig = await consumeMonorepoConfigAsync(projectRoot);
|
|
708
780
|
try {
|
|
709
|
-
const files = await getTemplateFilesToRenameAsync({
|
|
781
|
+
const files = await getTemplateFilesToRenameAsync({
|
|
782
|
+
cwd: projectRoot,
|
|
783
|
+
renameConfig: monorepoConfig?.renamePatterns,
|
|
784
|
+
});
|
|
710
785
|
await renameTemplateAppNameAsync({
|
|
711
786
|
cwd: projectRoot,
|
|
712
787
|
files,
|
|
@@ -758,8 +833,8 @@ function escapeXMLCharacters(original) {
|
|
|
758
833
|
* Whitespace is trimmed and whitespace-only lines are ignored.
|
|
759
834
|
*
|
|
760
835
|
* If no rename config has been passed directly to
|
|
761
|
-
* `getTemplateFilesToRenameAsync()
|
|
762
|
-
* used instead.
|
|
836
|
+
* `getTemplateFilesToRenameAsync()`, then this default
|
|
837
|
+
* rename config will be used instead.
|
|
763
838
|
*/
|
|
764
839
|
const defaultRenameConfig = [
|
|
765
840
|
// Common
|
|
@@ -818,7 +893,9 @@ async function renameTemplateAppNameAsync({ cwd, name, files, }) {
|
|
|
818
893
|
const absoluteFilePath = external_path_default().resolve(cwd, file);
|
|
819
894
|
let contents;
|
|
820
895
|
try {
|
|
821
|
-
contents = await external_fs_default().promises.readFile(absoluteFilePath, {
|
|
896
|
+
contents = await external_fs_default().promises.readFile(absoluteFilePath, {
|
|
897
|
+
encoding: 'utf-8',
|
|
898
|
+
});
|
|
822
899
|
}
|
|
823
900
|
catch (error) {
|
|
824
901
|
throw new Error(`Failed to read template file: "${absoluteFilePath}". Was it removed mid-operation?`, { cause: error });
|
|
@@ -874,12 +951,14 @@ async function sanitizeTemplateAsync(projectRoot) {
|
|
|
874
951
|
name: projectName,
|
|
875
952
|
slug: projectName,
|
|
876
953
|
};
|
|
877
|
-
const appFile = new (
|
|
954
|
+
const appFile = new JsonFile["default"](external_path_default().join(projectRoot, 'app.json'), {
|
|
955
|
+
default: {},
|
|
956
|
+
});
|
|
878
957
|
const appContent = (await appFile.readAsync());
|
|
879
958
|
const appJson = deepMerge(appContent, 'expo' in appContent ? { expo: defaultConfig } : defaultConfig);
|
|
880
959
|
await appFile.writeAsync(appJson);
|
|
881
960
|
Template_debug(`Created app.json:\n%O`, appJson);
|
|
882
|
-
const packageFile = new (
|
|
961
|
+
const packageFile = new JsonFile["default"](external_path_default().join(projectRoot, 'package.json'));
|
|
883
962
|
const packageJson = await packageFile.readAsync();
|
|
884
963
|
// name and version are required for yarn workspaces (monorepos)
|
|
885
964
|
const inputName = 'name' in appJson ? appJson.name : appJson.expo.name;
|
|
@@ -1024,6 +1103,7 @@ function logNewSection(title) {
|
|
|
1024
1103
|
|
|
1025
1104
|
|
|
1026
1105
|
|
|
1106
|
+
|
|
1027
1107
|
const Examples_debug = __webpack_require__(6675)('expo:init:template');
|
|
1028
1108
|
/** List all existing examples directory from https://github.com/expo/examples. */
|
|
1029
1109
|
async function listExamplesAsync() {
|
|
@@ -1079,7 +1159,14 @@ async function promptExamplesAsync() {
|
|
|
1079
1159
|
}
|
|
1080
1160
|
return answer;
|
|
1081
1161
|
}
|
|
1082
|
-
/**
|
|
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
|
+
*/
|
|
1083
1170
|
async function downloadAndExtractExampleAsync(root, name) {
|
|
1084
1171
|
const projectName = external_path_default().basename(root);
|
|
1085
1172
|
const response = await fetch_fetch('https://codeload.github.com/expo/examples/tar.gz/master');
|
|
@@ -1097,7 +1184,11 @@ async function downloadAndExtractExampleAsync(root, name) {
|
|
|
1097
1184
|
strip: 2,
|
|
1098
1185
|
filter: (entryName) => entryName.startsWith(prefix),
|
|
1099
1186
|
});
|
|
1100
|
-
const
|
|
1187
|
+
const monorepoConfig = await consumeMonorepoConfigAsync(root);
|
|
1188
|
+
const files = await getTemplateFilesToRenameAsync({
|
|
1189
|
+
cwd: root,
|
|
1190
|
+
renameConfig: monorepoConfig?.renamePatterns,
|
|
1191
|
+
});
|
|
1101
1192
|
await renameTemplateAppNameAsync({
|
|
1102
1193
|
cwd: root,
|
|
1103
1194
|
files,
|
|
@@ -1123,13 +1214,187 @@ async function sanitizeScriptsAsync(root) {
|
|
|
1123
1214
|
ios: 'expo start --ios',
|
|
1124
1215
|
web: 'expo start --web',
|
|
1125
1216
|
};
|
|
1126
|
-
const packageFile = new (
|
|
1217
|
+
const packageFile = new JsonFile["default"](external_path_default().join(root, 'package.json'));
|
|
1127
1218
|
const packageJson = await packageFile.readAsync();
|
|
1128
1219
|
const scripts = (packageJson.scripts ?? {});
|
|
1129
1220
|
packageJson.scripts = { ...defaultScripts, ...scripts };
|
|
1130
1221
|
await packageFile.writeAsync(packageJson);
|
|
1131
1222
|
}
|
|
1132
1223
|
|
|
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
|
|
1227
|
+
|
|
1228
|
+
|
|
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) {
|
|
1312
|
+
try {
|
|
1313
|
+
const stat = await external_fs_default().promises.stat(external_path_default().join(memberDir, 'package.json'));
|
|
1314
|
+
return stat.isFile();
|
|
1315
|
+
}
|
|
1316
|
+
catch {
|
|
1317
|
+
return false;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
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
|
+
}
|
|
1397
|
+
|
|
1133
1398
|
;// CONCATENATED MODULE: ./src/generateAgentFiles.ts
|
|
1134
1399
|
|
|
1135
1400
|
|
|
@@ -1446,12 +1711,23 @@ async function resolveProjectRootAsync(input) {
|
|
|
1446
1711
|
|
|
1447
1712
|
// EXTERNAL MODULE: ./src/telemetry.ts + 2 modules
|
|
1448
1713
|
var telemetry = __webpack_require__(601);
|
|
1714
|
+
// EXTERNAL MODULE: ./src/utils/update-check.ts
|
|
1715
|
+
var update_check = __webpack_require__(7517);
|
|
1449
1716
|
;// CONCATENATED MODULE: ./src/utils/git.ts
|
|
1450
1717
|
|
|
1451
1718
|
|
|
1452
1719
|
|
|
1453
1720
|
|
|
1721
|
+
|
|
1454
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
|
+
};
|
|
1455
1731
|
/** Check if the given directory is inside an existing git repository */
|
|
1456
1732
|
async function isInsideGitRepoAsync(root) {
|
|
1457
1733
|
try {
|
|
@@ -1500,12 +1776,12 @@ async function initGitRepoAsync(root) {
|
|
|
1500
1776
|
// User explicitly chose not to skip, proceed with git init (creates nested repo)
|
|
1501
1777
|
git_debug(source_default().dim('User chose to initialize git inside existing repo.'));
|
|
1502
1778
|
}
|
|
1503
|
-
const packageJSON =
|
|
1779
|
+
const packageJSON = getPackageJson();
|
|
1504
1780
|
// not in git tree, so let's init
|
|
1505
1781
|
try {
|
|
1506
1782
|
await spawnAsync_default()('git', ['init'], { stdio: 'ignore', cwd: root });
|
|
1507
1783
|
await spawnAsync_default()('git', ['add', '-A'], { stdio: 'ignore', cwd: root });
|
|
1508
|
-
const commitMsg = `Initial commit\n\nGenerated by ${packageJSON.
|
|
1784
|
+
const commitMsg = `Initial commit\n\nGenerated by ${packageJSON?.name ?? update_check.PACKAGE_NAME} ${packageJSON?.version ?? '0.0.0'}.`;
|
|
1509
1785
|
await spawnAsync_default()('git', ['commit', '-m', commitMsg], {
|
|
1510
1786
|
stdio: 'ignore',
|
|
1511
1787
|
cwd: root,
|
|
@@ -1557,6 +1833,7 @@ function withSectionLog(action, message) {
|
|
|
1557
1833
|
|
|
1558
1834
|
|
|
1559
1835
|
|
|
1836
|
+
|
|
1560
1837
|
const createAsync_debug = __webpack_require__(6675)('expo:init:create');
|
|
1561
1838
|
async function resolveProjectRootArgAsync(inputPath, { yes }) {
|
|
1562
1839
|
if (!inputPath && yes) {
|
|
@@ -1573,13 +1850,18 @@ async function resolveProjectRootArgAsync(inputPath, { yes }) {
|
|
|
1573
1850
|
async function setupDependenciesAsync(projectRoot, props) {
|
|
1574
1851
|
const shouldInstall = props.install;
|
|
1575
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);
|
|
1576
1857
|
// Configure package manager, which is unrelated to installing or not
|
|
1577
1858
|
await configureNodeDependenciesAsync(projectRoot, packageManager);
|
|
1578
1859
|
// Install dependencies
|
|
1579
1860
|
let podsInstalled = false;
|
|
1861
|
+
let nodeModulesInstalled = false;
|
|
1580
1862
|
const needsPodsInstalled = await external_fs_default().existsSync(external_path_default().join(projectRoot, 'ios'));
|
|
1581
1863
|
if (shouldInstall) {
|
|
1582
|
-
await installNodeDependenciesAsync(projectRoot, packageManager);
|
|
1864
|
+
nodeModulesInstalled = await installNodeDependenciesAsync(projectRoot, packageManager);
|
|
1583
1865
|
if (needsPodsInstalled) {
|
|
1584
1866
|
podsInstalled = await installCocoaPodsAsync(projectRoot);
|
|
1585
1867
|
}
|
|
@@ -1587,7 +1869,8 @@ async function setupDependenciesAsync(projectRoot, props) {
|
|
|
1587
1869
|
const cdPath = getChangeDirectoryPath(projectRoot);
|
|
1588
1870
|
console.log();
|
|
1589
1871
|
logProjectReady({ cdPath, packageManager });
|
|
1590
|
-
|
|
1872
|
+
// The install can also fail without stopping the command, so check the result and not the flag.
|
|
1873
|
+
if (!nodeModulesInstalled) {
|
|
1591
1874
|
logNodeInstallWarning(cdPath, packageManager, needsPodsInstalled && !podsInstalled);
|
|
1592
1875
|
}
|
|
1593
1876
|
}
|
|
@@ -1625,7 +1908,11 @@ async function createTemplateAsync(inputPath, props) {
|
|
|
1625
1908
|
event: telemetry.AnalyticsEventTypes.CREATE_EXPO_APP,
|
|
1626
1909
|
properties: { phase: telemetry.AnalyticsEventPhases.ATTEMPT, template: resolvedTemplate },
|
|
1627
1910
|
});
|
|
1628
|
-
await withSectionLog(() =>
|
|
1911
|
+
await withSectionLog(async () => {
|
|
1912
|
+
await extractAndPrepareTemplateAppAsync(projectRoot, {
|
|
1913
|
+
npmPackage: resolvedTemplate,
|
|
1914
|
+
});
|
|
1915
|
+
}, {
|
|
1629
1916
|
pending: source_default().bold('Locating project files.'),
|
|
1630
1917
|
success: 'Downloaded and extracted project files.',
|
|
1631
1918
|
error: (error) => `Something went wrong in downloading and extracting the project files: ${error.message}`,
|
|
@@ -1699,7 +1986,9 @@ async function createExampleAsync(inputPath, props) {
|
|
|
1699
1986
|
event: telemetry.AnalyticsEventTypes.CREATE_EXPO_APP,
|
|
1700
1987
|
properties: { phase: telemetry.AnalyticsEventPhases.ATTEMPT, example: resolvedExample },
|
|
1701
1988
|
});
|
|
1702
|
-
await withSectionLog(() =>
|
|
1989
|
+
await withSectionLog(async () => {
|
|
1990
|
+
await downloadAndExtractExampleAsync(projectRoot, resolvedExample);
|
|
1991
|
+
}, {
|
|
1703
1992
|
pending: source_default().bold('Locating example files...'),
|
|
1704
1993
|
success: 'Downloaded and extracted example files.',
|
|
1705
1994
|
error: (error) => `Something went wrong in downloading and extracting the example files: ${error.message}`,
|
|
@@ -1739,14 +2028,17 @@ async function configureNodeDependenciesAsync(projectRoot, packageManager) {
|
|
|
1739
2028
|
log/* Log */.tG.exception(error);
|
|
1740
2029
|
}
|
|
1741
2030
|
}
|
|
2031
|
+
/** Install the node modules. Returns `false` when the package manager failed. */
|
|
1742
2032
|
async function installNodeDependenciesAsync(projectRoot, packageManager) {
|
|
1743
2033
|
try {
|
|
1744
2034
|
await (0,resolvePackageManager/* installDependenciesAsync */.DC)(projectRoot, packageManager, { silent: false });
|
|
2035
|
+
return true;
|
|
1745
2036
|
}
|
|
1746
2037
|
catch (error) {
|
|
1747
2038
|
createAsync_debug(`Error installing node modules: %O`, error);
|
|
1748
2039
|
log/* Log */.tG.error(`Something went wrong installing JavaScript dependencies. Check your ${packageManager} logs. Continuing to create the app.`);
|
|
1749
2040
|
log/* Log */.tG.exception(error);
|
|
2041
|
+
return false;
|
|
1750
2042
|
}
|
|
1751
2043
|
}
|
|
1752
2044
|
async function installCocoaPodsAsync(projectRoot) {
|
|
@@ -1801,7 +2093,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
1801
2093
|
|
|
1802
2094
|
// EXTERNAL MODULE: ../@expo/json-file/build/JsonFile.js
|
|
1803
2095
|
var JsonFile = __webpack_require__(3064);
|
|
1804
|
-
var JsonFile_default = /*#__PURE__*/__webpack_require__.n(JsonFile);
|
|
1805
2096
|
// EXTERNAL MODULE: external "crypto"
|
|
1806
2097
|
var external_crypto_ = __webpack_require__(6982);
|
|
1807
2098
|
var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto_);
|
|
@@ -1843,7 +2134,7 @@ const getStateJsonPath = () => external_path_default().join(dotExpoHomeDirectory
|
|
|
1843
2134
|
|
|
1844
2135
|
function getSession() {
|
|
1845
2136
|
try {
|
|
1846
|
-
return
|
|
2137
|
+
return JsonFile["default"].read(getStateJsonPath())?.auth ?? null;
|
|
1847
2138
|
}
|
|
1848
2139
|
catch (error) {
|
|
1849
2140
|
if (error.code === 'ENOENT') {
|
|
@@ -1855,6 +2146,8 @@ function getSession() {
|
|
|
1855
2146
|
|
|
1856
2147
|
// EXTERNAL MODULE: ./src/utils/env.ts
|
|
1857
2148
|
var utils_env = __webpack_require__(4342);
|
|
2149
|
+
// EXTERNAL MODULE: ./src/utils/update-check.ts
|
|
2150
|
+
var update_check = __webpack_require__(7517);
|
|
1858
2151
|
;// CONCATENATED MODULE: ./src/telemetry.ts
|
|
1859
2152
|
|
|
1860
2153
|
|
|
@@ -1863,11 +2156,19 @@ var utils_env = __webpack_require__(4342);
|
|
|
1863
2156
|
|
|
1864
2157
|
|
|
1865
2158
|
|
|
1866
|
-
|
|
2159
|
+
|
|
2160
|
+
const getPackageJson = () => {
|
|
2161
|
+
try {
|
|
2162
|
+
return __webpack_require__(8330);
|
|
2163
|
+
}
|
|
2164
|
+
catch {
|
|
2165
|
+
return null;
|
|
2166
|
+
}
|
|
2167
|
+
};
|
|
1867
2168
|
const xdlUnifiedWriteKey = '1wabJGd5IiuF9Q8SGlcI90v8WTs';
|
|
1868
2169
|
const analyticsEndpoint = 'https://cdp.expo.dev/v1/batch';
|
|
1869
2170
|
const version = '1.0.0';
|
|
1870
|
-
const library =
|
|
2171
|
+
const library = update_check.PACKAGE_NAME;
|
|
1871
2172
|
const messageBatch = [];
|
|
1872
2173
|
let analyticsIdentity = null;
|
|
1873
2174
|
// jest does not clear global variables inbetween tests so we need this helper
|
|
@@ -1924,7 +2225,7 @@ function enqueue(type, message) {
|
|
|
1924
2225
|
message.originalTimestamp = new Date();
|
|
1925
2226
|
}
|
|
1926
2227
|
if (!message.messageId) {
|
|
1927
|
-
// We md5 the
|
|
2228
|
+
// We md5 the message to add more randomness. This is primarily meant
|
|
1928
2229
|
// for use in the browser where the uuid package falls back to Math.random()
|
|
1929
2230
|
// which is not a great source of randomness.
|
|
1930
2231
|
// Borrowed from analytics.js (https://github.com/segment-integrations/analytics.js-integration-segmentio/blob/a20d2a2d222aeb3ab2a8c7e72280f1df2618440e/lib/index.js#L255-L256).
|
|
@@ -1934,7 +2235,7 @@ function enqueue(type, message) {
|
|
|
1934
2235
|
}
|
|
1935
2236
|
messageBatch.push(message);
|
|
1936
2237
|
}
|
|
1937
|
-
// very barebones
|
|
2238
|
+
// very barebones implementation...
|
|
1938
2239
|
// does not support multiple concurrent flushes or large numbers of messages
|
|
1939
2240
|
async function flushAsync() {
|
|
1940
2241
|
if (utils_env.env.EXPO_NO_TELEMETRY)
|
|
@@ -1960,7 +2261,7 @@ async function flushAsync() {
|
|
|
1960
2261
|
await fetch(analyticsEndpoint, request);
|
|
1961
2262
|
}
|
|
1962
2263
|
catch {
|
|
1963
|
-
//
|
|
2264
|
+
// suppress errors - likely due to network connectivity or endpoint health
|
|
1964
2265
|
}
|
|
1965
2266
|
// clear array so we don't resend events in subsequent flushes
|
|
1966
2267
|
messageBatch.splice(0, messageBatch.length);
|
|
@@ -1977,7 +2278,7 @@ function getAnalyticsContext() {
|
|
|
1977
2278
|
return {
|
|
1978
2279
|
os: { name: platform, version: external_os_default().release() },
|
|
1979
2280
|
device: { type: platform, model: platform },
|
|
1980
|
-
app: { name: library, version:
|
|
2281
|
+
app: { name: library, version: getPackageJson()?.version ?? undefined },
|
|
1981
2282
|
};
|
|
1982
2283
|
}
|
|
1983
2284
|
//#endregion
|
|
@@ -1988,7 +2289,7 @@ function uuidv4() {
|
|
|
1988
2289
|
return external_crypto_default().randomUUID();
|
|
1989
2290
|
}
|
|
1990
2291
|
catch {
|
|
1991
|
-
//
|
|
2292
|
+
// suppress errors due to node 13 or less not having randomUUID
|
|
1992
2293
|
return null;
|
|
1993
2294
|
}
|
|
1994
2295
|
}
|
|
@@ -2009,14 +2310,14 @@ async function getAnalyticsIdentityAsync() {
|
|
|
2009
2310
|
if (!external_fs_default().existsSync(getStateJsonPath())) {
|
|
2010
2311
|
external_fs_default().writeFileSync(getStateJsonPath(), JSON.stringify({}));
|
|
2011
2312
|
}
|
|
2012
|
-
const savedDeviceId = await
|
|
2313
|
+
const savedDeviceId = await JsonFile["default"].getAsync(getStateJsonPath(), 'analyticsDeviceId', null);
|
|
2013
2314
|
const deviceId = savedDeviceId ?? uuidv4();
|
|
2014
2315
|
if (!deviceId) {
|
|
2015
2316
|
// unable to generate an id or load one from disk
|
|
2016
2317
|
return null;
|
|
2017
2318
|
}
|
|
2018
2319
|
if (!savedDeviceId) {
|
|
2019
|
-
await
|
|
2320
|
+
await JsonFile["default"].setAsync(getStateJsonPath(), 'analyticsDeviceId', deviceId);
|
|
2020
2321
|
}
|
|
2021
2322
|
const userId = getSession()?.userId ?? null;
|
|
2022
2323
|
return userId ? { anonymousId: deviceId, userId } : { anonymousId: deviceId };
|