rnbuilder 0.6.72 → 0.6.74

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/README.md CHANGED
@@ -40,7 +40,7 @@ $ npm install -g rnbuilder
40
40
  $ rnbuilder COMMAND
41
41
  running command...
42
42
  $ rnbuilder (-v|--version|version)
43
- rnbuilder/0.6.72 darwin-arm64 node-v24.13.0
43
+ rnbuilder/0.6.74 darwin-arm64 node-v24.13.0
44
44
  $ rnbuilder --help [COMMAND]
45
45
  USAGE
46
46
  $ rnbuilder COMMAND
@@ -98,7 +98,7 @@ EXAMPLE
98
98
  hello world from ./src/build.ts!
99
99
  ```
100
100
 
101
- _See code: [src/commands/build.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/build.ts)_
101
+ _See code: [src/commands/build.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/build.ts)_
102
102
 
103
103
  ## `rnbuilder check-version [MATCH-CHECK]`
104
104
 
@@ -117,7 +117,7 @@ EXAMPLE
117
117
  Nuke certificates ./src/match-check.ts!
118
118
  ```
119
119
 
120
- _See code: [src/commands/check-version.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/check-version.ts)_
120
+ _See code: [src/commands/check-version.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/check-version.ts)_
121
121
 
122
122
  ## `rnbuilder codepush [BUILD]`
123
123
 
@@ -136,7 +136,7 @@ EXAMPLE
136
136
  Push changes to existing apps ./src/firebase-sync-udids.ts!
137
137
  ```
138
138
 
139
- _See code: [src/commands/codepush.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/codepush.ts)_
139
+ _See code: [src/commands/codepush.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/codepush.ts)_
140
140
 
141
141
  ## `rnbuilder google-key [MATCH-CHECK]`
142
142
 
@@ -155,7 +155,7 @@ EXAMPLE
155
155
  Nuke certificates ./src/match-check.ts!
156
156
  ```
157
157
 
158
- _See code: [src/commands/google-key.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/google-key.ts)_
158
+ _See code: [src/commands/google-key.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/google-key.ts)_
159
159
 
160
160
  ## `rnbuilder help [COMMAND]`
161
161
 
@@ -187,7 +187,7 @@ EXAMPLE
187
187
  initialize environment for first run from ./src/initialize.ts!
188
188
  ```
189
189
 
190
- _See code: [src/commands/initialize.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/initialize.ts)_
190
+ _See code: [src/commands/initialize.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/initialize.ts)_
191
191
 
192
192
  ## `rnbuilder match-check [MATCH-CHECK]`
193
193
 
@@ -206,7 +206,7 @@ EXAMPLE
206
206
  Check match certificates ./src/match-check.ts!
207
207
  ```
208
208
 
209
- _See code: [src/commands/match-check.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/match-check.ts)_
209
+ _See code: [src/commands/match-check.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/match-check.ts)_
210
210
 
211
211
  ## `rnbuilder match-nuke [BUILD]`
212
212
 
@@ -225,7 +225,7 @@ EXAMPLE
225
225
  Nuke certificates ./src/match-nuke.ts!
226
226
  ```
227
227
 
228
- _See code: [src/commands/match-nuke.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/match-nuke.ts)_
228
+ _See code: [src/commands/match-nuke.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/match-nuke.ts)_
229
229
 
230
230
  ## `rnbuilder onesignal [BUILD]`
231
231
 
@@ -247,7 +247,7 @@ EXAMPLE
247
247
  Create and upload push certificate to One Signal from ./src/commands/onesignal.ts!
248
248
  ```
249
249
 
250
- _See code: [src/commands/onesignal.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/onesignal.ts)_
250
+ _See code: [src/commands/onesignal.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/onesignal.ts)_
251
251
 
252
252
  ## `rnbuilder reject-review [REJECT-REVIEW]`
253
253
 
@@ -265,7 +265,7 @@ EXAMPLE
265
265
  $ rnbuilder reject-review
266
266
  ```
267
267
 
268
- _See code: [src/commands/reject-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/reject-review.ts)_
268
+ _See code: [src/commands/reject-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/reject-review.ts)_
269
269
 
270
270
  ## `rnbuilder setup [SETUP]`
271
271
 
@@ -283,7 +283,7 @@ EXAMPLE
283
283
  hello world from ./src/setup.ts!
284
284
  ```
285
285
 
286
- _See code: [src/commands/setup.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/setup.ts)_
286
+ _See code: [src/commands/setup.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/setup.ts)_
287
287
 
288
288
  ## `rnbuilder setup-gcp`
289
289
 
@@ -297,7 +297,7 @@ OPTIONS
297
297
  -h, --help show CLI help
298
298
  ```
299
299
 
300
- _See code: [src/commands/setup-gcp.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/setup-gcp.ts)_
300
+ _See code: [src/commands/setup-gcp.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/setup-gcp.ts)_
301
301
 
302
302
  ## `rnbuilder submit-review [SUBMIT-REVIEW]`
303
303
 
@@ -316,7 +316,7 @@ EXAMPLE
316
316
  Push changes to existing apps ./src/firebase-sync-udids.ts!
317
317
  ```
318
318
 
319
- _See code: [src/commands/submit-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/submit-review.ts)_
319
+ _See code: [src/commands/submit-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/submit-review.ts)_
320
320
 
321
321
  ## `rnbuilder sync-udids [BUILD]`
322
322
 
@@ -335,5 +335,5 @@ EXAMPLE
335
335
  Sync device UDIDs from firebase from ./src/firebase-sync-udids.ts!
336
336
  ```
337
337
 
338
- _See code: [src/commands/sync-udids.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.72/src/commands/sync-udids.ts)_
338
+ _See code: [src/commands/sync-udids.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.74/src/commands/sync-udids.ts)_
339
339
  <!-- commandsstop -->
@@ -52,6 +52,7 @@ class Setup extends command_1.Command {
52
52
  // shell.exec(`mkdir configs/${client}`);
53
53
  const { appIconFile } = await app_icon_1.prepareAppIcon({
54
54
  iosAssetFolder,
55
+ androidAssetFolder,
55
56
  });
56
57
  const { launchScreen, launchScreenColor } = await launch_screen_1.prepareLaunchScreen({
57
58
  iosAssetFolder,
@@ -64,11 +65,9 @@ class Setup extends command_1.Command {
64
65
  if (launchScreenColor) {
65
66
  env_1.setEnvValue('LAUNCH_SCREEN_BACKGROUND_COLOR', launchScreenColor, envVars);
66
67
  }
67
- // Onesignal
68
- const { onesignal } = await onesignal_1.prepareOneSignal();
69
- if (onesignal) {
70
- env_1.setEnvValue('ONESIGNAL_APP_ID', onesignal, envVars);
71
- }
68
+ const devEnvPath = path.join(process.cwd(), `/configs/${client}/.env.dev`);
69
+ const stagingEnvPath = path.join(process.cwd(), `/configs/${client}/.env.staging`);
70
+ const prodEnvPath = path.join(process.cwd(), `/configs/${client}/.env.prod`);
72
71
  // Store dev env
73
72
  env_1.setEnvValue('ENV', 'dev', envVars);
74
73
  const devEnvVars = env_1.updateServiceDomain(envVars, 'app');
@@ -77,7 +76,7 @@ class Setup extends command_1.Command {
77
76
  }
78
77
  env_1.setEnvValue('BUNDLE_ID', `${bundleId}.dev`, devEnvVars);
79
78
  env_1.setEnvValue('APPLICATION_ID', `${applicationId}.dev`, devEnvVars);
80
- env_1.saveEnvValues(devEnvVars, path.join(process.cwd(), `/configs/${client}/.env.dev`));
79
+ env_1.saveEnvValues(devEnvVars, devEnvPath);
81
80
  // Store staging env
82
81
  env_1.setEnvValue('ENV', 'staging', envVars);
83
82
  const stagingEnvVars = env_1.updateServiceDomain(envVars, 'app');
@@ -86,7 +85,7 @@ class Setup extends command_1.Command {
86
85
  }
87
86
  env_1.setEnvValue('BUNDLE_ID', `${bundleId}.staging`, stagingEnvVars);
88
87
  env_1.setEnvValue('APPLICATION_ID', `${applicationId}.staging`, stagingEnvVars);
89
- env_1.saveEnvValues(stagingEnvVars, path.join(process.cwd(), `/configs/${client}/.env.staging`));
88
+ env_1.saveEnvValues(stagingEnvVars, stagingEnvPath);
90
89
  // Store prod env
91
90
  env_1.setEnvValue('ENV', 'prod', envVars);
92
91
  const prodEnvVars = env_1.updateServiceDomain(envVars, 'com');
@@ -95,7 +94,7 @@ class Setup extends command_1.Command {
95
94
  }
96
95
  env_1.setEnvValue('BUNDLE_ID', bundleId, prodEnvVars);
97
96
  env_1.setEnvValue('APPLICATION_ID', applicationId, prodEnvVars);
98
- env_1.saveEnvValues(prodEnvVars, path.join(process.cwd(), `/configs/${client}/.env.prod`));
97
+ env_1.saveEnvValues(prodEnvVars, prodEnvPath);
99
98
  // Setup fastlane
100
99
  const { firebaseIosApp, firebaseAndroidApp } = await fastlane_1.setupFastlane({
101
100
  client,
@@ -110,7 +109,7 @@ class Setup extends command_1.Command {
110
109
  env_1.setEnvValue('APP_IDENTIFIER', bundleId, fastlaneEnvVars);
111
110
  }
112
111
  if (applicationId) {
113
- env_1.setEnvValue('APP_IDENTIFIER_ANDROID', bundleId, fastlaneEnvVars);
112
+ env_1.setEnvValue('APP_IDENTIFIER_ANDROID', applicationId, fastlaneEnvVars);
114
113
  }
115
114
  if (appName) {
116
115
  env_1.setEnvValue('APP_NAME', appName, fastlaneEnvVars);
@@ -130,6 +129,25 @@ class Setup extends command_1.Command {
130
129
  env_1.setEnvValue('FIREBASE_ANDROID_APP', firebaseAndroidApp, fastlaneEnvVars);
131
130
  }
132
131
  env_1.saveEnvValues(fastlaneEnvVars, fastlaneDir + '/.env');
132
+ // Onesignal — creates the push cert via fastlane, needs the client fastlane
133
+ // env (APPLE_TEAM_ID, APP_IDENTIFIER, CLIENT) already written above.
134
+ const { onesignal, onesignalRestApiKey } = await onesignal_1.prepareOneSignal({
135
+ client,
136
+ fastlaneDir,
137
+ });
138
+ if (onesignal) {
139
+ env_1.setEnvValue('ONESIGNAL_APP_ID', onesignal, devEnvVars);
140
+ env_1.setEnvValue('ONESIGNAL_APP_ID', onesignal, stagingEnvVars);
141
+ env_1.setEnvValue('ONESIGNAL_APP_ID', onesignal, prodEnvVars);
142
+ env_1.saveEnvValues(devEnvVars, devEnvPath);
143
+ env_1.saveEnvValues(stagingEnvVars, stagingEnvPath);
144
+ env_1.saveEnvValues(prodEnvVars, prodEnvPath);
145
+ env_1.setEnvValue('ONESIGNAL_APP_ID', onesignal, fastlaneEnvVars);
146
+ if (onesignalRestApiKey) {
147
+ env_1.setEnvValue('ONESIGNAL_REST_API_KEY', onesignalRestApiKey, fastlaneEnvVars);
148
+ }
149
+ env_1.saveEnvValues(fastlaneEnvVars, fastlaneDir + '/.env');
150
+ }
133
151
  }
134
152
  }
135
153
  exports.default = Setup;
@@ -6,7 +6,7 @@ export declare const getAppVersion: (env: string, client?: string | undefined, t
6
6
  version: string;
7
7
  build: number;
8
8
  };
9
- export declare const copyDir: (src: string, dest: string) => Promise<unknown>;
9
+ export declare const copyDir: (src: string, dest: string, force?: boolean) => Promise<unknown>;
10
10
  export declare const ensureDir: (path: string) => void;
11
11
  export declare const exists: (path: string) => boolean;
12
12
  export declare const copyFile: (srcFile: string, destFile: string) => Promise<unknown>;
@@ -50,8 +50,8 @@ exports.getAppVersion = (env, client, target = 'ios') => {
50
50
  }
51
51
  return version;
52
52
  };
53
- exports.copyDir = (src, dest) => new Promise((resolve, reject) => {
54
- fs.cp(src, dest, { recursive: true }, (err) => {
53
+ exports.copyDir = (src, dest, force = true) => new Promise((resolve, reject) => {
54
+ fs.cp(src, dest, { recursive: true, force }, (err) => {
55
55
  if (err) {
56
56
  reject(err);
57
57
  }
@@ -0,0 +1,4 @@
1
+ export declare function generateAndroidIcons({ sourceFile, androidAssetFolder, }: {
2
+ sourceFile: string;
3
+ androidAssetFolder: string;
4
+ }): Promise<void>;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAndroidIcons = void 0;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const sharp = require("sharp");
7
+ const common_1 = require("../common");
8
+ const DENSITIES = [
9
+ { folder: 'mdpi', scale: 1 },
10
+ { folder: 'hdpi', scale: 1.5 },
11
+ { folder: 'xhdpi', scale: 2 },
12
+ { folder: 'xxhdpi', scale: 3 },
13
+ { folder: 'xxxhdpi', scale: 4 },
14
+ ];
15
+ const LEGACY_BASE_SIZE = 48;
16
+ const ADAPTIVE_CANVAS_BASE_SIZE = 108;
17
+ const ADAPTIVE_SAFE_ZONE_BASE_SIZE = 66;
18
+ const NOTIFICATION_BASE_SIZE = 24;
19
+ const ADAPTIVE_ICON_XML = `<?xml version="1.0" encoding="utf-8"?>
20
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
21
+ <background android:drawable="@mipmap/ic_launcher_background"/>
22
+ <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
23
+ </adaptive-icon>
24
+ `;
25
+ function circleMask(size) {
26
+ return Buffer.from(`<svg width="${size}" height="${size}"><circle cx="${size / 2}" cy="${size / 2}" r="${size / 2}" fill="#fff"/></svg>`);
27
+ }
28
+ async function generateLegacyIcons(sourceFile, mipmapDir, size) {
29
+ const square = await sharp(sourceFile).resize(size, size).png().toBuffer();
30
+ await sharp(square).toFile(path.join(mipmapDir, 'ic_launcher.png'));
31
+ await sharp(square)
32
+ .composite([{ input: circleMask(size), blend: 'dest-in' }])
33
+ .png()
34
+ .toFile(path.join(mipmapDir, 'ic_launcher_round.png'));
35
+ }
36
+ async function generateAdaptiveLayers(sourceFile, mipmapDir, canvasSize, safeZoneSize) {
37
+ await sharp({
38
+ create: { width: canvasSize, height: canvasSize, channels: 4, background: { r: 255, g: 255, b: 255, alpha: 1 } },
39
+ })
40
+ .png()
41
+ .toFile(path.join(mipmapDir, 'ic_launcher_background.png'));
42
+ const offset = Math.round((canvasSize - safeZoneSize) / 2);
43
+ const foreground = await sharp(sourceFile).resize(safeZoneSize, safeZoneSize).toBuffer();
44
+ await sharp({
45
+ create: { width: canvasSize, height: canvasSize, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } },
46
+ })
47
+ .composite([{ input: foreground, left: offset, top: offset }])
48
+ .png()
49
+ .toFile(path.join(mipmapDir, 'ic_launcher_foreground.png'));
50
+ }
51
+ // Notification icons must be a white silhouette on transparent. If the source
52
+ // has an alpha channel we use it directly (correct shape); otherwise we fall
53
+ // back to a luminance threshold, which assumes a dark mark on a light background.
54
+ async function buildSilhouetteMask(sourceFile, size) {
55
+ const meta = await sharp(sourceFile).metadata();
56
+ if (meta.hasAlpha) {
57
+ return sharp(sourceFile).resize(size, size).ensureAlpha().png().toBuffer();
58
+ }
59
+ const alphaChannel = await sharp(sourceFile)
60
+ .resize(size, size)
61
+ .greyscale()
62
+ .negate()
63
+ .threshold(128)
64
+ .toBuffer();
65
+ const rgb = await sharp({
66
+ create: { width: size, height: size, channels: 3, background: { r: 255, g: 255, b: 255 } },
67
+ })
68
+ .png()
69
+ .toBuffer();
70
+ return sharp(rgb).joinChannel(alphaChannel).png().toBuffer();
71
+ }
72
+ async function generateNotificationIcon(sourceFile, drawableDir, size) {
73
+ const mask = await buildSilhouetteMask(sourceFile, size);
74
+ const white = await sharp({
75
+ create: { width: size, height: size, channels: 4, background: { r: 255, g: 255, b: 255, alpha: 1 } },
76
+ })
77
+ .png()
78
+ .toBuffer();
79
+ await sharp(white)
80
+ .composite([{ input: mask, blend: 'dest-in' }])
81
+ .png()
82
+ .toFile(path.join(drawableDir, 'ic_notification.png'));
83
+ }
84
+ async function generateAndroidIcons({ sourceFile, androidAssetFolder, }) {
85
+ const anydpiDir = path.join(androidAssetFolder, 'mipmap-anydpi-v26');
86
+ common_1.ensureDir(anydpiDir);
87
+ fs.writeFileSync(path.join(anydpiDir, 'ic_launcher.xml'), ADAPTIVE_ICON_XML, 'utf-8');
88
+ fs.writeFileSync(path.join(anydpiDir, 'ic_launcher_round.xml'), ADAPTIVE_ICON_XML, 'utf-8');
89
+ for (const { folder, scale } of DENSITIES) {
90
+ const mipmapDir = path.join(androidAssetFolder, `mipmap-${folder}`);
91
+ const drawableDir = path.join(androidAssetFolder, `drawable-${folder}`);
92
+ common_1.ensureDir(mipmapDir);
93
+ common_1.ensureDir(drawableDir);
94
+ await generateLegacyIcons(sourceFile, mipmapDir, Math.round(LEGACY_BASE_SIZE * scale));
95
+ await generateAdaptiveLayers(sourceFile, mipmapDir, Math.round(ADAPTIVE_CANVAS_BASE_SIZE * scale), Math.round(ADAPTIVE_SAFE_ZONE_BASE_SIZE * scale));
96
+ await generateNotificationIcon(sourceFile, drawableDir, Math.round(NOTIFICATION_BASE_SIZE * scale));
97
+ }
98
+ console.log(`Generated Android launcher + adaptive + notification icons in ${androidAssetFolder}`);
99
+ console.log('Note: reference "ic_notification" from AndroidManifest.xml / push SDK config manually if not already wired.');
100
+ }
101
+ exports.generateAndroidIcons = generateAndroidIcons;
@@ -1,3 +1,3 @@
1
- export declare const prepareAppIcon: ({ iosAssetFolder }: any) => Promise<{
1
+ export declare const prepareAppIcon: ({ iosAssetFolder, androidAssetFolder }: any) => Promise<{
2
2
  appIconFile: string;
3
3
  }>;
@@ -5,29 +5,27 @@ const inquirer = require("inquirer");
5
5
  const path = require("path");
6
6
  const sharp = require("sharp");
7
7
  const common_1 = require("../common");
8
- exports.prepareAppIcon = async ({ iosAssetFolder }) => {
8
+ const android_icon_1 = require("./android-icon");
9
+ exports.prepareAppIcon = async ({ iosAssetFolder, androidAssetFolder }) => {
9
10
  const questions = [
10
- {
11
- type: 'confirm',
12
- name: 'android-icon',
13
- message: 'It is recommend to use Android Studio to create App icon and notification icon for android',
14
- },
15
11
  {
16
12
  type: 'input',
17
13
  name: 'appIconFile',
18
- message: 'App Icon file for iOS?',
14
+ message: 'App Icon file (1024x1024, used for iOS + Android)?',
19
15
  },
20
16
  ];
21
17
  const { appIconFile } = await inquirer.prompt(questions);
22
18
  if (appIconFile) {
19
+ const normalisedIcon = common_1.normalise(appIconFile);
23
20
  // Generate app icon for ios
24
21
  // Copy template files
25
22
  await common_1.copyDir('./template/AppIcon.appiconset', path.join(iosAssetFolder, 'AppIcon.appiconset'));
26
- await sharp(common_1.normalise(appIconFile))
23
+ await sharp(normalisedIcon)
27
24
  .resize(1024, 1024)
28
25
  .png()
29
26
  .removeAlpha()
30
27
  .toFile(path.join(iosAssetFolder, 'AppIcon.appiconset/ItunesArtwork@2x.png'));
28
+ await android_icon_1.generateAndroidIcons({ sourceFile: normalisedIcon, androidAssetFolder });
31
29
  }
32
30
  return { appIconFile: common_1.normalise(appIconFile) };
33
31
  };
@@ -1 +1,7 @@
1
- export declare const getAppleTeam: () => Promise<any>;
1
+ export declare const getAppleTeam: () => Promise<{
2
+ appleTeamId?: undefined;
3
+ itcTeamId?: undefined;
4
+ } | {
5
+ appleTeamId: any;
6
+ itcTeamId: any;
7
+ }>;
@@ -3,6 +3,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getAppleTeam = void 0;
4
4
  const inquirer = require("inquirer");
5
5
  const shell = require("shelljs");
6
+ function stripAnsi(input) {
7
+ // eslint-disable-next-line no-control-regex
8
+ return input.replace(/\x1b\[[0-9;]*m/g, '');
9
+ }
10
+ function parseTeamIds(output, sectionHeader) {
11
+ const startIdx = output.indexOf(sectionHeader);
12
+ if (startIdx === -1)
13
+ return [];
14
+ const rest = output.slice(startIdx + sectionHeader.length);
15
+ const nextSectionIdx = rest.indexOf('----');
16
+ const section = nextSectionIdx === -1 ? rest : rest.slice(0, nextSectionIdx);
17
+ const matches = [...section.matchAll(/([^\r\n(]+?)\s+\(([A-Za-z0-9]+)\)/g)];
18
+ return matches.map(m => ({ name: m[1].trim(), id: m[2] }));
19
+ }
20
+ async function resolveTeamId(candidates, label) {
21
+ if (candidates.length === 0)
22
+ return undefined;
23
+ if (candidates.length === 1)
24
+ return candidates[0].id;
25
+ const { chosen } = await inquirer.prompt([
26
+ {
27
+ type: 'list',
28
+ name: 'chosen',
29
+ message: `Multiple ${label} found — pick one:`,
30
+ choices: candidates.map(c => ({ name: `${c.name} (${c.id})`, value: c.id })),
31
+ },
32
+ ]);
33
+ return chosen;
34
+ }
6
35
  exports.getAppleTeam = async () => {
7
36
  const { account } = await inquirer.prompt([
8
37
  {
@@ -21,17 +50,35 @@ exports.getAppleTeam = async () => {
21
50
  message: 'What is Apple team name (using for searching)?',
22
51
  },
23
52
  ]);
24
- shell.exec(`fastlane get_team_names search:${team} id:${account}`);
25
- return inquirer.prompt([
26
- {
53
+ const result = shell.exec(`fastlane get_team_names search:${team} id:${account}`);
54
+ const output = stripAnsi(`${result.stdout}\n${result.stderr}`);
55
+ const devTeams = parseTeamIds(output, 'Developer teams for');
56
+ const itcTeams = parseTeamIds(output, 'Appstore Connect teams for');
57
+ const appleTeamId = await resolveTeamId(devTeams, 'Apple Developer teams');
58
+ const itcTeamId = await resolveTeamId(itcTeams, 'App Store Connect teams');
59
+ if (appleTeamId && itcTeamId) {
60
+ return { appleTeamId, itcTeamId };
61
+ }
62
+ const manualQuestions = [];
63
+ if (!appleTeamId) {
64
+ manualQuestions.push({
27
65
  type: 'input',
28
66
  name: 'appleTeamId',
29
67
  message: 'What is Developer Team Id?',
30
- },
31
- {
68
+ });
69
+ }
70
+ if (!itcTeamId) {
71
+ manualQuestions.push({
32
72
  type: 'input',
33
73
  name: 'itcTeamId',
34
74
  message: 'What is Appstore Connect Team Id?',
35
- },
36
- ]);
75
+ });
76
+ }
77
+ const manual = manualQuestions.length
78
+ ? await inquirer.prompt(manualQuestions)
79
+ : {};
80
+ return {
81
+ appleTeamId: appleTeamId || manual.appleTeamId,
82
+ itcTeamId: itcTeamId || manual.itcTeamId,
83
+ };
37
84
  };
@@ -8,9 +8,9 @@ const firebase_1 = require("./firebase");
8
8
  exports.setupFastlane = async ({ client, bundleId, applicationId, appName, }) => {
9
9
  const clientDir = path.join(process.cwd(), `fastlane/clients/${client}`);
10
10
  const fastlaneDir = path.join(clientDir, 'fastlane');
11
- if (!common_1.exists(fastlaneDir)) {
12
- await common_1.copyDir(path.join(process.cwd(), 'template/fastlane'), fastlaneDir);
13
- }
11
+ // Merge template files in without overwriting existing client files —
12
+ // fills gaps left by a partial/previous setup run (e.g. missing .env).
13
+ await common_1.copyDir(path.join(process.cwd(), 'template/fastlane'), fastlaneDir, false);
14
14
  const { firebaseServiceAccountFile, jsonKeyFile } = await inquirer.prompt([
15
15
  {
16
16
  type: 'input',
@@ -90,6 +90,15 @@ async function getAccessToken(serviceAccountPath) {
90
90
  return result.access_token;
91
91
  }
92
92
  exports.getAccessToken = getAccessToken;
93
+ async function findExistingAppId({ accessToken, projectId, platform, bundleId, packageName, }) {
94
+ const endpoint = platform === 'ios' ? 'iosApps' : 'androidApps';
95
+ const result = await httpsRequest(`https://firebase.googleapis.com/v1beta1/projects/${projectId}/${endpoint}`, 'GET', { Authorization: `Bearer ${accessToken}` });
96
+ const apps = result.apps || [];
97
+ const match = platform === 'ios'
98
+ ? apps.find((app) => app.bundleId === bundleId)
99
+ : apps.find((app) => app.packageName === packageName);
100
+ return match === null || match === void 0 ? void 0 : match.appId;
101
+ }
93
102
  async function createFirebaseApp({ accessToken, projectId, platform, bundleId, packageName, displayName, }) {
94
103
  const endpoint = platform === 'ios' ? 'iosApps' : 'androidApps';
95
104
  const payload = platform === 'ios'
@@ -99,8 +108,20 @@ async function createFirebaseApp({ accessToken, projectId, platform, bundleId, p
99
108
  Authorization: `Bearer ${accessToken}`,
100
109
  'Content-Type': 'application/json',
101
110
  }, JSON.stringify(payload));
102
- if (result.error)
111
+ if (result.error) {
112
+ if (result.error.status === 'ALREADY_EXISTS') {
113
+ const existingAppId = await findExistingAppId({
114
+ accessToken,
115
+ projectId,
116
+ platform,
117
+ bundleId,
118
+ packageName,
119
+ });
120
+ if (existingAppId)
121
+ return existingAppId;
122
+ }
103
123
  throw new Error(`Firebase API error: ${JSON.stringify(result.error)}`);
124
+ }
104
125
  if (result.done)
105
126
  return result.response.appId;
106
127
  if (result.name)
@@ -53,14 +53,14 @@ exports.prepareLaunchScreen = async ({ iosAssetFolder, androidAssetFolder, fallb
53
53
  .png()
54
54
  .toFile(path.join(iosAssetFolder, 'BootSplashLogo.imageset/bootsplash_logo.png'));
55
55
  }
56
- else if (launchScreen === 'fullscreen') {
57
- if (inputFile) {
58
- // ios
59
- await common_1.copyDir('./template/BootSplashImage.imageset', path.join(iosAssetFolder, 'BootSplashImage.imageset'));
60
- await sharp(inputFile)
61
- .png()
62
- .toFile(path.join(iosAssetFolder, 'BootSplashImage.imageset/splashTablet.png'));
63
- }
56
+ }
57
+ else if (launchScreen === 'fullscreen') {
58
+ if (inputFile) {
59
+ // ios
60
+ await common_1.copyDir('./template/BootSplashImage.imageset', path.join(iosAssetFolder, 'BootSplashImage.imageset'));
61
+ await sharp(inputFile)
62
+ .png()
63
+ .toFile(path.join(iosAssetFolder, 'BootSplashImage.imageset/splashTablet.png'));
64
64
  }
65
65
  }
66
66
  // There is no full screen for android, so generate icon
@@ -1,3 +1,7 @@
1
- export declare const prepareOneSignal: () => Promise<any> & {
2
- ui: import("inquirer/lib/ui/prompt");
3
- };
1
+ export declare const prepareOneSignal: ({ client, fastlaneDir, }: {
2
+ client: string;
3
+ fastlaneDir: string;
4
+ }) => Promise<{
5
+ onesignal?: string | undefined;
6
+ onesignalRestApiKey?: string | undefined;
7
+ }>;
@@ -2,12 +2,71 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.prepareOneSignal = void 0;
4
4
  const inquirer = require("inquirer");
5
- exports.prepareOneSignal = () => {
6
- return inquirer.prompt([
5
+ const shell = require("shelljs");
6
+ const common_1 = require("../common");
7
+ function parseValue(output, key) {
8
+ var _a;
9
+ const match = output.match(new RegExp(`^${key}=(.*)$`, 'm'));
10
+ const value = (_a = match === null || match === void 0 ? void 0 : match[1]) === null || _a === void 0 ? void 0 : _a.trim();
11
+ return value ? value : undefined;
12
+ }
13
+ async function askAppIdManually() {
14
+ const { onesignal } = await inquirer.prompt([
7
15
  {
8
16
  type: 'input',
9
17
  name: 'onesignal',
10
18
  message: 'What is OneSignal App Id?',
11
19
  },
12
20
  ]);
21
+ return { onesignal, onesignalRestApiKey: undefined };
22
+ }
23
+ exports.prepareOneSignal = async ({ client, fastlaneDir, }) => {
24
+ const fastlaneConfigs = common_1.getFastlaneConfigs();
25
+ let authToken = fastlaneConfigs.onesignalAuthToken;
26
+ if (!authToken) {
27
+ const { inputToken } = await inquirer.prompt([
28
+ {
29
+ type: 'input',
30
+ name: 'inputToken',
31
+ message: 'OneSignal Organization Auth Token (add "onesignalAuthToken" to fastlane/configs.json to skip this prompt)?',
32
+ },
33
+ ]);
34
+ authToken = inputToken;
35
+ }
36
+ if (!authToken) {
37
+ return askAppIdManually();
38
+ }
39
+ const { autoCreate } = await inquirer.prompt([
40
+ {
41
+ type: 'confirm',
42
+ name: 'autoCreate',
43
+ message: `Create OneSignal app "${client}" + push certificate via fastlane now?`,
44
+ default: true,
45
+ },
46
+ ]);
47
+ if (!autoCreate) {
48
+ return askAppIdManually();
49
+ }
50
+ const { androidToken, androidGcmSenderId } = await inquirer.prompt([
51
+ {
52
+ type: 'input',
53
+ name: 'androidToken',
54
+ message: 'Android GCM key (optional)?',
55
+ },
56
+ {
57
+ type: 'input',
58
+ name: 'androidGcmSenderId',
59
+ message: 'Android GCM Sender Id (optional)?',
60
+ },
61
+ ]);
62
+ const parameters = common_1.buildKeyValuePairs(Object.assign(Object.assign({ auth_token: authToken }, (androidToken ? { android_token: androidToken } : {})), (androidGcmSenderId ? { android_gcm_sender_id: androidGcmSenderId } : {})));
63
+ // shell.exec('bundle install', { cwd: fastlaneDir } as any);
64
+ const result = shell.exec(`bundle exec fastlane sync_onesignal ${parameters.join(' ')}`, { cwd: fastlaneDir });
65
+ const output = `${result.stdout}\n${result.stderr}`;
66
+ const onesignal = parseValue(output, 'ONESIGNAL_APP_ID');
67
+ const onesignalRestApiKey = parseValue(output, 'ONESIGNAL_APP_AUTH_KEY');
68
+ if (!onesignal) {
69
+ console.warn('Could not parse OneSignal App Id from fastlane output — check the logs above and set ONESIGNAL_APP_ID manually if needed.');
70
+ }
71
+ return { onesignal, onesignalRestApiKey };
13
72
  };
@@ -1 +1 @@
1
- {"version":"0.6.72","commands":{"build":{"id":"build","description":"Build react native apps","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder build\nhello world from ./src/build.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Set client that you want to build app"},"target":{"name":"target","type":"option","char":"t","description":"Set the build target: android, ios or both","options":["android","ios","android,ios"]},"env":{"name":"env","type":"option","char":"e","description":"Set the environment: prod, staging, dev"},"branch":{"name":"branch","type":"option","char":"b","description":"Set the source branch used to build the app"},"version":{"name":"version","type":"option","char":"v","description":"Set the version number for this build"},"installr":{"name":"installr","type":"option","char":"i","description":"If enabled, the build will be uploaded to installR"},"distribute":{"name":"distribute","type":"option","char":"d","description":"Specify where to distribute app"},"firebase":{"name":"firebase","type":"boolean","char":"f","description":"If enabled, the build will be uploaded to firebase","allowNo":false},"testersIos":{"name":"testersIos","type":"option","char":"t","description":"Tester ids for iOS distribution"},"testersAndroid":{"name":"testersAndroid","type":"option","char":"u","description":"Tester ids for Android distribution"},"gitReset":{"name":"gitReset","type":"boolean","char":"g","description":"Do git reset when building","allowNo":false},"cleanup":{"name":"cleanup","type":"boolean","char":"s","description":"Do cleanup when building","allowNo":false},"groupsIos":{"name":"groupsIos","type":"option","description":"Groups ids for iOS distribution"},"groupsAndroid":{"name":"groupsAndroid","type":"option","description":"Groups ids for Android distribution"},"skipCheckVersion":{"name":"skipCheckVersion","type":"boolean","description":"Skip checking current version on stores","allowNo":false},"install":{"name":"install","type":"boolean","char":"n","description":"Install dependencies before building","allowNo":false}},"args":[{"name":"build"}]},"check-version":{"id":"check-version","description":"Check live versions","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder check-version\n Nuke certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"match-check"}]},"codepush":{"id":"codepush","description":"Push changes to existing apps","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder codepush\n Push changes to existing apps ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to push update"}},"args":[{"name":"build"}]},"google-key":{"id":"google-key","description":"Nuke certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-check\n Nuke certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"match-check"}]},"initialize":{"id":"initialize","description":"Initialize the environment for first run","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder initialize\ninitialize environment for first run from ./src/initialize.ts!\n"],"flags":{},"args":[]},"match-check":{"id":"match-check","description":"Check match certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-check\n Check match certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to check match certificates"}},"args":[{"name":"match-check"}]},"match-nuke":{"id":"match-nuke","description":"Nuke certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-nuke\n Nuke certificates ./src/match-nuke.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"build"}]},"onesignal":{"id":"onesignal","description":"Create and upload push cerfiticate to One Signal","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder onesignal\n Create and upload push certificate to One Signal from ./src/commands/onesignal.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"},"auth_token":{"name":"auth_token","type":"option","description":"Auth token for OneSignal"},"android_token":{"name":"android_token","type":"option"},"android_gcm_sender_id":{"name":"android_gcm_sender_id","type":"option"}},"args":[{"name":"build"}]},"reject-review":{"id":"reject-review","description":"Reject current App Store review version (In Review or Pending Developer Release)","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder reject-review\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client to reject App Store review version"}},"args":[{"name":"reject-review"}]},"setup-gcp":{"id":"setup-gcp","description":"Setup GCP service account impersonation","pluginName":"rnbuilder","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"setup":{"id":"setup","description":"Setup new client","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder build\nhello world from ./src/setup.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"setup"}]},"submit-review":{"id":"submit-review","description":"Submit ios for review","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder submit-review\n Push changes to existing apps ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to push update"}},"args":[{"name":"submit-review"}]},"sync-udids":{"id":"sync-udids","description":"Sync device UDIDs from firebase","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder sync-udids\n Sync device UDIDs from firebase from ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"build"}]}}}
1
+ {"version":"0.6.74","commands":{"build":{"id":"build","description":"Build react native apps","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder build\nhello world from ./src/build.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Set client that you want to build app"},"target":{"name":"target","type":"option","char":"t","description":"Set the build target: android, ios or both","options":["android","ios","android,ios"]},"env":{"name":"env","type":"option","char":"e","description":"Set the environment: prod, staging, dev"},"branch":{"name":"branch","type":"option","char":"b","description":"Set the source branch used to build the app"},"version":{"name":"version","type":"option","char":"v","description":"Set the version number for this build"},"installr":{"name":"installr","type":"option","char":"i","description":"If enabled, the build will be uploaded to installR"},"distribute":{"name":"distribute","type":"option","char":"d","description":"Specify where to distribute app"},"firebase":{"name":"firebase","type":"boolean","char":"f","description":"If enabled, the build will be uploaded to firebase","allowNo":false},"testersIos":{"name":"testersIos","type":"option","char":"t","description":"Tester ids for iOS distribution"},"testersAndroid":{"name":"testersAndroid","type":"option","char":"u","description":"Tester ids for Android distribution"},"gitReset":{"name":"gitReset","type":"boolean","char":"g","description":"Do git reset when building","allowNo":false},"cleanup":{"name":"cleanup","type":"boolean","char":"s","description":"Do cleanup when building","allowNo":false},"groupsIos":{"name":"groupsIos","type":"option","description":"Groups ids for iOS distribution"},"groupsAndroid":{"name":"groupsAndroid","type":"option","description":"Groups ids for Android distribution"},"skipCheckVersion":{"name":"skipCheckVersion","type":"boolean","description":"Skip checking current version on stores","allowNo":false},"install":{"name":"install","type":"boolean","char":"n","description":"Install dependencies before building","allowNo":false}},"args":[{"name":"build"}]},"check-version":{"id":"check-version","description":"Check live versions","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder check-version\n Nuke certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"match-check"}]},"codepush":{"id":"codepush","description":"Push changes to existing apps","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder codepush\n Push changes to existing apps ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to push update"}},"args":[{"name":"build"}]},"google-key":{"id":"google-key","description":"Nuke certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-check\n Nuke certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"match-check"}]},"initialize":{"id":"initialize","description":"Initialize the environment for first run","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder initialize\ninitialize environment for first run from ./src/initialize.ts!\n"],"flags":{},"args":[]},"match-check":{"id":"match-check","description":"Check match certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-check\n Check match certificates ./src/match-check.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to check match certificates"}},"args":[{"name":"match-check"}]},"match-nuke":{"id":"match-nuke","description":"Nuke certificates","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder match-nuke\n Nuke certificates ./src/match-nuke.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"build"}]},"onesignal":{"id":"onesignal","description":"Create and upload push cerfiticate to One Signal","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder onesignal\n Create and upload push certificate to One Signal from ./src/commands/onesignal.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"},"auth_token":{"name":"auth_token","type":"option","description":"Auth token for OneSignal"},"android_token":{"name":"android_token","type":"option"},"android_gcm_sender_id":{"name":"android_gcm_sender_id","type":"option"}},"args":[{"name":"build"}]},"reject-review":{"id":"reject-review","description":"Reject current App Store review version (In Review or Pending Developer Release)","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder reject-review\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client to reject App Store review version"}},"args":[{"name":"reject-review"}]},"setup-gcp":{"id":"setup-gcp","description":"Setup GCP service account impersonation","pluginName":"rnbuilder","pluginType":"core","aliases":[],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"setup":{"id":"setup","description":"Setup new client","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder build\nhello world from ./src/setup.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[{"name":"setup"}]},"submit-review":{"id":"submit-review","description":"Submit ios for review","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder submit-review\n Push changes to existing apps ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to push update"}},"args":[{"name":"submit-review"}]},"sync-udids":{"id":"sync-udids","description":"Sync device UDIDs from firebase","pluginName":"rnbuilder","pluginType":"core","aliases":[],"examples":["$ rnbuilder sync-udids\n Sync device UDIDs from firebase from ./src/firebase-sync-udids.ts!\n"],"flags":{"help":{"name":"help","type":"boolean","char":"h","description":"show CLI help","allowNo":false},"client":{"name":"client","type":"option","char":"c","description":"Select client that you want to sync udids"}},"args":[{"name":"build"}]}}}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rnbuilder",
3
3
  "description": "React Native builder tool",
4
- "version": "0.6.72",
4
+ "version": "0.6.74",
5
5
  "author": "Tuan Luong @r0b0t3d",
6
6
  "bin": "./bin/run",
7
7
  "bugs": "https://github.com/r0b0t3d/rnbuilder/issues",