vxrn 2.7.7 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/config/getBaseViteConfigOnly.mjs +1 -1
  2. package/dist/config/getBaseViteConfigOnly.mjs.map +1 -1
  3. package/dist/config/getBaseViteConfigOnly.native.js +1 -1
  4. package/dist/config/getBaseViteConfigOnly.native.js.map +1 -1
  5. package/dist/config/getReactNativePlugins.mjs +1 -2
  6. package/dist/config/getReactNativePlugins.mjs.map +1 -1
  7. package/dist/config/getReactNativePlugins.native.js +4 -2
  8. package/dist/config/getReactNativePlugins.native.js.map +1 -1
  9. package/dist/exports/prebuildWithoutExpo.mjs +26 -97
  10. package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
  11. package/dist/exports/prebuildWithoutExpo.native.js +47 -133
  12. package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
  13. package/dist/plugins/autoDepOptimizePlugin.mjs +5 -2
  14. package/dist/plugins/autoDepOptimizePlugin.mjs.map +1 -1
  15. package/dist/plugins/autoDepOptimizePlugin.native.js +10 -7
  16. package/dist/plugins/autoDepOptimizePlugin.native.js.map +1 -1
  17. package/dist/rn-commands/bundle/buildBundle.mjs +5 -4
  18. package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
  19. package/dist/rn-commands/bundle/buildBundle.native.js +5 -4
  20. package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
  21. package/dist/utils/createNativeDevEngine.mjs +17 -5
  22. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  23. package/dist/utils/createNativeDevEngine.native.js +17 -5
  24. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  25. package/package.json +27 -20
  26. package/src/config/getBaseViteConfigOnly.ts +1 -1
  27. package/src/config/getReactNativePlugins.ts +8 -4
  28. package/src/exports/prebuildWithoutExpo.test.ts +62 -157
  29. package/src/exports/prebuildWithoutExpo.ts +31 -125
  30. package/src/plugins/autoDepOptimizeExternal.test.ts +101 -0
  31. package/src/plugins/autoDepOptimizePlugin.ts +12 -6
  32. package/src/plugins/rnCodegenPlugin.ts +1 -2
  33. package/src/rn-commands/bundle/buildBundle.ts +8 -7
  34. package/src/utils/createNativeDevEngine.test.ts +234 -11
  35. package/src/utils/createNativeDevEngine.ts +35 -22
  36. package/types/config/getReactNativePlugins.d.ts +3 -2
  37. package/types/config/getReactNativePlugins.d.ts.map +1 -1
  38. package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
  39. package/types/plugins/autoDepOptimizePlugin.d.ts +1 -0
  40. package/types/plugins/autoDepOptimizePlugin.d.ts.map +1 -1
  41. package/types/plugins/rnCodegenPlugin.d.ts.map +1 -1
  42. package/types/rn-commands/bundle/buildBundle.d.ts +1 -1
  43. package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
  44. package/types/utils/createNativeDevEngine.d.ts +3 -4
  45. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
  46. package/src/plugins/autoDepOptimizePlugin.test.ts +0 -42
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vxrn",
3
- "version": "2.7.7",
3
+ "version": "2.8.1",
4
4
  "sideEffects": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -57,7 +57,6 @@
57
57
  "files": [
58
58
  "src",
59
59
  "types",
60
- "patches",
61
60
  "dist",
62
61
  "run.mjs",
63
62
  "expo-plugin.cjs",
@@ -77,19 +76,18 @@
77
76
  "@hono/node-server": "^1.19.14",
78
77
  "@jridgewell/remapping": "^2.3.0",
79
78
  "@jridgewell/trace-mapping": "^0.3.25",
80
- "@react-native/codegen": "^0.87.1",
79
+ "@react-native/codegen": "^0.88.0",
81
80
  "@react-native-community/cli": "^20.2.0",
82
81
  "@react-native-community/cli-config": "^20.2.0",
83
- "@react-native/dev-middleware": "^0.87.1",
84
- "@vxrn/compiler": "2.7.7",
85
- "@vxrn/debug": "2.7.7",
86
- "@vxrn/query-string": "2.7.7",
87
- "@vxrn/resolve": "2.7.7",
88
- "@vxrn/url-parse": "2.7.7",
89
- "@vxrn/utils": "2.7.7",
90
- "@vxrn/vendor": "2.7.7",
91
- "@vxrn/vite-flow": "2.7.7",
92
- "@vxrn/vite-plugin-metro": "2.7.7",
82
+ "@react-native/dev-middleware": "^0.88.0",
83
+ "@vxrn/compiler": "2.8.1",
84
+ "@vxrn/debug": "2.8.1",
85
+ "@vxrn/query-string": "2.8.1",
86
+ "@vxrn/resolve": "2.8.1",
87
+ "@vxrn/url-parse": "2.8.1",
88
+ "@vxrn/utils": "2.8.1",
89
+ "@vxrn/vendor": "2.8.1",
90
+ "@vxrn/vite-flow": "2.8.1",
93
91
  "citty": "^0.1.6",
94
92
  "dotenv": "^17.2.1",
95
93
  "dotenv-expand": "^12.0.2",
@@ -117,23 +115,32 @@
117
115
  "sucrase": "3.35.1"
118
116
  },
119
117
  "devDependencies": {
120
- "@biomejs/biome": "2.3.3",
118
+ "@biomejs/biome": "2.5.15",
121
119
  "@jridgewell/gen-mapping": "^0.3.5",
122
- "@tamagui/build": "3.0.17",
120
+ "@tamagui/build": "3.0.18",
123
121
  "@types/find-node-modules": "^2.1.2",
124
122
  "@types/node": "^24.10.0",
125
123
  "@types/ws": "^8.18.1",
126
124
  "depcheck": "^1.4.7",
127
- "hermes-compiler": "250829098.0.17",
128
- "metro-source-map": "0.84.4",
129
- "react-native": "0.87.1",
125
+ "hermes-compiler": "260318099.0.4",
126
+ "metro-source-map": "0.87.1",
127
+ "react-native": "0.88.0",
130
128
  "typescript": "7.0.2",
131
- "vitest": "^4.1.0"
129
+ "vitest": "^4.1.0",
130
+ "@vxrn/vite-plugin-metro": "2.8.1"
132
131
  },
133
132
  "publishConfig": {
134
133
  "access": "public"
135
134
  },
136
- "releaseSourceCommit": "2335a80d570e794536b7bb62b023bb73ec1e4d59",
135
+ "peerDependencies": {
136
+ "@vxrn/vite-plugin-metro": "2.8.1"
137
+ },
138
+ "peerDependenciesMeta": {
139
+ "@vxrn/vite-plugin-metro": {
140
+ "optional": true
141
+ }
142
+ },
143
+ "releaseSourceCommit": "9c7de1d429903229d3a6ef9a741c5ec57102ba6b",
137
144
  "repository": {
138
145
  "type": "git",
139
146
  "url": "git+https://github.com/onejs/one.git",
@@ -97,7 +97,7 @@ export async function getBaseViteConfig(
97
97
  // have these native-only subpaths
98
98
  {
99
99
  find: /^react-native\/Libraries\/.*/,
100
- replacement: resolvePath('@vxrn/vite-plugin-metro/empty', import.meta.dirname),
100
+ replacement: resolvePath('@vxrn/utils/empty', import.meta.dirname),
101
101
  },
102
102
  {
103
103
  // react native 0.87 removed @react-native/assets-registry, but libraries
@@ -1,4 +1,5 @@
1
- import { metroPlugin, type MetroPluginOptions } from '@vxrn/vite-plugin-metro'
1
+ import type { MetroPluginOptions } from '@vxrn/vite-plugin-metro'
2
+ import type { PluginOption } from 'vite'
2
3
 
3
4
  import type { VXRNOptionsFilled } from './getOptionsFilled'
4
5
  import { DEFAULT_ASSET_EXTS } from '../constants/defaults'
@@ -17,7 +18,7 @@ export function getReactNativePlugins(
17
18
  /** Passing a non-null value will enable metro mode */
18
19
  metro?: MetroPluginOptions | null
19
20
  } = {}
20
- ) {
21
+ ): PluginOption[] {
21
22
  // when native is disabled (via one's `native: false`), skip all RN / metro
22
23
  // plugins so web-only projects don't spin up the RN dev server, middleware,
23
24
  // websockets, or rolldown native engine.
@@ -27,8 +28,11 @@ export function getReactNativePlugins(
27
28
 
28
29
  const metroOptions: typeof metro = metro || globalThis['__vxrnMetroOptions__']
29
30
  if (metroOptions) {
30
- // Metro mode
31
- return [applyBuiltInPatchesPlugin(), metroPlugin(metroOptions)]
31
+ // metro mode. metro is an optional peer, so only this mode loads it
32
+ return [
33
+ applyBuiltInPatchesPlugin(),
34
+ import('@vxrn/vite-plugin-metro').then(({ metroPlugin }) => metroPlugin(metroOptions)),
35
+ ]
32
36
  }
33
37
 
34
38
  return [
@@ -49,15 +49,17 @@ const app = {
49
49
  android: { applicationId: 'dev.one.myapp', minSdk: 28 },
50
50
  } satisfies PrebuildAppConfig
51
51
 
52
- const templateRnDelegate = readFileSync(
53
- fileURLToPath(
54
- new URL(
55
- '../../../../node_modules/@react-native-community/template/template/ios/HelloWorld/AppDelegate.swift',
56
- import.meta.url
57
- )
58
- ),
59
- 'utf8'
60
- ).split('class ReactNativeDelegate:')[1]
52
+ const templateFile = (file: string) =>
53
+ readFileSync(
54
+ fileURLToPath(
55
+ new URL(
56
+ `../../../../node_modules/@react-native-community/template/template/ios/${file}`,
57
+ import.meta.url
58
+ )
59
+ ),
60
+ 'utf8'
61
+ )
62
+ const templateAppDelegate = templateFile('HelloWorld/AppDelegate.swift')
61
63
 
62
64
  describe('native.app prebuild validation', () => {
63
65
  // smoke for the shared definition re-export; the full cases live beside
@@ -149,10 +151,13 @@ describe('native.app prebuild validation', () => {
149
151
  })
150
152
  })
151
153
 
152
- // the template's AppDelegate entries, which the scene delegate patch anchors
153
- // on, and its two app-target plist settings, beside which the bridging header
154
- // setting lands
155
- const APP_DELEGATE_PBXPROJ = `\t\t761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
154
+ // the template's app and scene source entries and two app-target plist settings,
155
+ // beside which the bridging header setting lands
156
+ const APP_DELEGATE_PBXPROJ = ` 761780EF2CA45674006654EF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EE2CA45674006654EF /* SceneDelegate.swift */; };
157
+ 761780EE2CA45674006654EF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SceneDelegate.swift; path = HelloWorld/SceneDelegate.swift; sourceTree = "<group>"; };
158
+ 761780EE2CA45674006654EF /* SceneDelegate.swift */,
159
+ 761780EF2CA45674006654EF /* SceneDelegate.swift in Sources */,
160
+ \t\t761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
156
161
  \t\t761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = HelloWorld/AppDelegate.swift; sourceTree = "<group>"; };
157
162
  \t\t\t\t761780EC2CA45674006654EE /* AppDelegate.swift */,
158
163
  \t\t\t\t761780ED2CA45674006654EE /* AppDelegate.swift in Sources */,
@@ -485,6 +490,30 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli
485
490
  expect(noPedometerManifest.content).not.toContain('ACTIVITY_RECOGNITION')
486
491
  })
487
492
 
493
+ it('defaults the ios deployment target to the 17.0 floor when unset', () => {
494
+ // one requires ios 17 (see schema minimumVersion and One.podspec);
495
+ // leaving the template's react native 15.1 default fails pod install.
496
+ const noTarget = { ...app, ios: { bundleId: 'dev.one.myapp' } }
497
+ const podfile = renderPrebuildFile({
498
+ relativePath: 'Podfile',
499
+ content:
500
+ "platform :ios, min_ios_version_supported\ntarget 'HelloWorld' do\n config = use_native_modules!\n post_install do |installer|\n react_native_post_install(\n installer\n )\n end\nend",
501
+ platform: 'ios',
502
+ app: noTarget,
503
+ })
504
+ expect(podfile.content).toContain("platform :ios, '17.0'")
505
+ expect(podfile.content).toContain(
506
+ "config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '17.0'"
507
+ )
508
+ const pbxproj = renderPrebuildFile({
509
+ relativePath: 'HelloWorld.xcodeproj/project.pbxproj',
510
+ content: `IPHONEOS_DEPLOYMENT_TARGET = 15.1; target HelloWorld\nshellScript = ${JSON.stringify('REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"\n/bin/sh -c "\\"$WITH_ENVIRONMENT\\" \\"$REACT_NATIVE_XCODE\\""\n')};\n${APP_DELEGATE_PBXPROJ}`,
511
+ platform: 'ios',
512
+ app: noTarget,
513
+ })
514
+ expect(pbxproj.content).toContain('IPHONEOS_DEPLOYMENT_TARGET = 17.0;')
515
+ })
516
+
488
517
  it('stamps the brightness write-settings permission from native.app', () => {
489
518
  const content =
490
519
  '<manifest>\n <uses-permission android:name="android.permission.INTERNET" />\n <activity>\n </activity>\n </application>'
@@ -829,36 +858,7 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli
829
858
 
830
859
  const appDelegate = renderPrebuildFile({
831
860
  relativePath: 'HelloWorld/AppDelegate.swift',
832
- content: `@main
833
- class AppDelegate: UIResponder, UIApplicationDelegate {
834
- var window: UIWindow?
835
-
836
- var reactNativeDelegate: ReactNativeDelegate?
837
- var reactNativeFactory: RCTReactNativeFactory?
838
-
839
- func application(
840
- _ application: UIApplication,
841
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
842
- ) -> Bool {
843
- let delegate = ReactNativeDelegate()
844
- let factory = RCTReactNativeFactory(delegate: delegate)
845
- delegate.dependencyProvider = RCTAppDependencyProvider()
846
-
847
- reactNativeDelegate = delegate
848
- reactNativeFactory = factory
849
-
850
- window = UIWindow(frame: UIScreen.main.bounds)
851
-
852
- factory.startReactNative(
853
- withModuleName: "HelloWorld",
854
- in: window,
855
- launchOptions: launchOptions
856
- )
857
-
858
- return true
859
- }
860
- }
861
- class ReactNativeDelegate:${templateRnDelegate}`,
861
+ content: templateAppDelegate,
862
862
  platform: 'ios',
863
863
  app: push,
864
864
  })
@@ -1163,42 +1163,10 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli
1163
1163
  })
1164
1164
 
1165
1165
  describe('ios scene lifecycle', () => {
1166
- const templateAppDelegate = `@main
1167
- class AppDelegate: UIResponder, UIApplicationDelegate {
1168
- var window: UIWindow?
1169
-
1170
- var reactNativeDelegate: ReactNativeDelegate?
1171
- var reactNativeFactory: RCTReactNativeFactory?
1172
-
1173
- func application(
1174
- _ application: UIApplication,
1175
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
1176
- ) -> Bool {
1177
- let delegate = ReactNativeDelegate()
1178
- let factory = RCTReactNativeFactory(delegate: delegate)
1179
- delegate.dependencyProvider = RCTAppDependencyProvider()
1180
-
1181
- reactNativeDelegate = delegate
1182
- reactNativeFactory = factory
1183
-
1184
- window = UIWindow(frame: UIScreen.main.bounds)
1185
-
1186
- factory.startReactNative(
1187
- withModuleName: "HelloWorld",
1188
- in: window,
1189
- launchOptions: launchOptions
1190
- )
1191
-
1192
- return true
1193
- }
1194
- }
1195
- `
1196
-
1197
- it('trims the AppDelegate to app-level work and keeps the RN delegate', () => {
1166
+ it('registers the app-level factory and keeps the RN launch screen delegate', () => {
1198
1167
  const rendered = renderPrebuildFile({
1199
1168
  relativePath: 'HelloWorld/AppDelegate.swift',
1200
- content: `${templateAppDelegate}
1201
- class ReactNativeDelegate:${templateRnDelegate}`,
1169
+ content: templateAppDelegate,
1202
1170
  platform: 'ios',
1203
1171
  app,
1204
1172
  })
@@ -1212,13 +1180,15 @@ class ReactNativeDelegate:${templateRnDelegate}`,
1212
1180
  expect(rendered.content).toContain('OneHoldLaunchScreen(rootView)')
1213
1181
  })
1214
1182
 
1215
- it('rejects a template that cannot request dev bytecode', () => {
1216
- expect(() => renderPrebuildFile({
1183
+ it('requests Hermes dev bytecode from the generated RN delegate', () => {
1184
+ const rendered = renderPrebuildFile({
1217
1185
  relativePath: 'HelloWorld/AppDelegate.swift',
1218
- content: `${templateAppDelegate}class ReactNativeDelegate:${templateRnDelegate.replace('forBundleRoot: "index"', 'forBundleRoot: "changed"')}`,
1186
+ content: templateAppDelegate,
1219
1187
  platform: 'ios',
1220
1188
  app,
1221
- })).toThrow('expected the template bundle URL provider')
1189
+ })
1190
+ expect(rendered.content).toContain('URLQueryItem(name: "bytecode", value: "hermes")')
1191
+ expect(rendered.content).toContain('if bundleURL.isFileURL { return bundleURL }')
1222
1192
  })
1223
1193
 
1224
1194
  it('throws instead of shipping a non-scene AppDelegate', () => {
@@ -1232,10 +1202,10 @@ class ReactNativeDelegate:${templateRnDelegate}`,
1232
1202
  ).toThrow('changed shape')
1233
1203
  })
1234
1204
 
1235
- it('stamps the scene manifest and delegate into the project', () => {
1205
+ it('preserves the upstream scene manifest and renders the RN delegate', () => {
1236
1206
  const infoPlist = renderPrebuildFile({
1237
1207
  relativePath: 'HelloWorld/Info.plist',
1238
- content: '<dict>\n\t<key>LSRequiresIPhoneOS</key>\n</dict>',
1208
+ content: templateFile('HelloWorld/Info.plist'),
1239
1209
  platform: 'ios',
1240
1210
  app,
1241
1211
  })
@@ -1254,25 +1224,9 @@ class ReactNativeDelegate:${templateRnDelegate}`,
1254
1224
  expect(sceneDelegate).toContain('continue userActivity')
1255
1225
  expect(sceneDelegate).toContain('RCTLinkingManager')
1256
1226
  expect(sceneDelegate).toContain('appDelegate.reactNativeFactory')
1257
- })
1258
-
1259
- it('throws when the template loses a scene anchor', () => {
1260
- expect(() =>
1261
- renderPrebuildFile({
1262
- relativePath: 'HelloWorld/Info.plist',
1263
- content: '<dict>\n</dict>',
1264
- platform: 'ios',
1265
- app,
1266
- })
1267
- ).toThrow('LSRequiresIPhoneOS')
1268
- expect(() =>
1269
- renderPrebuildFile({
1270
- relativePath: 'HelloWorld.xcodeproj/project.pbxproj',
1271
- content: `shellScript = ${JSON.stringify('REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"\n/bin/sh -c "\\"$WITH_ENVIRONMENT\\" \\"$REACT_NATIVE_XCODE\\""\n')};\nno app delegate here`,
1272
- platform: 'ios',
1273
- app,
1274
- })
1275
- ).toThrow('AppDelegate.swift anchor')
1227
+ expect(sceneDelegate).toContain('connectionOptions: connectionOptions')
1228
+ expect(sceneDelegate).toContain('RCTLinkingManager.scene(scene, openURLContexts: URLContexts)')
1229
+ expect(sceneDelegate).toContain('RCTLinkingManager.scene(scene, continue: userActivity)')
1276
1230
  })
1277
1231
 
1278
1232
  it('bundles native.app fonts into both platforms from the real template', async () => {
@@ -1364,7 +1318,7 @@ class ReactNativeDelegate:${templateRnDelegate}`,
1364
1318
  expect(appDelegate).toContain('class ReactNativeDelegate')
1365
1319
 
1366
1320
  const infoPlist = readFileSync(join(output, 'ios', 'MyApp', 'Info.plist'), 'utf8')
1367
- expect(infoPlist).toContain('<key>UIApplicationSceneManifest</key>')
1321
+ expect(infoPlist.split('<key>UIApplicationSceneManifest</key>')).toHaveLength(2)
1368
1322
  expect(infoPlist).toContain('<key>OneNativeNotificationsEnabled</key>')
1369
1323
  // orientation default opens the phone list to all four; ipad keeps its own.
1370
1324
  const phoneOrientations = infoPlist
@@ -1387,7 +1341,7 @@ class ReactNativeDelegate:${templateRnDelegate}`,
1387
1341
  'utf8'
1388
1342
  )
1389
1343
  expect(project).toContain('path = MyApp/SceneDelegate.swift')
1390
- expect(project).toContain('/* SceneDelegate.swift in Sources */,')
1344
+ expect(project.split('/* SceneDelegate.swift in Sources */,')).toHaveLength(2)
1391
1345
  // no push flag: no entitlements file and no entitlement wiring.
1392
1346
  expect(project).not.toContain('CODE_SIGN_ENTITLEMENTS')
1393
1347
  expect(() => statSync(join(output, 'ios', 'MyApp', 'MyApp.entitlements'))).toThrow()
@@ -2357,55 +2311,6 @@ describe('one updates prebuild', () => {
2357
2311
  updates: { url: 'https://updates.example.com', runtimeVersion: 'test-1' },
2358
2312
  } satisfies PrebuildAppConfig
2359
2313
 
2360
- const templateAppDelegate = `import UIKit
2361
- import React
2362
- import React_RCTAppDelegate
2363
- import ReactAppDependencyProvider
2364
-
2365
- @main
2366
- class AppDelegate: UIResponder, UIApplicationDelegate {
2367
- var window: UIWindow?
2368
-
2369
- var reactNativeDelegate: ReactNativeDelegate?
2370
- var reactNativeFactory: RCTReactNativeFactory?
2371
-
2372
- func application(
2373
- _ application: UIApplication,
2374
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
2375
- ) -> Bool {
2376
- let delegate = ReactNativeDelegate()
2377
- let factory = RCTReactNativeFactory(delegate: delegate)
2378
- delegate.dependencyProvider = RCTAppDependencyProvider()
2379
-
2380
- reactNativeDelegate = delegate
2381
- reactNativeFactory = factory
2382
-
2383
- window = UIWindow(frame: UIScreen.main.bounds)
2384
-
2385
- factory.startReactNative(
2386
- withModuleName: "HelloWorld",
2387
- in: window,
2388
- launchOptions: launchOptions
2389
- )
2390
-
2391
- return true
2392
- }
2393
- }
2394
-
2395
- class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
2396
- override func sourceURL(for bridge: RCTBridge) -> URL? {
2397
- self.bundleURL()
2398
- }
2399
-
2400
- override func bundleURL() -> URL? {
2401
- #if DEBUG
2402
- RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
2403
- #else
2404
- Bundle.main.url(forResource: "main", withExtension: "jsbundle")
2405
- #endif
2406
- }
2407
- }
2408
- `
2409
2314
 
2410
2315
  it('validates the updates config', () => {
2411
2316
  expect(() => validatePrebuildApp(updatesApp)).not.toThrow()
@@ -2484,15 +2389,15 @@ buildSettings = {
2484
2389
  ).toThrow('bridging header')
2485
2390
  })
2486
2391
 
2487
- it('throws instead of shipping a stock bundleURL with updates configured', () => {
2392
+ it('rejects an incompatible app delegate with updates configured', () => {
2488
2393
  expect(() =>
2489
2394
  renderPrebuildFile({
2490
2395
  relativePath: 'HelloWorld/AppDelegate.swift',
2491
- content: templateAppDelegate.replace('Bundle.main.url', 'Bundle.main.path'),
2396
+ content: templateAppDelegate.replace(' true', ' false'),
2492
2397
  platform: 'ios',
2493
2398
  app: updatesApp,
2494
2399
  })
2495
- ).toThrow('One.Updates')
2400
+ ).toThrow('changed shape')
2496
2401
  })
2497
2402
 
2498
2403
  it('locks userInterfaceStyle on both platforms, and follows the system when unset', () => {
@@ -2803,7 +2708,7 @@ import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
2803
2708
  platform: 'android',
2804
2709
  app: updatesApp,
2805
2710
  })
2806
- ).toThrow('One.Updates')
2711
+ ).toThrow('changed shape')
2807
2712
  })
2808
2713
 
2809
2714
  it('stamps the updates config into the android manifest', () => {