react-native-update-cli 2.8.4 → 2.9.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 (112) hide show
  1. package/lib/api.d.ts +18 -0
  2. package/lib/app.d.ts +38 -0
  3. package/lib/app.js +5 -4
  4. package/lib/bundle-pack.d.ts +1 -0
  5. package/lib/bundle-pack.js +104 -0
  6. package/lib/bundle-runner.d.ts +20 -0
  7. package/lib/bundle-runner.js +404 -0
  8. package/lib/bundle.d.ts +6 -0
  9. package/lib/bundle.js +73 -471
  10. package/lib/diff.d.ts +13 -0
  11. package/lib/diff.js +144 -123
  12. package/lib/exports.d.ts +12 -0
  13. package/lib/index.d.ts +5 -0
  14. package/lib/index.js +5 -13
  15. package/lib/install.d.ts +4 -0
  16. package/lib/locales/en.d.ts +137 -0
  17. package/lib/locales/en.js +11 -0
  18. package/lib/locales/zh.d.ts +136 -0
  19. package/lib/locales/zh.js +11 -0
  20. package/lib/module-manager.d.ts +20 -0
  21. package/lib/module-manager.js +3 -9
  22. package/lib/modules/app-module.d.ts +2 -0
  23. package/lib/modules/app-module.js +84 -44
  24. package/lib/modules/bundle-module.d.ts +2 -0
  25. package/lib/modules/bundle-module.js +7 -8
  26. package/lib/modules/index.d.ts +6 -0
  27. package/lib/modules/package-module.d.ts +2 -0
  28. package/lib/modules/user-module.d.ts +2 -0
  29. package/lib/modules/user-module.js +55 -44
  30. package/lib/modules/version-module.d.ts +2 -0
  31. package/lib/package.d.ts +58 -0
  32. package/lib/package.js +103 -139
  33. package/lib/provider.d.ts +26 -0
  34. package/lib/provider.js +115 -217
  35. package/lib/types.d.ts +120 -0
  36. package/lib/user.d.ts +8 -0
  37. package/lib/utils/add-gitignore.d.ts +1 -0
  38. package/lib/utils/app-info-parser/aab.d.ts +22 -0
  39. package/lib/utils/app-info-parser/aab.js +0 -4
  40. package/lib/utils/app-info-parser/apk.d.ts +14 -0
  41. package/lib/utils/app-info-parser/apk.js +6 -4
  42. package/lib/utils/app-info-parser/app.d.ts +4 -0
  43. package/lib/utils/app-info-parser/app.js +3 -0
  44. package/lib/utils/app-info-parser/index.d.ts +16 -0
  45. package/lib/utils/app-info-parser/index.js +2 -0
  46. package/lib/utils/app-info-parser/ipa.d.ts +14 -0
  47. package/lib/utils/app-info-parser/ipa.js +1 -1
  48. package/lib/utils/app-info-parser/resource-finder.d.ts +49 -0
  49. package/lib/utils/app-info-parser/utils.d.ts +31 -0
  50. package/lib/utils/app-info-parser/utils.js +1 -0
  51. package/lib/utils/app-info-parser/xml-parser/binary.d.ts +56 -0
  52. package/lib/utils/app-info-parser/xml-parser/manifest.d.ts +10 -0
  53. package/lib/utils/app-info-parser/zip.d.ts +18 -0
  54. package/lib/utils/app-info-parser/zip.js +7 -9
  55. package/lib/utils/check-lockfile.d.ts +1 -0
  56. package/lib/utils/check-plugin.d.ts +7 -0
  57. package/lib/utils/command-result.d.ts +3 -0
  58. package/lib/utils/command-result.js +35 -0
  59. package/lib/utils/constants.d.ts +9 -0
  60. package/lib/utils/dep-versions.d.ts +1 -0
  61. package/lib/utils/git.d.ts +8 -0
  62. package/lib/utils/http-helper.d.ts +4 -0
  63. package/lib/utils/i18n.d.ts +12 -0
  64. package/lib/utils/index.d.ts +22 -0
  65. package/lib/utils/index.js +52 -22
  66. package/lib/utils/latest-version/cli.d.ts +1 -0
  67. package/lib/utils/latest-version/cli.js +24 -60
  68. package/lib/utils/latest-version/index.d.ts +146 -0
  69. package/lib/utils/latest-version/index.js +22 -22
  70. package/lib/utils/options.d.ts +4 -0
  71. package/lib/utils/options.js +63 -0
  72. package/lib/utils/plugin-config.d.ts +9 -0
  73. package/lib/utils/zip-entries.d.ts +3 -0
  74. package/lib/versions.d.ts +43 -0
  75. package/lib/versions.js +186 -2
  76. package/lib/workflow-runner.d.ts +2 -0
  77. package/lib/workflow-runner.js +25 -0
  78. package/package.json +20 -5
  79. package/src/api.ts +1 -1
  80. package/src/app.ts +20 -11
  81. package/src/bundle-pack.ts +51 -0
  82. package/src/bundle-runner.ts +463 -0
  83. package/src/bundle.ts +184 -571
  84. package/src/diff.ts +208 -174
  85. package/src/index.ts +15 -17
  86. package/src/locales/en.ts +15 -0
  87. package/src/locales/zh.ts +13 -0
  88. package/src/module-manager.ts +15 -15
  89. package/src/modules/app-module.ts +120 -48
  90. package/src/modules/bundle-module.ts +21 -11
  91. package/src/modules/package-module.ts +0 -1
  92. package/src/modules/user-module.ts +117 -58
  93. package/src/package.ts +158 -138
  94. package/src/provider.ts +164 -240
  95. package/src/types.ts +15 -8
  96. package/src/utils/app-info-parser/aab.ts +0 -7
  97. package/src/utils/app-info-parser/apk.ts +9 -6
  98. package/src/utils/app-info-parser/app.ts +5 -1
  99. package/src/utils/app-info-parser/index.ts +11 -6
  100. package/src/utils/app-info-parser/ipa.ts +1 -1
  101. package/src/utils/app-info-parser/utils.ts +3 -0
  102. package/src/utils/app-info-parser/xml-parser/manifest.ts +3 -1
  103. package/src/utils/app-info-parser/zip.ts +12 -14
  104. package/src/utils/command-result.ts +24 -0
  105. package/src/utils/index.ts +138 -39
  106. package/src/utils/latest-version/cli.ts +22 -20
  107. package/src/utils/latest-version/index.ts +20 -20
  108. package/src/utils/options.ts +56 -0
  109. package/src/utils/zip-entries.ts +1 -1
  110. package/src/versions.ts +265 -2
  111. package/src/workflow-runner.ts +24 -0
  112. package/index.js +0 -1
package/src/bundle.ts CHANGED
@@ -1,555 +1,177 @@
1
- import { spawn, spawnSync } from 'child_process';
2
1
  import path from 'path';
3
- import { satisfies } from 'compare-versions';
4
- import * as fs from 'fs-extra';
5
- import { ZipFile as YazlZipFile } from 'yazl';
6
2
  import { getPlatform } from './app';
7
- import { translateOptions } from './utils';
8
- import { checkPlugins, question } from './utils';
9
- const g2js = require('gradle-to-js/lib/parser');
10
- const properties = require('properties');
3
+ import { packBundle } from './bundle-pack';
4
+ import {
5
+ copyDebugidForSentry,
6
+ runReactNativeBundleCommand,
7
+ uploadSourcemapForSentry,
8
+ } from './bundle-runner';
9
+ import type { Platform } from './types';
10
+ import { checkPlugins, question, translateOptions } from './utils';
11
11
  import { addGitIgnore } from './utils/add-gitignore';
12
12
  import { checkLockFiles } from './utils/check-lockfile';
13
13
  import { tempDir } from './utils/constants';
14
14
  import { depVersions } from './utils/dep-versions';
15
15
  import { t } from './utils/i18n';
16
+ import {
17
+ getBooleanOption,
18
+ getOptionalStringOption,
19
+ getStringOption,
20
+ } from './utils/options';
16
21
  import { versionCommands } from './versions';
17
- import os from 'os';
18
22
 
19
- async function runReactNativeBundleCommand({
20
- bundleName,
21
- dev,
22
- entryFile,
23
- outputFolder,
24
- platform,
25
- sourcemapOutput,
26
- config,
27
- forceHermes,
28
- cli,
29
- }: {
23
+ type NormalizedBundleOptions = {
30
24
  bundleName: string;
31
- dev: string;
32
25
  entryFile: string;
33
- outputFolder: string;
34
- platform: string;
35
- sourcemapOutput: string;
36
- config?: string;
37
- forceHermes?: boolean;
38
- cli: {
39
- taro?: boolean;
40
- expo?: boolean;
41
- rncli?: boolean;
42
- };
43
- }) {
44
- let gradleConfig: {
45
- crunchPngs?: boolean;
46
- enableHermes?: boolean;
47
- } = {};
48
- if (platform === 'android') {
49
- gradleConfig = await checkGradleConfig();
50
- if (gradleConfig.crunchPngs !== false) {
51
- console.warn(t('androidCrunchPngsWarning'));
52
- }
53
- }
54
-
55
- const reactNativeBundleArgs: string[] = [];
56
-
57
- const envArgs = process.env.PUSHY_ENV_ARGS;
58
-
59
- if (envArgs) {
60
- reactNativeBundleArgs.push(...envArgs.trim().split(/\s+/));
61
- }
62
-
63
- fs.emptyDirSync(outputFolder);
64
-
65
- let cliPath = '';
66
- let usingExpo = false;
67
-
68
- const getExpoCli = () => {
69
- try {
70
- const searchPaths = [process.cwd()];
71
-
72
- // 尝试添加 expo 包的路径作为额外的搜索路径
73
- try {
74
- const expoPath = require.resolve('expo/package.json', {
75
- paths: [process.cwd()],
76
- });
77
- // 获取 expo 包的目录路径
78
- const expoDir = expoPath.replace(/\/package\.json$/, '');
79
- searchPaths.push(expoDir);
80
- } catch {
81
- // expo 包不存在,忽略
82
- }
83
-
84
- // 尝试从搜索路径中解析 @expo/cli
85
- cliPath = require.resolve('@expo/cli', {
86
- paths: searchPaths,
87
- });
88
-
89
- const expoCliVersion = JSON.parse(
90
- fs
91
- .readFileSync(
92
- require.resolve('@expo/cli/package.json', {
93
- paths: searchPaths,
94
- }),
95
- )
96
- .toString(),
97
- ).version;
98
- // expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
99
- if (satisfies(expoCliVersion, '>= 0.10.17')) {
100
- usingExpo = true;
101
- } else {
102
- cliPath = '';
103
- }
104
- } catch (e) {}
105
- };
106
-
107
- const getRnCli = () => {
108
- try {
109
- // rn < 0.75
110
- cliPath = require.resolve('react-native/local-cli/cli.js', {
111
- paths: [process.cwd()],
112
- });
113
- } catch (e) {
114
- // rn >= 0.75
115
- cliPath = require.resolve('@react-native-community/cli/build/bin.js', {
116
- paths: [process.cwd()],
117
- });
118
- }
119
- };
120
-
121
- const getTaroCli = () => {
122
- try {
123
- cliPath = require.resolve('@tarojs/cli/bin/taro', {
124
- paths: [process.cwd()],
125
- });
126
- } catch (e) {}
127
- };
128
-
129
- if (cli.expo) {
130
- getExpoCli();
131
- } else if (cli.taro) {
132
- getTaroCli();
133
- } else if (cli.rncli) {
134
- getRnCli();
135
- }
136
-
137
- if (!cliPath) {
138
- getExpoCli();
139
- if (!usingExpo) {
140
- getRnCli();
141
- }
142
- }
143
-
144
- const bundleParams = await checkPlugins();
145
- const isSentry = bundleParams.sentry;
146
-
147
- if (isSentry) {
148
- if (platform === 'ios') {
149
- process.env.SENTRY_PROPERTIES = 'ios/sentry.properties';
150
- } else if (platform === 'android') {
151
- process.env.SENTRY_PROPERTIES = 'android/sentry.properties';
152
- }
153
- }
154
-
155
- let bundleCommand = 'bundle';
156
- if (usingExpo) {
157
- bundleCommand = 'export:embed';
158
- } else if (platform === 'harmony') {
159
- bundleCommand = 'bundle-harmony';
160
- } else if (cli.taro) {
161
- bundleCommand = 'build';
162
- }
163
-
164
- if (platform === 'harmony') {
165
- bundleName = 'bundle.harmony.js';
166
- if (forceHermes === undefined) {
167
- // enable hermes by default for harmony
168
- forceHermes = true;
169
- }
170
- }
171
-
172
- reactNativeBundleArgs.push(
173
- cliPath,
174
- bundleCommand,
175
- '--assets-dest',
176
- outputFolder,
177
- '--bundle-output',
178
- path.join(outputFolder, bundleName),
179
- );
180
-
181
- if (platform !== 'harmony') {
182
- reactNativeBundleArgs.push('--platform', platform, '--reset-cache');
183
- }
184
-
185
- if (cli.taro) {
186
- reactNativeBundleArgs.push('--type', 'rn');
187
- } else {
188
- reactNativeBundleArgs.push('--dev', dev, '--entry-file', entryFile);
189
- }
190
-
191
- if (sourcemapOutput) {
192
- reactNativeBundleArgs.push('--sourcemap-output', sourcemapOutput);
193
- }
194
-
195
- if (config) {
196
- reactNativeBundleArgs.push('--config', config);
197
- }
198
-
199
- const reactNativeBundleProcess = spawn('node', reactNativeBundleArgs);
200
- console.log(
201
- `Running bundle command: node ${reactNativeBundleArgs.join(' ')}`,
202
- );
203
-
204
- return new Promise((resolve, reject) => {
205
- reactNativeBundleProcess.stdout.on('data', (data) => {
206
- console.log(data.toString().trim());
207
- });
208
-
209
- reactNativeBundleProcess.stderr.on('data', (data) => {
210
- console.error(data.toString().trim());
211
- });
212
-
213
- reactNativeBundleProcess.on('close', async (exitCode) => {
214
- if (exitCode) {
215
- reject(new Error(t('bundleCommandError', { code: exitCode })));
216
- } else {
217
- let hermesEnabled: boolean | undefined = false;
218
-
219
- if (forceHermes) {
220
- hermesEnabled = true;
221
- console.log(t('forceHermes'));
222
- } else if (platform === 'android') {
223
- const gradlePropeties = await new Promise<{
224
- hermesEnabled?: boolean;
225
- }>((resolve) => {
226
- properties.parse(
227
- './android/gradle.properties',
228
- { path: true },
229
- (error: any, props: { hermesEnabled?: boolean }) => {
230
- if (error) {
231
- console.error(error);
232
- resolve({});
233
- }
234
-
235
- resolve(props);
236
- },
237
- );
238
- });
239
- hermesEnabled = gradlePropeties.hermesEnabled;
240
-
241
- if (typeof hermesEnabled !== 'boolean')
242
- hermesEnabled = gradleConfig.enableHermes;
243
- } else if (
244
- platform === 'ios' &&
245
- fs.existsSync('ios/Pods/hermes-engine')
246
- ) {
247
- hermesEnabled = true;
248
- }
249
- if (hermesEnabled) {
250
- await compileHermesByteCode(
251
- bundleName,
252
- outputFolder,
253
- sourcemapOutput,
254
- !isSentry,
255
- );
256
- }
257
- if (platform === 'harmony') {
258
- const harmonyRawAssetsPath =
259
- 'harmony/entry/src/main/resources/rawfile/assets';
260
- // copy all files in outputFolder to harmonyRawPath
261
- // assets should be in rawfile/assets
262
- fs.ensureDirSync(harmonyRawAssetsPath);
263
- fs.copySync(outputFolder, harmonyRawAssetsPath, { overwrite: true });
264
- fs.moveSync(
265
- `${harmonyRawAssetsPath}/bundle.harmony.js`,
266
- `${harmonyRawAssetsPath}/../bundle.harmony.js`,
267
- { overwrite: true },
268
- );
269
- }
270
- resolve(null);
271
- }
272
- });
273
- });
274
- }
26
+ intermediaDir: string;
27
+ output: string;
28
+ dev: string;
29
+ sourcemap: boolean;
30
+ taro: boolean;
31
+ expo: boolean;
32
+ rncli: boolean;
33
+ hermes: boolean;
34
+ name?: string;
35
+ description?: string;
36
+ metaInfo?: string;
37
+ packageId?: string;
38
+ packageVersion?: string;
39
+ minPackageVersion?: string;
40
+ maxPackageVersion?: string;
41
+ packageVersionRange?: string;
42
+ rollout?: string;
43
+ dryRun: boolean;
44
+ };
275
45
 
276
- function getHermesOSBin() {
277
- if (os.platform() === 'win32') return 'win64-bin';
278
- if (os.platform() === 'darwin') return 'osx-bin';
279
- if (os.platform() === 'linux') return 'linux64-bin';
280
- }
46
+ type PublishBundlePayload = {
47
+ name?: string;
48
+ description?: string;
49
+ metaInfo?: string;
50
+ packageId?: string;
51
+ packageVersion?: string;
52
+ minPackageVersion?: string;
53
+ maxPackageVersion?: string;
54
+ packageVersionRange?: string;
55
+ rollout?: string;
56
+ dryRun?: boolean;
57
+ };
281
58
 
282
- async function checkGradleConfig() {
283
- let enableHermes = false;
284
- let crunchPngs: boolean | undefined;
285
- try {
286
- const gradleConfig = await g2js.parseFile('android/app/build.gradle');
287
- crunchPngs = gradleConfig.android.buildTypes.release.crunchPngs;
288
- const projectConfig = gradleConfig['project.ext.react'];
289
- if (projectConfig) {
290
- for (const packagerConfig of projectConfig) {
291
- if (
292
- packagerConfig.includes('enableHermes') &&
293
- packagerConfig.includes('true')
294
- ) {
295
- enableHermes = true;
296
- break;
297
- }
298
- }
299
- }
300
- } catch (e) {}
59
+ function normalizeBundleOptions(
60
+ translatedOptions: Record<string, unknown>,
61
+ platform: string,
62
+ ): NormalizedBundleOptions {
301
63
  return {
302
- enableHermes,
303
- crunchPngs,
64
+ bundleName: getStringOption(
65
+ translatedOptions,
66
+ 'bundleName',
67
+ 'index.bundlejs',
68
+ ),
69
+ entryFile: getStringOption(translatedOptions, 'entryFile', 'index.js'),
70
+ intermediaDir: getStringOption(
71
+ translatedOptions,
72
+ 'intermediaDir',
73
+ `${tempDir}/intermedia/${platform}`,
74
+ ),
75
+ output: getStringOption(
76
+ translatedOptions,
77
+ 'output',
78
+ `${tempDir}/output/${platform}.\${time}.ppk`,
79
+ ),
80
+ dev: getBooleanOption(translatedOptions, 'dev', false) ? 'true' : 'false',
81
+ sourcemap: getBooleanOption(translatedOptions, 'sourcemap', false),
82
+ taro: getBooleanOption(translatedOptions, 'taro', false),
83
+ expo: getBooleanOption(translatedOptions, 'expo', false),
84
+ rncli: getBooleanOption(translatedOptions, 'rncli', false),
85
+ hermes: getBooleanOption(translatedOptions, 'hermes', false),
86
+ name: getOptionalStringOption(translatedOptions, 'name'),
87
+ description: getOptionalStringOption(translatedOptions, 'description'),
88
+ metaInfo: getOptionalStringOption(translatedOptions, 'metaInfo'),
89
+ packageId: getOptionalStringOption(translatedOptions, 'packageId'),
90
+ packageVersion: getOptionalStringOption(
91
+ translatedOptions,
92
+ 'packageVersion',
93
+ ),
94
+ minPackageVersion: getOptionalStringOption(
95
+ translatedOptions,
96
+ 'minPackageVersion',
97
+ ),
98
+ maxPackageVersion: getOptionalStringOption(
99
+ translatedOptions,
100
+ 'maxPackageVersion',
101
+ ),
102
+ packageVersionRange: getOptionalStringOption(
103
+ translatedOptions,
104
+ 'packageVersionRange',
105
+ ),
106
+ rollout: getOptionalStringOption(translatedOptions, 'rollout'),
107
+ dryRun: getBooleanOption(translatedOptions, 'dryRun', false),
304
108
  };
305
109
  }
306
110
 
307
- async function compileHermesByteCode(
111
+ async function uploadSentryArtifactsIfNeeded(
112
+ shouldUpload: boolean,
308
113
  bundleName: string,
309
- outputFolder: string,
114
+ intermediaDir: string,
310
115
  sourcemapOutput: string,
311
- shouldCleanSourcemap: boolean,
312
- ) {
313
- console.log(t('hermesEnabledCompiling'));
314
- // >= rn 0.69
315
- const rnDir = path.dirname(
316
- require.resolve('react-native', {
317
- paths: [process.cwd()],
318
- }),
116
+ versionName: string,
117
+ ): Promise<void> {
118
+ if (!shouldUpload) {
119
+ return;
120
+ }
121
+
122
+ await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
123
+ await uploadSourcemapForSentry(
124
+ bundleName,
125
+ intermediaDir,
126
+ sourcemapOutput,
127
+ versionName,
319
128
  );
320
- let hermesPath = path.join(rnDir, `/sdks/hermesc/${getHermesOSBin()}`);
321
-
322
- // < rn 0.69
323
- if (!fs.existsSync(hermesPath)) {
324
- hermesPath = `node_modules/hermes-engine/${getHermesOSBin()}`;
325
- }
326
-
327
- const hermesCommand = `${hermesPath}/hermesc`;
328
-
329
- const args = [
330
- '-emit-binary',
331
- '-out',
332
- path.join(outputFolder, bundleName),
333
- path.join(outputFolder, bundleName),
334
- '-O',
335
- ];
336
- if (sourcemapOutput) {
337
- fs.copyFileSync(
338
- sourcemapOutput,
339
- path.join(outputFolder, `${bundleName}.txt.map`),
340
- );
341
- args.push('-output-source-map');
342
- }
343
- console.log(
344
- t('runningHermesc', { command: hermesCommand, args: args.join(' ') }),
345
- );
346
- spawnSync(hermesCommand, args, {
347
- stdio: 'ignore',
348
- });
349
- if (sourcemapOutput) {
350
- const composerPath =
351
- 'node_modules/react-native/scripts/compose-source-maps.js';
352
- if (!fs.existsSync(composerPath)) {
353
- return;
354
- }
355
- console.log(t('composingSourceMap'));
356
- spawnSync(
357
- 'node',
358
- [
359
- composerPath,
360
- path.join(outputFolder, `${bundleName}.txt.map`),
361
- path.join(outputFolder, `${bundleName}.map`),
362
- '-o',
363
- sourcemapOutput,
364
- ],
365
- {
366
- stdio: 'ignore',
367
- },
368
- );
369
- }
370
- if (shouldCleanSourcemap) {
371
- fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
372
- }
373
- }
374
-
375
- async function copyDebugidForSentry(
376
- bundleName: string,
377
- outputFolder: string,
378
- sourcemapOutput: string,
379
- ) {
380
- if (sourcemapOutput) {
381
- let copyDebugidPath: string | undefined;
382
- try {
383
- copyDebugidPath = require.resolve(
384
- '@sentry/react-native/scripts/copy-debugid.js',
385
- {
386
- paths: [process.cwd()],
387
- },
388
- );
389
- } catch (error) {
390
- console.error(t('sentryCliNotFound'));
391
- return;
392
- }
393
-
394
- if (!fs.existsSync(copyDebugidPath)) {
395
- return;
396
- }
397
- console.log(t('copyingDebugId'));
398
- spawnSync(
399
- 'node',
400
- [
401
- copyDebugidPath,
402
- path.join(outputFolder, `${bundleName}.txt.map`),
403
- path.join(outputFolder, `${bundleName}.map`),
404
- ],
405
- {
406
- stdio: 'ignore',
407
- },
408
- );
409
- }
410
- fs.removeSync(path.join(outputFolder, `${bundleName}.txt.map`));
411
- }
412
-
413
- async function uploadSourcemapForSentry(
414
- bundleName: string,
415
- outputFolder: string,
416
- sourcemapOutput: string,
417
- version: string,
418
- ) {
419
- if (sourcemapOutput) {
420
- let sentryCliPath: string | undefined;
421
- try {
422
- sentryCliPath = require.resolve('@sentry/cli/bin/sentry-cli', {
423
- paths: [process.cwd()],
424
- });
425
- } catch (error) {
426
- console.error(t('sentryCliNotFound'));
427
- return;
428
- }
429
-
430
- if (!fs.existsSync(sentryCliPath)) {
431
- return;
432
- }
433
-
434
- spawnSync(
435
- 'node',
436
- [sentryCliPath, 'releases', 'set-commits', version, '--auto'],
437
- {
438
- stdio: 'inherit',
439
- },
440
- );
441
- console.log(t('sentryReleaseCreated', { version }));
442
-
443
- console.log(t('uploadingSourcemap'));
444
- spawnSync(
445
- 'node',
446
- [
447
- sentryCliPath,
448
- 'releases',
449
- 'files',
450
- version,
451
- 'upload-sourcemaps',
452
- '--strip-prefix',
453
- path.join(process.cwd(), outputFolder),
454
- path.join(outputFolder, bundleName),
455
- path.join(outputFolder, `${bundleName}.map`),
456
- ],
457
- {
458
- stdio: 'inherit',
459
- },
460
- );
461
- }
462
129
  }
463
130
 
464
- const ignorePackingFileNames = [
465
- '.',
466
- '..',
467
- 'index.bundlejs.map',
468
- 'bundle.harmony.js.map',
469
- ];
470
- const ignorePackingExtensions = ['DS_Store', 'txt.map'];
471
- async function pack(dir: string, output: string) {
472
- console.log(t('packing'));
473
- fs.ensureDirSync(path.dirname(output));
474
- await new Promise<void>((resolve, reject) => {
475
- const zipfile = new YazlZipFile();
476
-
477
- function addDirectory(root: string, rel: string) {
478
- if (rel) {
479
- zipfile.addEmptyDirectory(rel);
480
- }
481
- const childs = fs.readdirSync(root);
482
- for (const name of childs) {
483
- if (
484
- ignorePackingFileNames.includes(name) ||
485
- ignorePackingExtensions.some((ext) => name.endsWith(`.${ext}`))
486
- ) {
487
- continue;
488
- }
489
- const fullPath = path.join(root, name);
490
- const stat = fs.statSync(fullPath);
491
- if (stat.isFile()) {
492
- //console.log('adding: ' + rel+name);
493
- zipfile.addFile(fullPath, rel + name);
494
- } else if (stat.isDirectory()) {
495
- //console.log('adding: ' + rel+name+'/');
496
- addDirectory(fullPath, `${rel}${name}/`);
497
- }
498
- }
499
- }
500
-
501
- addDirectory(dir, '');
502
-
503
- zipfile.outputStream.on('error', (err: any) => reject(err));
504
- zipfile.outputStream.pipe(fs.createWriteStream(output)).on('close', () => {
505
- resolve(void 0);
506
- });
507
- zipfile.end();
131
+ async function publishBundleVersion(
132
+ outputPath: string,
133
+ platform: Platform,
134
+ payload: PublishBundlePayload,
135
+ ): Promise<string> {
136
+ return versionCommands.publish({
137
+ args: [outputPath],
138
+ options: {
139
+ platform,
140
+ ...payload,
141
+ },
508
142
  });
509
- console.log(t('fileGenerated', { file: output }));
510
143
  }
511
144
 
512
145
  export const bundleCommands = {
513
- bundle: async ({ options }) => {
514
- const platform = await getPlatform(options.platform);
146
+ bundle: async ({
147
+ options,
148
+ }: {
149
+ args?: string[];
150
+ options: Record<string, unknown>;
151
+ }) => {
152
+ const platform = await getPlatform(
153
+ typeof options.platform === 'string' ? options.platform : undefined,
154
+ );
515
155
 
516
- const {
517
- bundleName,
518
- entryFile,
519
- intermediaDir,
520
- output,
521
- dev,
522
- sourcemap,
523
- taro,
524
- expo,
525
- rncli,
526
- hermes,
527
- name,
528
- description,
529
- metaInfo,
530
- packageId,
531
- packageVersion,
532
- minPackageVersion,
533
- maxPackageVersion,
534
- packageVersionRange,
535
- rollout,
536
- dryRun,
537
- } = translateOptions({
156
+ const translatedOptions = translateOptions({
538
157
  ...options,
539
158
  tempDir,
540
159
  platform,
541
160
  });
161
+ const normalized = normalizeBundleOptions(translatedOptions, platform);
542
162
 
543
163
  checkLockFiles();
544
164
  addGitIgnore();
545
165
 
546
166
  const bundleParams = await checkPlugins();
547
- const sourcemapPlugin = bundleParams.sourcemap;
548
- const isSentry = bundleParams.sentry;
549
-
550
- const sourcemapOutput = path.join(intermediaDir, `${bundleName}.map`);
551
-
552
- const realOutput = output.replace(/\$\{time\}/g, `${Date.now()}`);
167
+ const sourcemapOutput = path.join(
168
+ normalized.intermediaDir,
169
+ `${normalized.bundleName}.map`,
170
+ );
171
+ const realOutput = normalized.output.replace(
172
+ /\$\{time\}/g,
173
+ `${Date.now()}`,
174
+ );
553
175
 
554
176
  if (!platform) {
555
177
  throw new Error(t('platformRequired'));
@@ -558,72 +180,63 @@ export const bundleCommands = {
558
180
  console.log(`Bundling with react-native: ${depVersions['react-native']}`);
559
181
 
560
182
  await runReactNativeBundleCommand({
561
- bundleName,
562
- dev,
563
- entryFile,
564
- outputFolder: intermediaDir,
183
+ bundleName: normalized.bundleName,
184
+ dev: normalized.dev,
185
+ entryFile: normalized.entryFile,
186
+ outputFolder: normalized.intermediaDir,
565
187
  platform,
566
- sourcemapOutput: sourcemap || sourcemapPlugin ? sourcemapOutput : '',
567
- forceHermes: hermes as unknown as boolean,
188
+ sourcemapOutput:
189
+ normalized.sourcemap || bundleParams.sourcemap ? sourcemapOutput : '',
190
+ forceHermes: normalized.hermes,
568
191
  cli: {
569
- taro: !!taro,
570
- expo: !!expo,
571
- rncli: !!rncli,
192
+ taro: normalized.taro,
193
+ expo: normalized.expo,
194
+ rncli: normalized.rncli,
572
195
  },
196
+ isSentry: bundleParams.sentry,
573
197
  });
574
198
 
575
- await pack(path.resolve(intermediaDir), realOutput);
576
-
577
- if (name) {
578
- const versionName = await versionCommands.publish({
579
- args: [realOutput],
580
- options: {
581
- platform,
582
- name,
583
- description,
584
- metaInfo,
585
- packageId,
586
- packageVersion,
587
- minPackageVersion,
588
- maxPackageVersion,
589
- packageVersionRange,
590
- rollout,
591
- dryRun: Boolean(dryRun),
592
- },
199
+ await packBundle(path.resolve(normalized.intermediaDir), realOutput);
200
+
201
+ if (normalized.name) {
202
+ const versionName = await publishBundleVersion(realOutput, platform, {
203
+ name: normalized.name,
204
+ description: normalized.description,
205
+ metaInfo: normalized.metaInfo,
206
+ packageId: normalized.packageId,
207
+ packageVersion: normalized.packageVersion,
208
+ minPackageVersion: normalized.minPackageVersion,
209
+ maxPackageVersion: normalized.maxPackageVersion,
210
+ packageVersionRange: normalized.packageVersionRange,
211
+ rollout: normalized.rollout,
212
+ dryRun: normalized.dryRun,
593
213
  });
214
+ await uploadSentryArtifactsIfNeeded(
215
+ bundleParams.sentry,
216
+ normalized.bundleName,
217
+ normalized.intermediaDir,
218
+ sourcemapOutput,
219
+ versionName,
220
+ );
221
+ return;
222
+ }
594
223
 
595
- if (isSentry) {
596
- await copyDebugidForSentry(bundleName, intermediaDir, sourcemapOutput);
597
- await uploadSourcemapForSentry(
598
- bundleName,
599
- intermediaDir,
224
+ if (!getBooleanOption(options, 'no-interactive', false)) {
225
+ const v = await question(t('uploadBundlePrompt'));
226
+ if (v.toLowerCase() === 'y') {
227
+ const versionName = await publishBundleVersion(
228
+ realOutput,
229
+ platform,
230
+ {},
231
+ );
232
+ await uploadSentryArtifactsIfNeeded(
233
+ bundleParams.sentry,
234
+ normalized.bundleName,
235
+ normalized.intermediaDir,
600
236
  sourcemapOutput,
601
237
  versionName,
602
238
  );
603
239
  }
604
- } else if (!options['no-interactive']) {
605
- const v = await question(t('uploadBundlePrompt'));
606
- if (v.toLowerCase() === 'y') {
607
- const versionName = await versionCommands.publish({
608
- args: [realOutput],
609
- options: {
610
- platform,
611
- },
612
- });
613
- if (isSentry) {
614
- await copyDebugidForSentry(
615
- bundleName,
616
- intermediaDir,
617
- sourcemapOutput,
618
- );
619
- await uploadSourcemapForSentry(
620
- bundleName,
621
- intermediaDir,
622
- sourcemapOutput,
623
- versionName,
624
- );
625
- }
626
- }
627
240
  }
628
241
  },
629
242
  };