react-native-bootsplash 6.0.0-beta.9 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/generate.ts CHANGED
@@ -1,8 +1,4 @@
1
- import { getConfig as getExpoConfig } from "@expo/config";
2
1
  import * as Expo from "@expo/config-plugins";
3
- import { assignColorValue } from "@expo/config-plugins/build/android/Colors";
4
- import { addImports } from "@expo/config-plugins/build/android/codeMod";
5
- import { mergeContents } from "@expo/config-plugins/build/utils/generateCode";
6
2
  import plist from "@expo/plist";
7
3
  import { findProjectRoot } from "@react-native-community/cli-tools";
8
4
  import {
@@ -20,6 +16,7 @@ import { Options as PrettierOptions } from "prettier";
20
16
  import * as htmlPlugin from "prettier/plugins/html";
21
17
  import * as cssPlugin from "prettier/plugins/postcss";
22
18
  import * as prettier from "prettier/standalone";
19
+ import semver from "semver";
23
20
  import sharp, { Sharp } from "sharp";
24
21
  import { dedent } from "ts-dedent";
25
22
  import util from "util";
@@ -29,6 +26,7 @@ import { Manifest } from ".";
29
26
  const workingPath = process.env.INIT_CWD ?? process.env.PWD ?? process.cwd();
30
27
  const projectRoot = findProjectRoot(workingPath);
31
28
 
29
+ type ProjectType = "detect" | "bare" | "expo";
32
30
  type Platforms = ("android" | "ios" | "web")[];
33
31
 
34
32
  export type RGBColor = {
@@ -187,6 +185,25 @@ export const hfs = {
187
185
  },
188
186
  };
189
187
 
188
+ export const getExpoConfig = (projectRoot: string): { isExpo: boolean } => {
189
+ try {
190
+ const pkg = hfs.json(
191
+ path.resolve(projectRoot, "node_modules", "expo", "package.json"),
192
+ ) as { version?: string };
193
+
194
+ const version = pkg.version;
195
+
196
+ if (version == null || semver.lt(version, "51.0.20")) {
197
+ log.error("Requires Expo 51.0.20 (or higher)");
198
+ process.exit(1);
199
+ }
200
+
201
+ return { isExpo: true };
202
+ } catch {
203
+ return { isExpo: false };
204
+ }
205
+ };
206
+
190
207
  export const writeJson = (filePath: string, content: object) => {
191
208
  hfs.write(filePath, JSON.stringify(content, null, 2));
192
209
  log.write(filePath);
@@ -263,7 +280,7 @@ export const writeXmlLike = async (
263
280
  }
264
281
  };
265
282
 
266
- const cleanIOS = (dir: string) => {
283
+ export const cleanIOSAssets = (dir: string) => {
267
284
  hfs
268
285
  .readDir(dir)
269
286
  .filter((file) => file === "Colors.xcassets" || file === "Images.xcassets")
@@ -568,6 +585,7 @@ const requireAddon = ():
568
585
  export const generate = async ({
569
586
  android,
570
587
  ios,
588
+ projectType,
571
589
  platforms,
572
590
  html,
573
591
  flavor,
@@ -578,6 +596,7 @@ export const generate = async ({
578
596
  ios?: IOSProjectConfig;
579
597
 
580
598
  logo: string;
599
+ projectType: ProjectType;
581
600
  platforms: Platforms;
582
601
  background: string;
583
602
  logoWidth: number;
@@ -593,13 +612,11 @@ export const generate = async ({
593
612
  darkBrand?: string;
594
613
  }) => {
595
614
  const isExpo =
596
- getExpoConfig(projectRoot, { skipSDKVersionRequirement: true }).exp
597
- .sdkVersion != null;
598
-
599
- const [nodeStringVersion = ""] = process.versions.node.split(".");
600
- const nodeVersion = Number.parseInt(nodeStringVersion, 10);
615
+ projectType === "detect" || projectType === "expo"
616
+ ? getExpoConfig(workingPath).isExpo
617
+ : false;
601
618
 
602
- if (!Number.isNaN(nodeVersion) && nodeVersion < 18) {
619
+ if (semver.lt(process.versions.node, "18.0.0")) {
603
620
  log.error("Requires Node 18 (or higher)");
604
621
  process.exit(1);
605
622
  }
@@ -897,7 +914,7 @@ export const generate = async ({
897
914
  log.title("šŸ", "iOS");
898
915
 
899
916
  hfs.ensureDir(iosOutputPath);
900
- cleanIOS(iosOutputPath);
917
+ cleanIOSAssets(iosOutputPath);
901
918
 
902
919
  const storyboardPath = path.resolve(iosOutputPath, "BootSplash.storyboard");
903
920
 
@@ -1199,345 +1216,3 @@ ${pc.blue("┗━━━━━━━━━━━━━━━━━━━━━━
1199
1216
  `\nšŸ’– Thanks for using ${pc.underline("react-native-bootsplash")}`,
1200
1217
  );
1201
1218
  };
1202
-
1203
- type ExpoPlugin = Expo.ConfigPlugin<{
1204
- assetsDir?: string;
1205
- android?: {
1206
- parentTheme?: "TransparentStatus" | "EdgeToEdge";
1207
- darkContentBarsStyle?: boolean;
1208
- };
1209
- }>;
1210
-
1211
- const withAndroidAssets: ExpoPlugin = (config, props) =>
1212
- Expo.withDangerousMod(config, [
1213
- "android",
1214
- (config) => {
1215
- const { assetsDir = "assets/bootsplash" } = props;
1216
- const { platformProjectRoot } = config.modRequest;
1217
-
1218
- const srcDir = path.resolve(workingPath, assetsDir, "android");
1219
-
1220
- const destDir = path.resolve(
1221
- platformProjectRoot,
1222
- "app",
1223
- "src",
1224
- "main",
1225
- "res",
1226
- );
1227
-
1228
- for (const drawableDir of hfs.readDir(srcDir)) {
1229
- const srcDrawableDir = path.join(srcDir, drawableDir);
1230
- const destDrawableDir = path.join(destDir, drawableDir);
1231
-
1232
- hfs.ensureDir(destDrawableDir);
1233
-
1234
- for (const file of hfs.readDir(srcDrawableDir)) {
1235
- hfs.copy(
1236
- path.join(srcDrawableDir, file),
1237
- path.join(destDrawableDir, file),
1238
- );
1239
- }
1240
- }
1241
-
1242
- return config;
1243
- },
1244
- ]);
1245
-
1246
- const withAndroidManifest: ExpoPlugin = (config) =>
1247
- Expo.withAndroidManifest(config, (config) => {
1248
- config.modResults.manifest.application?.forEach((application) => {
1249
- if (application.$["android:name"] === ".MainApplication") {
1250
- const { activity } = application;
1251
-
1252
- activity?.forEach((activity) => {
1253
- if (activity.$["android:name"] === ".MainActivity") {
1254
- activity.$["android:theme"] = "@style/BootTheme";
1255
- }
1256
- });
1257
- }
1258
- });
1259
-
1260
- return config;
1261
- });
1262
-
1263
- const withMainActivity: ExpoPlugin = (config) =>
1264
- Expo.withMainActivity(config, (config) => {
1265
- const { modResults } = config;
1266
- const { language } = modResults;
1267
-
1268
- const withImports = addImports(
1269
- modResults.contents.replace(
1270
- /(\/\/ )?setTheme\(R\.style\.AppTheme\)/,
1271
- "// setTheme(R.style.AppTheme)",
1272
- ),
1273
- ["android.os.Bundle", "com.zoontek.rnbootsplash.RNBootSplash"],
1274
- language === "java",
1275
- );
1276
-
1277
- // indented with 4 spaces
1278
- const withInit = mergeContents({
1279
- src: withImports,
1280
- comment: " //",
1281
- tag: "bootsplash-init",
1282
- offset: 0,
1283
- anchor: /super\.onCreate\(null\)/,
1284
- newSrc:
1285
- " RNBootSplash.init(this, R.style.BootTheme)" +
1286
- (language === "java" ? ";" : ""),
1287
- });
1288
-
1289
- return {
1290
- ...config,
1291
- modResults: {
1292
- ...modResults,
1293
- contents: withInit.contents,
1294
- },
1295
- };
1296
- });
1297
-
1298
- const withAndroidStyles: ExpoPlugin = (config, props) =>
1299
- Expo.withAndroidStyles(config, async (config) => {
1300
- const { assetsDir = "assets/bootsplash", android = {} } = props;
1301
- const { parentTheme, darkContentBarsStyle } = android;
1302
-
1303
- const { modResults } = config;
1304
- const { resources } = modResults;
1305
- const { style = [] } = resources;
1306
-
1307
- const manifest = (await hfs.json(
1308
- path.resolve(workingPath, assetsDir, "manifest.json"),
1309
- )) as Manifest;
1310
-
1311
- const item = [
1312
- {
1313
- $: { name: "postBootSplashTheme" },
1314
- _: "@style/AppTheme",
1315
- },
1316
- {
1317
- $: { name: "bootSplashBackground" },
1318
- _: "@color/bootsplash_background",
1319
- },
1320
- {
1321
- $: { name: "bootSplashLogo" },
1322
- _: "@drawable/bootsplash_logo",
1323
- },
1324
- ];
1325
-
1326
- if (manifest.brand != null) {
1327
- item.push({
1328
- $: { name: "bootSplashBrand" },
1329
- _: "@drawable/bootsplash_brand",
1330
- });
1331
- }
1332
- if (darkContentBarsStyle != null) {
1333
- item.push({
1334
- $: { name: "darkContentBarsStyle" },
1335
- _: String(darkContentBarsStyle),
1336
- });
1337
- }
1338
-
1339
- const withBootTheme = [
1340
- ...style.filter(({ $ }) => $.name !== "BootTheme"),
1341
- {
1342
- $: {
1343
- name: "BootTheme",
1344
- parent:
1345
- parentTheme === "TransparentStatus"
1346
- ? "Theme.BootSplash.TransparentStatus"
1347
- : parentTheme === "EdgeToEdge"
1348
- ? "Theme.BootSplash.EdgeToEdge"
1349
- : "Theme.BootSplash",
1350
- },
1351
- item,
1352
- },
1353
- ];
1354
-
1355
- return {
1356
- ...config,
1357
- modResults: {
1358
- ...modResults,
1359
- resources: {
1360
- ...resources,
1361
- style: withBootTheme,
1362
- },
1363
- },
1364
- };
1365
- });
1366
-
1367
- const withAndroidColors: ExpoPlugin = (config, props) =>
1368
- Expo.withAndroidColors(config, async (config) => {
1369
- const { assetsDir = "assets/bootsplash" } = props;
1370
-
1371
- const manifest = (await hfs.json(
1372
- path.resolve(workingPath, assetsDir, "manifest.json"),
1373
- )) as Manifest;
1374
-
1375
- config.modResults = assignColorValue(config.modResults, {
1376
- name: "bootsplash_background",
1377
- value: manifest.background,
1378
- });
1379
-
1380
- return config;
1381
- });
1382
-
1383
- const withAndroidColorsNight: ExpoPlugin = (config, props) =>
1384
- Expo.withAndroidColorsNight(config, async (config) => {
1385
- const { assetsDir = "assets/bootsplash" } = props;
1386
-
1387
- const manifest = (await hfs.json(
1388
- path.resolve(workingPath, assetsDir, "manifest.json"),
1389
- )) as Manifest;
1390
-
1391
- if (manifest.darkBackground != null) {
1392
- config.modResults = assignColorValue(config.modResults, {
1393
- name: "bootsplash_background",
1394
- value: manifest.darkBackground,
1395
- });
1396
- }
1397
-
1398
- return config;
1399
- });
1400
-
1401
- const withIOSAssets: ExpoPlugin = (config, props) =>
1402
- Expo.withDangerousMod(config, [
1403
- "ios",
1404
- (config) => {
1405
- const { assetsDir = "assets/bootsplash" } = props;
1406
- const { platformProjectRoot, projectName = "" } = config.modRequest;
1407
-
1408
- const srcDir = path.resolve(workingPath, assetsDir, "ios");
1409
- const destDir = path.resolve(platformProjectRoot, projectName);
1410
-
1411
- cleanIOS(destDir);
1412
-
1413
- hfs.copy(
1414
- path.join(srcDir, "BootSplash.storyboard"),
1415
- path.join(destDir, "BootSplash.storyboard"),
1416
- );
1417
-
1418
- for (const xcassetsDir of ["Colors.xcassets", "Images.xcassets"]) {
1419
- const srcXcassetsDir = path.join(srcDir, xcassetsDir);
1420
- const destXcassetsDir = path.join(destDir, xcassetsDir);
1421
-
1422
- hfs.ensureDir(destXcassetsDir);
1423
-
1424
- for (const file of hfs.readDir(srcXcassetsDir)) {
1425
- hfs.copy(
1426
- path.join(srcXcassetsDir, file),
1427
- path.join(destXcassetsDir, file),
1428
- );
1429
- }
1430
- }
1431
-
1432
- return config;
1433
- },
1434
- ]);
1435
-
1436
- const withAppDelegate: ExpoPlugin = (config) =>
1437
- Expo.withAppDelegate(config, (config) => {
1438
- const { modResults } = config;
1439
- const { language } = modResults;
1440
-
1441
- if (language !== "objc" && language !== "objcpp") {
1442
- throw new Error(
1443
- `Cannot modify the project AppDelegate as it's not in a supported language: ${language}`,
1444
- );
1445
- }
1446
-
1447
- const withHeader = mergeContents({
1448
- src: modResults.contents,
1449
- comment: "//",
1450
- tag: "bootsplash-header",
1451
- offset: 1,
1452
- anchor: /#import "AppDelegate\.h"/,
1453
- newSrc: '#import "RNBootSplash.h"',
1454
- });
1455
-
1456
- const withRootView = mergeContents({
1457
- src: withHeader.contents,
1458
- comment: "//",
1459
- tag: "bootsplash-init",
1460
- offset: 0,
1461
- anchor: /@end/,
1462
- newSrc: dedent`
1463
- - (UIView *)createRootViewWithBridge:(RCTBridge *)bridge moduleName:(NSString *)moduleName initProps:(NSDictionary *)initProps {
1464
- UIView *rootView = [super createRootViewWithBridge:bridge moduleName:moduleName initProps:initProps];
1465
- [RNBootSplash initWithStoryboard:@"BootSplash" rootView:rootView];
1466
- return rootView;
1467
- }
1468
- `,
1469
- });
1470
-
1471
- return {
1472
- ...config,
1473
- modResults: {
1474
- ...modResults,
1475
- contents: withRootView.contents,
1476
- },
1477
- };
1478
- });
1479
-
1480
- const withInfoPlist: ExpoPlugin = (config) =>
1481
- Expo.withInfoPlist(config, (config) => {
1482
- config.modResults["UILaunchStoryboardName"] = "BootSplash";
1483
- return config;
1484
- });
1485
-
1486
- const withXcodeProject: ExpoPlugin = (config) =>
1487
- Expo.withXcodeProject(config, (config) => {
1488
- const { projectName = "" } = config.modRequest;
1489
-
1490
- Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
1491
- filepath: path.join(projectName, "BootSplash.storyboard"),
1492
- groupName: projectName,
1493
- project: config.modResults,
1494
- isBuildFile: true,
1495
- });
1496
-
1497
- Expo.IOSConfig.XcodeUtils.addResourceFileToGroup({
1498
- filepath: path.join(projectName, "Colors.xcassets"),
1499
- groupName: projectName,
1500
- project: config.modResults,
1501
- isBuildFile: true,
1502
- });
1503
-
1504
- return config;
1505
- });
1506
-
1507
- const withoutExpoSplashScreen: ExpoPlugin = Expo.createRunOncePlugin(
1508
- (config) => config,
1509
- "expo-splash-screen",
1510
- "skip",
1511
- );
1512
-
1513
- export const withGenerate: ExpoPlugin = (config, props = {}) => {
1514
- const plugins: ExpoPlugin[] = [];
1515
- const { platforms = [] } = config;
1516
-
1517
- plugins.push(withoutExpoSplashScreen);
1518
-
1519
- if (platforms.includes("android")) {
1520
- plugins.push(
1521
- withAndroidAssets,
1522
- withAndroidManifest,
1523
- withMainActivity,
1524
- withAndroidStyles,
1525
- withAndroidColors,
1526
- withAndroidColorsNight,
1527
- );
1528
- }
1529
-
1530
- if (platforms.includes("ios")) {
1531
- plugins.push(
1532
- withIOSAssets,
1533
- withAppDelegate,
1534
- withInfoPlist,
1535
- withXcodeProject,
1536
- );
1537
- }
1538
-
1539
- return Expo.withPlugins(
1540
- config,
1541
- plugins.map((plugin) => [plugin, props]),
1542
- );
1543
- };