rnbuilder 0.6.72 → 0.6.73
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 +14 -14
- package/lib/commands/setup.js +27 -9
- package/lib/utils/setup/android-icon.d.ts +4 -0
- package/lib/utils/setup/android-icon.js +101 -0
- package/lib/utils/setup/app-icon.d.ts +1 -1
- package/lib/utils/setup/app-icon.js +6 -8
- package/lib/utils/setup/apple.d.ts +7 -1
- package/lib/utils/setup/apple.js +54 -7
- package/lib/utils/setup/launch-screen.js +8 -8
- package/lib/utils/setup/onesignal.d.ts +7 -3
- package/lib/utils/setup/onesignal.js +61 -2
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
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.
|
|
43
|
+
rnbuilder/0.6.73 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.
|
|
101
|
+
_See code: [src/commands/build.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
120
|
+
_See code: [src/commands/check-version.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
139
|
+
_See code: [src/commands/codepush.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
158
|
+
_See code: [src/commands/google-key.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
190
|
+
_See code: [src/commands/initialize.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
209
|
+
_See code: [src/commands/match-check.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
228
|
+
_See code: [src/commands/match-nuke.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
250
|
+
_See code: [src/commands/onesignal.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
268
|
+
_See code: [src/commands/reject-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
286
|
+
_See code: [src/commands/setup.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
300
|
+
_See code: [src/commands/setup-gcp.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
319
|
+
_See code: [src/commands/submit-review.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/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.
|
|
338
|
+
_See code: [src/commands/sync-udids.ts](https://github.com/r0b0t3d/rnbuilder/blob/v0.6.73/src/commands/sync-udids.ts)_
|
|
339
339
|
<!-- commandsstop -->
|
package/lib/commands/setup.js
CHANGED
|
@@ -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
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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',
|
|
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;
|
|
@@ -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;
|
|
@@ -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
|
-
|
|
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(
|
|
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
|
};
|
package/lib/utils/setup/apple.js
CHANGED
|
@@ -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
|
-
|
|
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
|
};
|
|
@@ -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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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: (
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
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
|
};
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.6.
|
|
1
|
+
{"version":"0.6.73","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"}]}}}
|