rnbuilder 0.6.69 → 0.6.70

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
@@ -22,7 +22,7 @@ $ npm install -g rnbuilder
22
22
  $ rnbuilder COMMAND
23
23
  running command...
24
24
  $ rnbuilder (-v|--version|version)
25
- rnbuilder/0.6.69 darwin-arm64 node-v24.13.0
25
+ rnbuilder/0.6.70 darwin-arm64 node-v24.13.0
26
26
  $ rnbuilder --help [COMMAND]
27
27
  USAGE
28
28
  $ rnbuilder COMMAND
@@ -79,7 +79,7 @@ EXAMPLE
79
79
  hello world from ./src/build.ts!
80
80
  ```
81
81
 
82
- _See code: [src/commands/build.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/build.ts)_
82
+ _See code: [src/commands/build.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/build.ts)_
83
83
 
84
84
  ## `rnbuilder check-version [MATCH-CHECK]`
85
85
 
@@ -98,7 +98,7 @@ EXAMPLE
98
98
  Nuke certificates ./src/match-check.ts!
99
99
  ```
100
100
 
101
- _See code: [src/commands/check-version.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/check-version.ts)_
101
+ _See code: [src/commands/check-version.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/check-version.ts)_
102
102
 
103
103
  ## `rnbuilder codepush [BUILD]`
104
104
 
@@ -117,7 +117,7 @@ EXAMPLE
117
117
  Push changes to existing apps ./src/firebase-sync-udids.ts!
118
118
  ```
119
119
 
120
- _See code: [src/commands/codepush.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/codepush.ts)_
120
+ _See code: [src/commands/codepush.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/codepush.ts)_
121
121
 
122
122
  ## `rnbuilder google-key [MATCH-CHECK]`
123
123
 
@@ -136,7 +136,7 @@ EXAMPLE
136
136
  Nuke certificates ./src/match-check.ts!
137
137
  ```
138
138
 
139
- _See code: [src/commands/google-key.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/google-key.ts)_
139
+ _See code: [src/commands/google-key.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/google-key.ts)_
140
140
 
141
141
  ## `rnbuilder help [COMMAND]`
142
142
 
@@ -168,7 +168,7 @@ EXAMPLE
168
168
  initialize environment for first run from ./src/initialize.ts!
169
169
  ```
170
170
 
171
- _See code: [src/commands/initialize.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/initialize.ts)_
171
+ _See code: [src/commands/initialize.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/initialize.ts)_
172
172
 
173
173
  ## `rnbuilder match-check [MATCH-CHECK]`
174
174
 
@@ -187,7 +187,7 @@ EXAMPLE
187
187
  Check match certificates ./src/match-check.ts!
188
188
  ```
189
189
 
190
- _See code: [src/commands/match-check.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/match-check.ts)_
190
+ _See code: [src/commands/match-check.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/match-check.ts)_
191
191
 
192
192
  ## `rnbuilder match-nuke [BUILD]`
193
193
 
@@ -206,7 +206,7 @@ EXAMPLE
206
206
  Nuke certificates ./src/match-nuke.ts!
207
207
  ```
208
208
 
209
- _See code: [src/commands/match-nuke.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/match-nuke.ts)_
209
+ _See code: [src/commands/match-nuke.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/match-nuke.ts)_
210
210
 
211
211
  ## `rnbuilder onesignal [BUILD]`
212
212
 
@@ -228,7 +228,7 @@ EXAMPLE
228
228
  Create and upload push certificate to One Signal from ./src/commands/onesignal.ts!
229
229
  ```
230
230
 
231
- _See code: [src/commands/onesignal.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/onesignal.ts)_
231
+ _See code: [src/commands/onesignal.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/onesignal.ts)_
232
232
 
233
233
  ## `rnbuilder reject-review [REJECT-REVIEW]`
234
234
 
@@ -246,7 +246,7 @@ EXAMPLE
246
246
  $ rnbuilder reject-review
247
247
  ```
248
248
 
249
- _See code: [src/commands/reject-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/reject-review.ts)_
249
+ _See code: [src/commands/reject-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/reject-review.ts)_
250
250
 
251
251
  ## `rnbuilder setup [SETUP]`
252
252
 
@@ -264,7 +264,7 @@ EXAMPLE
264
264
  hello world from ./src/setup.ts!
265
265
  ```
266
266
 
267
- _See code: [src/commands/setup.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/setup.ts)_
267
+ _See code: [src/commands/setup.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/setup.ts)_
268
268
 
269
269
  ## `rnbuilder submit-review [SUBMIT-REVIEW]`
270
270
 
@@ -283,7 +283,7 @@ EXAMPLE
283
283
  Push changes to existing apps ./src/firebase-sync-udids.ts!
284
284
  ```
285
285
 
286
- _See code: [src/commands/submit-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/submit-review.ts)_
286
+ _See code: [src/commands/submit-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/submit-review.ts)_
287
287
 
288
288
  ## `rnbuilder sync-udids [BUILD]`
289
289
 
@@ -302,5 +302,5 @@ EXAMPLE
302
302
  Sync device UDIDs from firebase from ./src/firebase-sync-udids.ts!
303
303
  ```
304
304
 
305
- _See code: [src/commands/sync-udids.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.69/src/commands/sync-udids.ts)_
305
+ _See code: [src/commands/sync-udids.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.70/src/commands/sync-udids.ts)_
306
306
  <!-- commandsstop -->
@@ -99,6 +99,9 @@ class Setup extends command_1.Command {
99
99
  // Setup fastlane
100
100
  const { firebaseIosApp, firebaseAndroidApp } = await fastlane_1.setupFastlane({
101
101
  client,
102
+ bundleId,
103
+ applicationId,
104
+ appName,
102
105
  });
103
106
  const fastlaneDir = path.join(process.cwd(), `fastlane/clients/${client}/fastlane`);
104
107
  const fastlaneEnvVars = env_1.readEnvVars(path.join(fastlaneDir, '/.env'));
@@ -0,0 +1,4 @@
1
+ export declare function addProductFlavor({ client, applicationId, }: {
2
+ client: string;
3
+ applicationId: string;
4
+ }): void;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addProductFlavor = void 0;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ function insertIntoProductFlavors(gradle, flavor) {
7
+ // Find productFlavors block and insert before its closing brace
8
+ const blockStart = gradle.indexOf('productFlavors {');
9
+ if (blockStart === -1) {
10
+ // No productFlavors block — append one inside android {}
11
+ const androidEnd = gradle.lastIndexOf('}');
12
+ return (gradle.slice(0, androidEnd) +
13
+ `\n productFlavors {\n${flavor}\n }\n` +
14
+ gradle.slice(androidEnd));
15
+ }
16
+ // Walk forward matching braces to find closing }
17
+ let depth = 0;
18
+ let i = blockStart;
19
+ while (i < gradle.length) {
20
+ if (gradle[i] === '{')
21
+ depth++;
22
+ else if (gradle[i] === '}') {
23
+ depth--;
24
+ if (depth === 0)
25
+ break;
26
+ }
27
+ i++;
28
+ }
29
+ return gradle.slice(0, i) + '\n' + flavor + '\n' + gradle.slice(i);
30
+ }
31
+ function addProductFlavor({ client, applicationId, }) {
32
+ const gradlePath = path.join(process.cwd(), 'android/app/build.gradle');
33
+ if (!fs.existsSync(gradlePath)) {
34
+ console.warn(`build.gradle not found at ${gradlePath} — skipping`);
35
+ return;
36
+ }
37
+ const gradle = fs.readFileSync(gradlePath, 'utf-8');
38
+ // Already has this flavor
39
+ const flavorRegex = new RegExp(`\\b${client}\\s*\\{`);
40
+ if (flavorRegex.test(gradle)) {
41
+ console.log(`Flavor "${client}" already exists in build.gradle — skipping`);
42
+ return;
43
+ }
44
+ const flavorBlock = ` ${client} {\n` +
45
+ ` dimension "default"\n` +
46
+ ` applicationId "${applicationId}"\n` +
47
+ ` }`;
48
+ const updated = insertIntoProductFlavors(gradle, flavorBlock);
49
+ fs.writeFileSync(gradlePath, updated, 'utf-8');
50
+ console.log(`Added flavor "${client}" to android/app/build.gradle`);
51
+ }
52
+ exports.addProductFlavor = addProductFlavor;
@@ -1,3 +1,5 @@
1
- export declare const createClientConfig: (client: string) => Promise<any> & {
2
- ui: import("inquirer/lib/ui/prompt");
3
- };
1
+ export declare const createClientConfig: (client: string) => Promise<{
2
+ appName: any;
3
+ bundleId: any;
4
+ applicationId: any;
5
+ }>;
@@ -2,18 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createClientConfig = void 0;
4
4
  const inquirer = require("inquirer");
5
- exports.createClientConfig = (client) => {
6
- return inquirer.prompt([
7
- {
8
- type: 'confirm',
9
- name: 'android-client',
10
- message: `Please add **${client}** to **productFlavors** in android>app>build.gradle`,
11
- },
12
- {
13
- type: 'confirm',
14
- name: 'ios-client',
15
- message: `Please add **${client} prod** scheme and config Pre actions`,
16
- },
5
+ const android_1 = require("./android");
6
+ const ios_scheme_1 = require("./ios-scheme");
7
+ exports.createClientConfig = async (client) => {
8
+ const { appName, bundleId, applicationId } = await inquirer.prompt([
17
9
  {
18
10
  type: 'input',
19
11
  name: 'appName',
@@ -28,8 +20,11 @@ exports.createClientConfig = (client) => {
28
20
  {
29
21
  type: 'input',
30
22
  name: 'applicationId',
31
- message: 'What is application id (this is for android in case you need difference id for platforms)?',
23
+ message: 'What is application id (android, if different from bundle id)?',
32
24
  default: `com.edular.${client}`,
33
25
  },
34
26
  ]);
27
+ android_1.addProductFlavor({ client, applicationId });
28
+ ios_scheme_1.createXcodeScheme({ client, bundleId });
29
+ return { appName, bundleId, applicationId };
35
30
  };
@@ -1,4 +1,9 @@
1
- export declare const setupFastlane: ({ client }: any) => Promise<{
1
+ export declare const setupFastlane: ({ client, bundleId, applicationId, appName, }: {
2
+ client: string;
3
+ bundleId?: string | undefined;
4
+ applicationId?: string | undefined;
5
+ appName?: string | undefined;
6
+ }) => Promise<{
2
7
  firebaseIosApp: string;
3
8
  firebaseAndroidApp: string;
4
9
  }>;
@@ -4,28 +4,19 @@ exports.setupFastlane = void 0;
4
4
  const common_1 = require("../common");
5
5
  const path = require("path");
6
6
  const inquirer = require("inquirer");
7
- exports.setupFastlane = async ({ client }) => {
7
+ const firebase_1 = require("./firebase");
8
+ exports.setupFastlane = async ({ client, bundleId, applicationId, appName, }) => {
8
9
  const clientDir = path.join(process.cwd(), `fastlane/clients/${client}`);
9
10
  const fastlaneDir = path.join(clientDir, 'fastlane');
10
11
  if (!common_1.exists(fastlaneDir)) {
11
- // Copy template folders
12
12
  await common_1.copyDir(path.join(process.cwd(), 'template/fastlane'), fastlaneDir);
13
13
  }
14
- const { firebaseServiceAccountFile, firebaseIosApp, firebaseAndroidApp, jsonKeyFile, } = await inquirer.prompt([
14
+ const { firebaseServiceAccountFile, jsonKeyFile } = await inquirer.prompt([
15
15
  {
16
16
  type: 'input',
17
17
  name: 'firebaseServiceAccountFile',
18
18
  message: 'Firebase Service Account file?',
19
- },
20
- {
21
- type: 'input',
22
- name: 'firebaseIosApp',
23
- message: 'What is Firebase iOS App Id?',
24
- },
25
- {
26
- type: 'input',
27
- name: 'firebaseAndroidApp',
28
- message: 'What is Firebase Android App Id?',
19
+ default: process.env.FIREBASE_SERVICE_ACCOUNT_FILE,
29
20
  },
30
21
  {
31
22
  type: 'input',
@@ -33,6 +24,78 @@ exports.setupFastlane = async ({ client }) => {
33
24
  message: 'Path to Google json file? See https://docs.fastlane.tools/actions/supply/#setup',
34
25
  },
35
26
  ]);
27
+ let firebaseIosApp = '';
28
+ let firebaseAndroidApp = '';
29
+ const resolvedServiceAccount = common_1.normalise(firebaseServiceAccountFile) ||
30
+ process.env.FIREBASE_SERVICE_ACCOUNT_FILE;
31
+ if (resolvedServiceAccount) {
32
+ const { autoCreate } = await inquirer.prompt([
33
+ {
34
+ type: 'confirm',
35
+ name: 'autoCreate',
36
+ message: 'Auto-create Firebase apps?',
37
+ default: true,
38
+ },
39
+ ]);
40
+ if (autoCreate) {
41
+ const accessToken = await firebase_1.getAccessToken(resolvedServiceAccount);
42
+ const projectId = firebase_1.getProjectId(resolvedServiceAccount);
43
+ const displayName = appName || client;
44
+ console.log(`Creating Firebase apps in project ${projectId}...`);
45
+ const [iosAppId, androidAppId] = await Promise.all([
46
+ firebase_1.createFirebaseApp({
47
+ accessToken,
48
+ projectId,
49
+ platform: 'ios',
50
+ bundleId,
51
+ displayName,
52
+ }),
53
+ firebase_1.createFirebaseApp({
54
+ accessToken,
55
+ projectId,
56
+ platform: 'android',
57
+ packageName: applicationId,
58
+ displayName,
59
+ }),
60
+ ]);
61
+ firebaseIosApp = iosAppId;
62
+ firebaseAndroidApp = androidAppId;
63
+ console.log(`Firebase iOS App ID: ${iosAppId}`);
64
+ console.log(`Firebase Android App ID: ${androidAppId}`);
65
+ }
66
+ else {
67
+ const result = await inquirer.prompt([
68
+ {
69
+ type: 'input',
70
+ name: 'firebaseIosApp',
71
+ message: 'What is Firebase iOS App Id?',
72
+ },
73
+ {
74
+ type: 'input',
75
+ name: 'firebaseAndroidApp',
76
+ message: 'What is Firebase Android App Id?',
77
+ },
78
+ ]);
79
+ firebaseIosApp = result.firebaseIosApp;
80
+ firebaseAndroidApp = result.firebaseAndroidApp;
81
+ }
82
+ }
83
+ else {
84
+ const result = await inquirer.prompt([
85
+ {
86
+ type: 'input',
87
+ name: 'firebaseIosApp',
88
+ message: 'What is Firebase iOS App Id?',
89
+ },
90
+ {
91
+ type: 'input',
92
+ name: 'firebaseAndroidApp',
93
+ message: 'What is Firebase Android App Id?',
94
+ },
95
+ ]);
96
+ firebaseIosApp = result.firebaseIosApp;
97
+ firebaseAndroidApp = result.firebaseAndroidApp;
98
+ }
36
99
  if (firebaseServiceAccountFile) {
37
100
  await common_1.copyFile(common_1.normalise(firebaseServiceAccountFile), path.join(fastlaneDir, 'firebase.json'));
38
101
  }
@@ -40,7 +103,7 @@ exports.setupFastlane = async ({ client }) => {
40
103
  await common_1.copyFile(common_1.normalise(jsonKeyFile), path.join(clientDir, 'key.json'));
41
104
  }
42
105
  return {
43
- firebaseIosApp: common_1.normalise(firebaseIosApp),
44
- firebaseAndroidApp: common_1.normalise(firebaseAndroidApp),
106
+ firebaseIosApp,
107
+ firebaseAndroidApp,
45
108
  };
46
109
  };
@@ -0,0 +1,10 @@
1
+ export declare function getProjectId(serviceAccountPath: string): string;
2
+ export declare function getAccessToken(serviceAccountPath: string): Promise<string>;
3
+ export declare function createFirebaseApp({ accessToken, projectId, platform, bundleId, packageName, displayName, }: {
4
+ accessToken: string;
5
+ projectId: string;
6
+ platform: 'ios' | 'android';
7
+ bundleId?: string;
8
+ packageName?: string;
9
+ displayName: string;
10
+ }): Promise<string>;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createFirebaseApp = exports.getAccessToken = exports.getProjectId = void 0;
4
+ const crypto = require("crypto");
5
+ const fs = require("fs");
6
+ const https = require("https");
7
+ function base64url(input) {
8
+ const buf = typeof input === 'string' ? Buffer.from(input) : input;
9
+ return buf
10
+ .toString('base64')
11
+ .replace(/=/g, '')
12
+ .replace(/\+/g, '-')
13
+ .replace(/\//g, '_');
14
+ }
15
+ function createJWT(serviceAccount) {
16
+ const now = Math.floor(Date.now() / 1000);
17
+ const header = base64url(JSON.stringify({ alg: 'RS256', typ: 'JWT' }));
18
+ const payload = base64url(JSON.stringify({
19
+ iss: serviceAccount.client_email,
20
+ scope: 'https://www.googleapis.com/auth/cloud-platform',
21
+ aud: 'https://oauth2.googleapis.com/token',
22
+ iat: now,
23
+ exp: now + 3600,
24
+ }));
25
+ const data = `${header}.${payload}`;
26
+ const sign = crypto.createSign('RSA-SHA256');
27
+ sign.update(data);
28
+ return `${data}.${base64url(sign.sign(serviceAccount.private_key))}`;
29
+ }
30
+ function httpsRequest(url, method, headers, body) {
31
+ return new Promise((resolve, reject) => {
32
+ const { hostname, pathname, search } = new URL(url);
33
+ const req = https.request({
34
+ hostname,
35
+ path: pathname + search,
36
+ method,
37
+ headers: body
38
+ ? Object.assign(Object.assign({}, headers), { 'Content-Length': Buffer.byteLength(body) }) : headers,
39
+ }, res => {
40
+ let raw = '';
41
+ res.on('data', chunk => (raw += chunk));
42
+ res.on('end', () => {
43
+ try {
44
+ resolve(JSON.parse(raw));
45
+ }
46
+ catch (_a) {
47
+ resolve(raw);
48
+ }
49
+ });
50
+ });
51
+ req.on('error', reject);
52
+ if (body)
53
+ req.write(body);
54
+ req.end();
55
+ });
56
+ }
57
+ function sleep(ms) {
58
+ return new Promise(r => setTimeout(r, ms));
59
+ }
60
+ async function pollOperation(operationName, accessToken) {
61
+ const url = `https://firebase.googleapis.com/v1beta1/${operationName}`;
62
+ for (let i = 0; i < 20; i++) {
63
+ await sleep(3000);
64
+ const op = await httpsRequest(url, 'GET', {
65
+ Authorization: `Bearer ${accessToken}`,
66
+ });
67
+ if (op.done) {
68
+ if (op.error)
69
+ throw new Error(`Firebase app creation failed: ${JSON.stringify(op.error)}`);
70
+ return op.response.appId;
71
+ }
72
+ }
73
+ throw new Error('Firebase app creation timed out after 60s');
74
+ }
75
+ function getProjectId(serviceAccountPath) {
76
+ const sa = JSON.parse(fs.readFileSync(serviceAccountPath, 'utf-8'));
77
+ return sa.project_id;
78
+ }
79
+ exports.getProjectId = getProjectId;
80
+ async function getAccessToken(serviceAccountPath) {
81
+ const sa = JSON.parse(fs.readFileSync(serviceAccountPath, 'utf-8'));
82
+ const jwt = createJWT(sa);
83
+ const body = new URLSearchParams({
84
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
85
+ assertion: jwt,
86
+ }).toString();
87
+ const result = await httpsRequest('https://oauth2.googleapis.com/token', 'POST', { 'Content-Type': 'application/x-www-form-urlencoded' }, body);
88
+ if (!result.access_token)
89
+ throw new Error(`Auth failed: ${JSON.stringify(result)}`);
90
+ return result.access_token;
91
+ }
92
+ exports.getAccessToken = getAccessToken;
93
+ async function createFirebaseApp({ accessToken, projectId, platform, bundleId, packageName, displayName, }) {
94
+ const endpoint = platform === 'ios' ? 'iosApps' : 'androidApps';
95
+ const payload = platform === 'ios'
96
+ ? { bundleId, displayName }
97
+ : { packageName, displayName };
98
+ const result = await httpsRequest(`https://firebase.googleapis.com/v1beta1/projects/${projectId}/${endpoint}`, 'POST', {
99
+ Authorization: `Bearer ${accessToken}`,
100
+ 'Content-Type': 'application/json',
101
+ }, JSON.stringify(payload));
102
+ if (result.error)
103
+ throw new Error(`Firebase API error: ${JSON.stringify(result.error)}`);
104
+ if (result.done)
105
+ return result.response.appId;
106
+ if (result.name)
107
+ return pollOperation(result.name, accessToken);
108
+ throw new Error(`Unexpected response: ${JSON.stringify(result)}`);
109
+ }
110
+ exports.createFirebaseApp = createFirebaseApp;
@@ -0,0 +1,4 @@
1
+ export declare function createXcodeScheme({ client, }: {
2
+ client: string;
3
+ bundleId: string;
4
+ }): void;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createXcodeScheme = void 0;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ function findSchemeDir() {
7
+ const iosDir = path.join(process.cwd(), 'ios');
8
+ if (!fs.existsSync(iosDir))
9
+ return null;
10
+ for (const entry of fs.readdirSync(iosDir)) {
11
+ if (!entry.endsWith('.xcodeproj'))
12
+ continue;
13
+ const candidate = path.join(iosDir, entry, 'xcshareddata', 'xcschemes');
14
+ if (fs.existsSync(candidate))
15
+ return candidate;
16
+ }
17
+ return null;
18
+ }
19
+ function findExistingProdScheme(schemeDir) {
20
+ const files = fs
21
+ .readdirSync(schemeDir)
22
+ .filter(f => f.endsWith(' prod.xcscheme'));
23
+ return files.length > 0 ? path.join(schemeDir, files[0]) : null;
24
+ }
25
+ function extractClientFromFilename(filename) {
26
+ return path.basename(filename, '.xcscheme').replace(/ prod$/, '');
27
+ }
28
+ function createXcodeScheme({ client, }) {
29
+ const schemeDir = findSchemeDir();
30
+ if (!schemeDir) {
31
+ console.warn('Could not find xcshareddata/xcschemes — add iOS scheme manually');
32
+ return;
33
+ }
34
+ const targetScheme = path.join(schemeDir, `${client} prod.xcscheme`);
35
+ if (fs.existsSync(targetScheme)) {
36
+ console.log(`Scheme "${client} prod" already exists — skipping`);
37
+ return;
38
+ }
39
+ const sourceScheme = findExistingProdScheme(schemeDir);
40
+ if (!sourceScheme) {
41
+ console.warn('No existing "*prod.xcscheme" found to copy from — add iOS scheme manually');
42
+ return;
43
+ }
44
+ const oldClient = extractClientFromFilename(sourceScheme);
45
+ let xml = fs.readFileSync(sourceScheme, 'utf-8');
46
+ // Replace all occurrences of old client name — covers BuildableName,
47
+ // BlueprintName, and pre-action script paths like configs/oldclient/.env.*
48
+ xml = xml.split(oldClient).join(client);
49
+ fs.writeFileSync(targetScheme, xml, 'utf-8');
50
+ console.log(`Created iOS scheme "${client} prod" from "${path.basename(sourceScheme)}"`);
51
+ }
52
+ exports.createXcodeScheme = createXcodeScheme;
@@ -1 +1 @@
1
- {"version":"0.6.69","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":{"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.70","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":{"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.69",
4
+ "version": "0.6.70",
5
5
  "author": "Tuan Luong @r0b0t3d",
6
6
  "bin": "./bin/run",
7
7
  "bugs": "https://github.com/r0b0t3d/rnbuilder/issues",