@absolutejs/absolute 0.20.0-beta.43 → 0.20.0-beta.45

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 (77) hide show
  1. package/dist/angular/browser.js +378 -361
  2. package/dist/angular/browser.js.map +2 -2
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +7 -7
  4. package/dist/angular/components/core/streamingSlotRegistry.js +4 -4
  5. package/dist/angular/index.js +300 -294
  6. package/dist/angular/index.js.map +2 -2
  7. package/dist/angular/server.js +54 -50
  8. package/dist/angular/server.js.map +2 -2
  9. package/dist/build.js +201 -204
  10. package/dist/build.js.map +3 -3
  11. package/dist/cli/config/client.js +12 -12
  12. package/dist/cli/config/server.js +1096 -1090
  13. package/dist/cli/index.js +1573 -1297
  14. package/dist/client/index.js +29 -25
  15. package/dist/client/index.js.map +2 -2
  16. package/dist/core/streamingSlotRegistrar.js +15 -13
  17. package/dist/core/streamingSlotRegistrar.js.map +2 -2
  18. package/dist/core/streamingSlotRegistry.js +11 -9
  19. package/dist/core/streamingSlotRegistry.js.map +2 -2
  20. package/dist/image-client/imageClient.js +7 -7
  21. package/dist/index.js +810 -733
  22. package/dist/index.js.map +7 -6
  23. package/dist/islands/browser.js +11 -9
  24. package/dist/islands/browser.js.map +2 -2
  25. package/dist/islands/index.js +39 -35
  26. package/dist/islands/index.js.map +2 -2
  27. package/dist/mobile/browser.js +23 -22
  28. package/dist/mobile/browser.js.map +3 -3
  29. package/dist/mobile/index.js +739 -426
  30. package/dist/mobile/index.js.map +11 -11
  31. package/dist/mobile/remoteMacAgentEntry.js +227 -37
  32. package/dist/mobile/shellBootstrap.js +0 -1
  33. package/dist/mobile/shellExpoAuth.js +184 -0
  34. package/dist/mobile/shellExpoDevices.js +4 -5
  35. package/dist/mobile/shellExpoSync.js +104 -0
  36. package/dist/mobile/shellSync.js +4 -4
  37. package/dist/react/browser.js +17 -15
  38. package/dist/react/browser.js.map +2 -2
  39. package/dist/react/components/browser/index.js +107 -107
  40. package/dist/react/components/index.js +118 -116
  41. package/dist/react/components/index.js.map +2 -2
  42. package/dist/react/hooks/index.js +11 -9
  43. package/dist/react/hooks/index.js.map +2 -2
  44. package/dist/react/index.js +53 -49
  45. package/dist/react/index.js.map +2 -2
  46. package/dist/react/jsxDevRuntimeCompat.js +11 -9
  47. package/dist/react/jsxDevRuntimeCompat.js.map +2 -2
  48. package/dist/react/jsxRuntimeCompat.js +11 -9
  49. package/dist/react/jsxRuntimeCompat.js.map +2 -2
  50. package/dist/react/router/browser.js +9 -7
  51. package/dist/react/router/browser.js.map +2 -2
  52. package/dist/react/router/index.js +9 -7
  53. package/dist/react/router/index.js.map +2 -2
  54. package/dist/react/server.js +12 -10
  55. package/dist/react/server.js.map +2 -2
  56. package/dist/src/mobile/devDeviceAdapter.d.ts +1 -1
  57. package/dist/src/mobile/expoBridge.d.ts +12 -12
  58. package/dist/src/mobile/nativeAuth.d.ts +6 -0
  59. package/dist/src/mobile/shellExpoAuth.d.ts +12 -0
  60. package/dist/src/mobile/shellExpoSync.d.ts +18 -0
  61. package/dist/svelte/browser.js +12 -10
  62. package/dist/svelte/browser.js.map +2 -2
  63. package/dist/svelte/index.js +47 -43
  64. package/dist/svelte/index.js.map +2 -2
  65. package/dist/svelte/server.js +29 -27
  66. package/dist/svelte/server.js.map +2 -2
  67. package/dist/vue/browser.js +14 -12
  68. package/dist/vue/browser.js.map +2 -2
  69. package/dist/vue/components/Image.js +9 -7
  70. package/dist/vue/components/Image.js.map +2 -2
  71. package/dist/vue/components/index.js +11 -9
  72. package/dist/vue/components/index.js.map +2 -2
  73. package/dist/vue/index.js +52 -48
  74. package/dist/vue/index.js.map +2 -2
  75. package/dist/vue/server.js +14 -12
  76. package/dist/vue/server.js.map +2 -2
  77. package/package.json +3 -2
@@ -19,12 +19,14 @@ var __toESM = (mod, isNodeMode, target) => {
19
19
  }
20
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
21
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
- for (let key of __getOwnPropNames(mod))
23
- if (!__hasOwnProp.call(to, key))
24
- __defProp(to, key, {
25
- get: __accessProp.bind(mod, key),
26
- enumerable: true
27
- });
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
28
30
  if (canCache)
29
31
  cache.set(mod, to);
30
32
  return to;
@@ -163,6 +165,137 @@ var init_startupBanner = __esm(() => {
163
165
  ];
164
166
  });
165
167
 
168
+ // src/mobile/config.ts
169
+ import { resolve as resolve6 } from "path";
170
+ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, HOSTNAME_PATTERN, resolveProjectPath = (projectRoot, value, field2) => {
171
+ const root = resolve6(projectRoot);
172
+ const path = resolve6(root, value);
173
+ if (path !== root && !path.startsWith(`${root}/`)) {
174
+ throw new TypeError(`${field2} must remain inside the project root.`);
175
+ }
176
+ return path;
177
+ }, requireText = (value, field2) => {
178
+ const normalized = value.trim();
179
+ if (!normalized)
180
+ throw new TypeError(`${field2} must not be empty.`);
181
+ return normalized;
182
+ }, normalizeEntry = (entry) => {
183
+ const normalized = requireText(entry ?? "/", "mobile.entry");
184
+ if (!normalized.startsWith("/") || normalized.startsWith("//")) {
185
+ throw new TypeError("mobile.entry must be an absolute application path.");
186
+ }
187
+ return normalized;
188
+ }, normalizeProductionOrigin = (value) => {
189
+ const parsed = new URL(requireText(value, "mobile.server.productionOrigin"));
190
+ const isLoopbackHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]");
191
+ if (parsed.protocol !== "https:" && !isLoopbackHttp) {
192
+ throw new TypeError("mobile.server.productionOrigin must use HTTPS, except for a loopback development origin.");
193
+ }
194
+ if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
195
+ throw new TypeError("mobile.server.productionOrigin must be an origin without credentials, path, query, or hash.");
196
+ }
197
+ return parsed.origin;
198
+ }, normalizePlatforms = (platforms) => {
199
+ const normalized = [
200
+ ...new Set(platforms ?? ["ios", "android"])
201
+ ];
202
+ if (normalized.length === 0) {
203
+ throw new TypeError("mobile.platforms must contain at least one platform.");
204
+ }
205
+ return normalized;
206
+ }, normalizeHosts = (hosts, productionOrigin) => {
207
+ const normalizeHostname = (host) => {
208
+ const value = requireText(host, "mobile.deepLinks.hosts").toLowerCase();
209
+ if (!HOSTNAME_PATTERN.test(value)) {
210
+ throw new TypeError("mobile.deepLinks.hosts entries must be valid hostnames without ports, wildcards, or paths.");
211
+ }
212
+ return value;
213
+ };
214
+ const productionHostname = new URL(productionOrigin).hostname;
215
+ const normalized = new Set(productionHostname === "[::1]" ? [] : [normalizeHostname(productionHostname)]);
216
+ for (const host of hosts ?? []) {
217
+ normalized.add(normalizeHostname(host));
218
+ }
219
+ return [...normalized].sort();
220
+ }, normalizeAppleAppIdPrefix = (value) => {
221
+ if (value === undefined)
222
+ return;
223
+ const normalized = requireText(value, "mobile.deepLinks.apple.appIdPrefix").toUpperCase();
224
+ if (!APPLE_APP_ID_PREFIX_PATTERN.test(normalized)) {
225
+ throw new TypeError("mobile.deepLinks.apple.appIdPrefix must contain ten letters or digits.");
226
+ }
227
+ return normalized;
228
+ }, normalizeIosVersion = (value) => {
229
+ if (value === undefined)
230
+ return;
231
+ const normalized = requireText(value, "mobile.ios.version");
232
+ if (!/^\d+(?:\.\d+){0,2}$/u.test(normalized)) {
233
+ throw new TypeError("mobile.ios.version must contain one to three dot-separated integer components, for example 1.4.0.");
234
+ }
235
+ return normalized;
236
+ }, normalizeCertificateFingerprints = (values) => [
237
+ ...new Set((values ?? []).map((value) => requireText(value, "mobile.deepLinks.android.sha256CertificateFingerprints").replaceAll(":", "").toUpperCase()).map((value) => {
238
+ if (!CERTIFICATE_FINGERPRINT_PATTERN.test(value)) {
239
+ throw new TypeError("mobile.deepLinks.android.sha256CertificateFingerprints entries must be SHA-256 certificate fingerprints.");
240
+ }
241
+ return value.match(/.{2}/g)?.join(":") ?? value;
242
+ }))
243
+ ].sort(), normalizeExpoNativeRoutes = (config, projectRoot) => {
244
+ if (config.engine !== "expo")
245
+ return {};
246
+ const routes = config.routes?.native ?? {};
247
+ const normalized = {};
248
+ for (const [route, module] of Object.entries(routes)) {
249
+ const path = normalizeEntry(route);
250
+ if (path.includes("?") || path.includes("#") || path !== "/" && path.endsWith("/")) {
251
+ throw new TypeError(`mobile.routes.native route ${path} must be a canonical path without a query, fragment, or trailing slash.`);
252
+ }
253
+ if (path === "/__absolute/native") {
254
+ throw new TypeError("mobile.routes.native reserves /__absolute/native for the Expo diagnostic screen.");
255
+ }
256
+ if (path.includes("*") || path.includes(":")) {
257
+ throw new TypeError(`mobile.routes.native route ${path} must be static during the Expo experiment; parameters and wildcards are not supported yet.`);
258
+ }
259
+ normalized[path] = resolveProjectPath(projectRoot, requireText(module, `mobile.routes.native[${path}]`), `mobile.routes.native[${path}]`);
260
+ }
261
+ return Object.fromEntries(Object.entries(normalized).sort(([left], [right]) => left.localeCompare(right)));
262
+ }, normalizeAbsoluteMobileConfig = (config, projectRoot) => {
263
+ const appId = requireText(config.appId, "mobile.appId");
264
+ if (!APP_ID_PATTERN.test(appId)) {
265
+ throw new TypeError("mobile.appId must use reverse-domain notation, for example com.example.app.");
266
+ }
267
+ const productionOrigin = normalizeProductionOrigin(config.server.productionOrigin);
268
+ const deepLinkScheme = (config.deepLinks?.scheme ?? appId).trim().toLowerCase();
269
+ if (deepLinkScheme && !SCHEME_PATTERN.test(deepLinkScheme)) {
270
+ throw new TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");
271
+ }
272
+ return {
273
+ androidCertificateFingerprints: normalizeCertificateFingerprints(config.deepLinks?.android?.sha256CertificateFingerprints),
274
+ appId,
275
+ appleAppIdPrefix: normalizeAppleAppIdPrefix(config.deepLinks?.apple?.appIdPrefix),
276
+ appName: requireText(config.appName, "mobile.appName"),
277
+ bundleDirectory: resolveProjectPath(projectRoot, config.bundleDirectory ?? ".absolutejs/mobile/web", "mobile.bundleDirectory"),
278
+ deepLinkHosts: normalizeHosts(config.deepLinks?.hosts, productionOrigin),
279
+ deepLinkScheme,
280
+ engine: config.engine ?? "capacitor",
281
+ entry: normalizeEntry(config.entry),
282
+ expoNativeRoutes: normalizeExpoNativeRoutes(config, projectRoot),
283
+ ...config.engine === "expo" ? { expoSdkVersion: config.expo?.sdkVersion ?? 57 } : {},
284
+ iosVersion: normalizeIosVersion(config.ios?.version),
285
+ nativeProjectDirectory: resolveProjectPath(projectRoot, config.nativeProject?.directory ?? (config.engine === "expo" ? ".absolutejs/mobile/expo" : "mobile"), "mobile.nativeProject.directory"),
286
+ platforms: normalizePlatforms(config.platforms),
287
+ productionOrigin,
288
+ pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile")
289
+ };
290
+ };
291
+ var init_config = __esm(() => {
292
+ APP_ID_PATTERN = /^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)+$/;
293
+ SCHEME_PATTERN = /^[a-z][a-z0-9+.-]*$/;
294
+ APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
295
+ CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
296
+ HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/;
297
+ });
298
+
166
299
  // src/utils/stringModifiers.ts
167
300
  var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
168
301
  if (!str.includes("-") && !str.includes("_")) {
@@ -171,8 +304,52 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
171
304
  return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
172
305
  };
173
306
 
307
+ // src/mobile/nativeAuth.ts
308
+ import { readFileSync as readFileSync2 } from "fs";
309
+ import { join as join11 } from "path";
310
+ var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth", ABSOLUTE_EXPO_AUTH_CORE_VERSION = "0.75.6", ABSOLUTE_EXPO_AUTH_PACKAGE = "@absolutejs/auth-expo", ABSOLUTE_EXPO_AUTH_VERSION = "0.0.2", ABSOLUTE_EXPO_SYNC_CORE_VERSION = "2.31.0", ABSOLUTE_EXPO_SYNC_PACKAGE = "@absolutejs/sync-expo", ABSOLUTE_EXPO_SYNC_VERSION = "0.0.2", ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS", ABSOLUTE_NATIVE_AUTH_SCOPES, ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync", readPackageManifest = (projectRoot) => {
311
+ try {
312
+ return JSON.parse(readFileSync2(join11(projectRoot, "package.json"), "utf8"));
313
+ } catch {
314
+ return;
315
+ }
316
+ }, packageManifestHas = (manifest, packageName) => {
317
+ if (typeof manifest !== "object" || manifest === null)
318
+ return false;
319
+ return [
320
+ Reflect.get(manifest, "dependencies"),
321
+ Reflect.get(manifest, "devDependencies"),
322
+ Reflect.get(manifest, "optionalDependencies"),
323
+ Reflect.get(manifest, "peerDependencies")
324
+ ].some((dependencies) => typeof dependencies === "object" && dependencies !== null && Object.hasOwn(dependencies, packageName));
325
+ }, createAbsoluteMobileAuthManifest = (config) => {
326
+ const scheme = config.deepLinkScheme ?? config.appId.toLowerCase();
327
+ return {
328
+ clientId: `absolutejs-native:${config.appId}`,
329
+ issuer: config.productionOrigin,
330
+ redirectUri: `${scheme}://auth/callback`,
331
+ scopes: [...ABSOLUTE_NATIVE_AUTH_SCOPES]
332
+ };
333
+ }, installAbsoluteMobileAuthEnvironment = (projectRoot, config) => {
334
+ const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
335
+ const serialized = serializeAbsoluteMobileAuthEnvironment(config, auth);
336
+ if (serialized === undefined)
337
+ delete process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV];
338
+ else
339
+ process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV] = serialized;
340
+ return auth;
341
+ }, projectUsesAbsoluteAuth = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_AUTH_PACKAGE), projectUsesAbsoluteSync = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_SYNC_PACKAGE), resolveAbsoluteMobileAuthManifest = (projectRoot, config) => projectUsesAbsoluteAuth(projectRoot) ? createAbsoluteMobileAuthManifest(config) : undefined, serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefined ? undefined : JSON.stringify([
342
+ {
343
+ ...auth,
344
+ name: `${config.appName} native app`
345
+ }
346
+ ]);
347
+ var init_nativeAuth = __esm(() => {
348
+ ABSOLUTE_NATIVE_AUTH_SCOPES = ["openid", "profile"];
349
+ });
350
+
174
351
  // node_modules/@absolutejs/sync/dist/client/index.js
175
- var RUNTIME_TRANSPORT, host, isRegistry = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations")) && Array.isArray(Reflect.get(value, "clients")), registry, SyncLocalDataPolicyError, SyncLocalStoreSchemaError, positiveVersion = (value, label) => {
352
+ var RUNTIME_TRANSPORT, host, isRegistry = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations")) && Array.isArray(Reflect.get(value, "clients")), registry, pools, SyncLocalDataPolicyError, SyncLocalStoreSchemaError, positiveVersion = (value, label) => {
176
353
  if (!Number.isSafeInteger(value) || value < 1)
177
354
  throw new SyncLocalStoreSchemaError("INVALID_PLAN", `${label} must be a positive safe integer`);
178
355
  return value;
@@ -277,6 +454,7 @@ var init_client = __esm(() => {
277
454
  });
278
455
  return created;
279
456
  })();
457
+ pools = new Map;
280
458
  SyncLocalDataPolicyError = class SyncLocalDataPolicyError extends Error {
281
459
  code;
282
460
  constructor(code, message) {
@@ -4532,6 +4710,7 @@ var testAbsoluteIosPhysicalDevice = async (options) => {
4532
4710
  };
4533
4711
  };
4534
4712
  // src/mobile/associationFiles.ts
4713
+ init_config();
4535
4714
  import {
4536
4715
  access as access7,
4537
4716
  mkdir as mkdir7,
@@ -4542,196 +4721,55 @@ import {
4542
4721
  } from "fs/promises";
4543
4722
  import { resolve as resolve7 } from "path";
4544
4723
  import { Elysia } from "elysia";
4545
-
4546
- // src/mobile/config.ts
4547
- import { resolve as resolve6 } from "path";
4548
- var APP_ID_PATTERN = /^[A-Za-z][\w]*(?:\.[A-Za-z][\w]*)+$/;
4549
- var SCHEME_PATTERN = /^[a-z][a-z0-9+.-]*$/;
4550
- var APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
4551
- var CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
4552
- var HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/;
4553
- var resolveProjectPath = (projectRoot, value, field2) => {
4554
- const root = resolve6(projectRoot);
4555
- const path = resolve6(root, value);
4556
- if (path !== root && !path.startsWith(`${root}/`)) {
4557
- throw new TypeError(`${field2} must remain inside the project root.`);
4558
- }
4559
- return path;
4560
- };
4561
- var requireText = (value, field2) => {
4562
- const normalized = value.trim();
4563
- if (!normalized)
4564
- throw new TypeError(`${field2} must not be empty.`);
4565
- return normalized;
4566
- };
4567
- var normalizeEntry = (entry) => {
4568
- const normalized = requireText(entry ?? "/", "mobile.entry");
4569
- if (!normalized.startsWith("/") || normalized.startsWith("//")) {
4570
- throw new TypeError("mobile.entry must be an absolute application path.");
4571
- }
4572
- return normalized;
4573
- };
4574
- var normalizeProductionOrigin = (value) => {
4575
- const parsed = new URL(requireText(value, "mobile.server.productionOrigin"));
4576
- const isLoopbackHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]");
4577
- if (parsed.protocol !== "https:" && !isLoopbackHttp) {
4578
- throw new TypeError("mobile.server.productionOrigin must use HTTPS, except for a loopback development origin.");
4579
- }
4580
- if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
4581
- throw new TypeError("mobile.server.productionOrigin must be an origin without credentials, path, query, or hash.");
4582
- }
4583
- return parsed.origin;
4724
+ var JSON_HEADERS = {
4725
+ "cache-control": "public, max-age=300, must-revalidate",
4726
+ "content-type": "application/json; charset=utf-8"
4584
4727
  };
4585
- var normalizePlatforms = (platforms) => {
4586
- const normalized = [
4587
- ...new Set(platforms ?? ["ios", "android"])
4588
- ];
4589
- if (normalized.length === 0) {
4590
- throw new TypeError("mobile.platforms must contain at least one platform.");
4728
+ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json";
4729
+ var HTTP_OK = 200;
4730
+ var VERIFY_TIMEOUT_MS = 1e4;
4731
+ var ANDROID_ASSOCIATION_PATH = "/.well-known/assetlinks.json";
4732
+ var APPLE_ASSOCIATION_PATH = "/.well-known/apple-app-site-association";
4733
+ var missingIdentity = (field2, platform) => new TypeError(`${field2} is required to publish ${platform} deep-link association files.`);
4734
+ var createAppleDocument = (config, requireAll) => {
4735
+ if (!config.platforms.includes("ios"))
4736
+ return;
4737
+ if (!config.appleAppIdPrefix && requireAll) {
4738
+ throw missingIdentity("mobile.deepLinks.apple.appIdPrefix", "iOS");
4591
4739
  }
4592
- return normalized;
4593
- };
4594
- var normalizeHosts = (hosts, productionOrigin) => {
4595
- const normalizeHostname = (host) => {
4596
- const value = requireText(host, "mobile.deepLinks.hosts").toLowerCase();
4597
- if (!HOSTNAME_PATTERN.test(value)) {
4598
- throw new TypeError("mobile.deepLinks.hosts entries must be valid hostnames without ports, wildcards, or paths.");
4740
+ if (!config.appleAppIdPrefix)
4741
+ return;
4742
+ return {
4743
+ applinks: {
4744
+ details: [
4745
+ {
4746
+ appIDs: [
4747
+ `${config.appleAppIdPrefix}.${config.appId}`
4748
+ ],
4749
+ components: [{ "/": "/*" }]
4750
+ }
4751
+ ]
4599
4752
  }
4600
- return value;
4601
4753
  };
4602
- const productionHostname = new URL(productionOrigin).hostname;
4603
- const normalized = new Set(productionHostname === "[::1]" ? [] : [normalizeHostname(productionHostname)]);
4604
- for (const host of hosts ?? []) {
4605
- normalized.add(normalizeHostname(host));
4606
- }
4607
- return [...normalized].sort();
4608
4754
  };
4609
- var normalizeAppleAppIdPrefix = (value) => {
4610
- if (value === undefined)
4755
+ var createAndroidDocument = (config, requireAll) => {
4756
+ if (!config.platforms.includes("android"))
4611
4757
  return;
4612
- const normalized = requireText(value, "mobile.deepLinks.apple.appIdPrefix").toUpperCase();
4613
- if (!APPLE_APP_ID_PREFIX_PATTERN.test(normalized)) {
4614
- throw new TypeError("mobile.deepLinks.apple.appIdPrefix must contain ten letters or digits.");
4758
+ if (config.androidCertificateFingerprints.length === 0 && requireAll) {
4759
+ throw missingIdentity("mobile.deepLinks.android.sha256CertificateFingerprints", "Android");
4615
4760
  }
4616
- return normalized;
4617
- };
4618
- var normalizeIosVersion = (value) => {
4619
- if (value === undefined)
4761
+ if (config.androidCertificateFingerprints.length === 0)
4620
4762
  return;
4621
- const normalized = requireText(value, "mobile.ios.version");
4622
- if (!/^\d+(?:\.\d+){0,2}$/u.test(normalized)) {
4623
- throw new TypeError("mobile.ios.version must contain one to three dot-separated integer components, for example 1.4.0.");
4624
- }
4625
- return normalized;
4626
- };
4627
- var normalizeCertificateFingerprints = (values) => [
4628
- ...new Set((values ?? []).map((value) => requireText(value, "mobile.deepLinks.android.sha256CertificateFingerprints").replaceAll(":", "").toUpperCase()).map((value) => {
4629
- if (!CERTIFICATE_FINGERPRINT_PATTERN.test(value)) {
4630
- throw new TypeError("mobile.deepLinks.android.sha256CertificateFingerprints entries must be SHA-256 certificate fingerprints.");
4631
- }
4632
- return value.match(/.{2}/g)?.join(":") ?? value;
4633
- }))
4634
- ].sort();
4635
- var normalizeExpoNativeRoutes = (config, projectRoot) => {
4636
- if (config.engine !== "expo")
4637
- return {};
4638
- const routes = config.routes?.native ?? {};
4639
- const normalized = {};
4640
- for (const [route, module] of Object.entries(routes)) {
4641
- const path = normalizeEntry(route);
4642
- if (path.includes("?") || path.includes("#") || path !== "/" && path.endsWith("/")) {
4643
- throw new TypeError(`mobile.routes.native route ${path} must be a canonical path without a query, fragment, or trailing slash.`);
4644
- }
4645
- if (path === "/__absolute/native") {
4646
- throw new TypeError("mobile.routes.native reserves /__absolute/native for the Expo diagnostic screen.");
4647
- }
4648
- if (path.includes("*") || path.includes(":")) {
4649
- throw new TypeError(`mobile.routes.native route ${path} must be static during the Expo experiment; parameters and wildcards are not supported yet.`);
4650
- }
4651
- normalized[path] = resolveProjectPath(projectRoot, requireText(module, `mobile.routes.native[${path}]`), `mobile.routes.native[${path}]`);
4652
- }
4653
- return Object.fromEntries(Object.entries(normalized).sort(([left], [right]) => left.localeCompare(right)));
4654
- };
4655
- var normalizeAbsoluteMobileConfig = (config, projectRoot) => {
4656
- const appId = requireText(config.appId, "mobile.appId");
4657
- if (!APP_ID_PATTERN.test(appId)) {
4658
- throw new TypeError("mobile.appId must use reverse-domain notation, for example com.example.app.");
4659
- }
4660
- const productionOrigin = normalizeProductionOrigin(config.server.productionOrigin);
4661
- const deepLinkScheme = (config.deepLinks?.scheme ?? appId).trim().toLowerCase();
4662
- if (deepLinkScheme && !SCHEME_PATTERN.test(deepLinkScheme)) {
4663
- throw new TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");
4664
- }
4665
- return {
4666
- androidCertificateFingerprints: normalizeCertificateFingerprints(config.deepLinks?.android?.sha256CertificateFingerprints),
4667
- appId,
4668
- appleAppIdPrefix: normalizeAppleAppIdPrefix(config.deepLinks?.apple?.appIdPrefix),
4669
- appName: requireText(config.appName, "mobile.appName"),
4670
- bundleDirectory: resolveProjectPath(projectRoot, config.bundleDirectory ?? ".absolutejs/mobile/web", "mobile.bundleDirectory"),
4671
- deepLinkHosts: normalizeHosts(config.deepLinks?.hosts, productionOrigin),
4672
- deepLinkScheme,
4673
- engine: config.engine ?? "capacitor",
4674
- entry: normalizeEntry(config.entry),
4675
- expoNativeRoutes: normalizeExpoNativeRoutes(config, projectRoot),
4676
- ...config.engine === "expo" ? { expoSdkVersion: config.expo?.sdkVersion ?? 57 } : {},
4677
- iosVersion: normalizeIosVersion(config.ios?.version),
4678
- nativeProjectDirectory: resolveProjectPath(projectRoot, config.nativeProject?.directory ?? (config.engine === "expo" ? ".absolutejs/mobile/expo" : "mobile"), "mobile.nativeProject.directory"),
4679
- platforms: normalizePlatforms(config.platforms),
4680
- productionOrigin,
4681
- pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile")
4682
- };
4683
- };
4684
-
4685
- // src/mobile/associationFiles.ts
4686
- var JSON_HEADERS = {
4687
- "cache-control": "public, max-age=300, must-revalidate",
4688
- "content-type": "application/json; charset=utf-8"
4689
- };
4690
- var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json";
4691
- var HTTP_OK = 200;
4692
- var VERIFY_TIMEOUT_MS = 1e4;
4693
- var ANDROID_ASSOCIATION_PATH = "/.well-known/assetlinks.json";
4694
- var APPLE_ASSOCIATION_PATH = "/.well-known/apple-app-site-association";
4695
- var missingIdentity = (field2, platform) => new TypeError(`${field2} is required to publish ${platform} deep-link association files.`);
4696
- var createAppleDocument = (config, requireAll) => {
4697
- if (!config.platforms.includes("ios"))
4698
- return;
4699
- if (!config.appleAppIdPrefix && requireAll) {
4700
- throw missingIdentity("mobile.deepLinks.apple.appIdPrefix", "iOS");
4701
- }
4702
- if (!config.appleAppIdPrefix)
4703
- return;
4704
- return {
4705
- applinks: {
4706
- details: [
4707
- {
4708
- appIDs: [
4709
- `${config.appleAppIdPrefix}.${config.appId}`
4710
- ],
4711
- components: [{ "/": "/*" }]
4712
- }
4713
- ]
4714
- }
4715
- };
4716
- };
4717
- var createAndroidDocument = (config, requireAll) => {
4718
- if (!config.platforms.includes("android"))
4719
- return;
4720
- if (config.androidCertificateFingerprints.length === 0 && requireAll) {
4721
- throw missingIdentity("mobile.deepLinks.android.sha256CertificateFingerprints", "Android");
4722
- }
4723
- if (config.androidCertificateFingerprints.length === 0)
4724
- return;
4725
- return [
4726
- {
4727
- relation: ["delegate_permission/common.handle_all_urls"],
4728
- target: {
4729
- namespace: "android_app",
4730
- package_name: config.appId,
4731
- sha256_cert_fingerprints: config.androidCertificateFingerprints
4732
- }
4733
- }
4734
- ];
4763
+ return [
4764
+ {
4765
+ relation: ["delegate_permission/common.handle_all_urls"],
4766
+ target: {
4767
+ namespace: "android_app",
4768
+ package_name: config.appId,
4769
+ sha256_cert_fingerprints: config.androidCertificateFingerprints
4770
+ }
4771
+ }
4772
+ ];
4735
4773
  };
4736
4774
  var createAbsoluteMobileAssociationDocuments = (config, options = {}) => {
4737
4775
  const documents = {};
@@ -5356,7 +5394,6 @@ var finalizeAbsoluteMobilePage = (input) => {
5356
5394
 
5357
5395
  // src/mobile/client.ts
5358
5396
  class AbsoluteMobilePageProtocolError extends Error {
5359
- code;
5360
5397
  constructor(code, message) {
5361
5398
  super(message);
5362
5399
  this.name = "AbsoluteMobilePageProtocolError";
@@ -5567,12 +5604,24 @@ var shellAuthModule = () => {
5567
5604
  return candidate;
5568
5605
  throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
5569
5606
  };
5607
+ var shellExpoAuthModule = () => {
5608
+ const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync2);
5609
+ if (candidate)
5610
+ return candidate;
5611
+ throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
5612
+ };
5570
5613
  var shellSyncModule = () => {
5571
5614
  const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellSync.${extension}`)).find(existsSync2);
5572
5615
  if (candidate)
5573
5616
  return candidate;
5574
5617
  throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
5575
5618
  };
5619
+ var shellExpoSyncModule = () => {
5620
+ const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync2);
5621
+ if (candidate)
5622
+ return candidate;
5623
+ throw new TypeError("AbsoluteJS Expo Sync bridge module is missing.");
5624
+ };
5576
5625
  var shellPushModule = () => {
5577
5626
  const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellPush.${extension}`)).find(existsSync2);
5578
5627
  if (candidate)
@@ -5649,10 +5698,12 @@ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, engine, dev
5649
5698
  const capacitor = engine !== "expo";
5650
5699
  const shellCapabilities = capacitor ? deviceCapabilities.capabilities : [];
5651
5700
  const modulePath = shellBootstrapModule();
5652
- const authImport = auth ? `import { createAbsoluteMobileShellAuth } from ${JSON.stringify(shellAuthModule())};
5701
+ const authFactory = capacitor ? "createAbsoluteMobileShellAuth" : "createAbsoluteExpoShellAuth";
5702
+ const syncFactory = capacitor ? "installAbsoluteMobileShellSync" : "installAbsoluteExpoShellSync";
5703
+ const authImport = auth ? `import { ${authFactory} } from ${JSON.stringify(capacitor ? shellAuthModule() : shellExpoAuthModule())};
5653
5704
  ` : "";
5654
- const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
5655
- const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
5705
+ const options = auth ? `{ createAuth: ${authFactory}${sync ? `, installSync: ${syncFactory}` : ""} }` : "";
5706
+ const syncImport = sync ? `import { ${syncFactory} } from ${JSON.stringify(capacitor ? shellSyncModule() : shellExpoSyncModule())};
5656
5707
  ` : "";
5657
5708
  const pushIndex = shellCapabilities.indexOf("pushNotifications");
5658
5709
  const push = pushIndex !== -1;
@@ -5673,11 +5724,11 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
5673
5724
  const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
5674
5725
  const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
5675
5726
  const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : "installAbsoluteExpoWebDeviceAdapter();";
5676
- let shellOptions = "{ createFetch: createAbsoluteExpoBridgeFetch }";
5727
+ let shellOptions = auth ? options : "{ createFetch: createAbsoluteExpoBridgeFetch }";
5677
5728
  if (capacitor)
5678
5729
  shellOptions = options;
5679
5730
  if (push) {
5680
- shellOptions = `{ createAuth: (config, options) => createAbsoluteMobileShellAuth(config, options), beforeSignOut: absoluteMobilePush.beforeSignOut, connectPush: (auth) => absoluteMobilePush.connect(auth, absoluteMobilePushCapability)${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }`;
5731
+ shellOptions = `{ createAuth: (config, options) => createAbsoluteMobileShellAuth(config, options), beforeSignOut: absoluteMobilePush.beforeSignOut, connectPush: (auth) => absoluteMobilePush.connect(auth, absoluteMobilePushCapability)${sync ? `, installSync: ${syncFactory}` : ""} }`;
5681
5732
  }
5682
5733
  await writeFile10(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
5683
5734
  ${adapterImport}
@@ -5857,6 +5908,9 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
5857
5908
  }
5858
5909
  };
5859
5910
 
5911
+ // src/mobile/buildPipeline.ts
5912
+ init_config();
5913
+
5860
5914
  // src/mobile/materializedBundle.ts
5861
5915
  import { createHash as createHash9 } from "crypto";
5862
5916
  import {
@@ -6034,63 +6088,14 @@ var readAbsoluteMobileMaterializedReleases = async (root) => {
6034
6088
  }
6035
6089
  };
6036
6090
 
6037
- // src/mobile/nativeAuth.ts
6038
- import { readFileSync as readFileSync2 } from "fs";
6039
- import { join as join11 } from "path";
6040
- var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth";
6041
- var ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS";
6042
- var ABSOLUTE_NATIVE_AUTH_SCOPES = ["openid", "profile"];
6043
- var ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync";
6044
- var readPackageManifest = (projectRoot) => {
6045
- try {
6046
- return JSON.parse(readFileSync2(join11(projectRoot, "package.json"), "utf8"));
6047
- } catch {
6048
- return;
6049
- }
6050
- };
6051
- var packageManifestHas = (manifest, packageName) => {
6052
- if (typeof manifest !== "object" || manifest === null)
6053
- return false;
6054
- return [
6055
- Reflect.get(manifest, "dependencies"),
6056
- Reflect.get(manifest, "devDependencies"),
6057
- Reflect.get(manifest, "optionalDependencies"),
6058
- Reflect.get(manifest, "peerDependencies")
6059
- ].some((dependencies) => typeof dependencies === "object" && dependencies !== null && Object.hasOwn(dependencies, packageName));
6060
- };
6061
- var createAbsoluteMobileAuthManifest = (config) => {
6062
- const scheme = config.deepLinkScheme ?? config.appId.toLowerCase();
6063
- return {
6064
- clientId: `absolutejs-native:${config.appId}`,
6065
- issuer: config.productionOrigin,
6066
- redirectUri: `${scheme}://auth/callback`,
6067
- scopes: [...ABSOLUTE_NATIVE_AUTH_SCOPES]
6068
- };
6069
- };
6070
- var installAbsoluteMobileAuthEnvironment = (projectRoot, config) => {
6071
- const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
6072
- const serialized = serializeAbsoluteMobileAuthEnvironment(config, auth);
6073
- if (serialized === undefined)
6074
- delete process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV];
6075
- else
6076
- process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV] = serialized;
6077
- return auth;
6078
- };
6079
- var projectUsesAbsoluteAuth = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_AUTH_PACKAGE);
6080
- var projectUsesAbsoluteSync = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_SYNC_PACKAGE);
6081
- var resolveAbsoluteMobileAuthManifest = (projectRoot, config) => projectUsesAbsoluteAuth(projectRoot) ? createAbsoluteMobileAuthManifest(config) : undefined;
6082
- var serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefined ? undefined : JSON.stringify([
6083
- {
6084
- ...auth,
6085
- name: `${config.appName} native app`
6086
- }
6087
- ]);
6088
-
6089
6091
  // src/mobile/buildPipeline.ts
6092
+ init_nativeAuth();
6090
6093
  init_syncSchema();
6091
6094
  init_deviceCapabilities();
6092
6095
 
6093
6096
  // src/mobile/expoProject.ts
6097
+ init_nativeAuth();
6098
+ init_syncSchema();
6094
6099
  import {
6095
6100
  access as access9,
6096
6101
  cp as cp2,
@@ -6129,8 +6134,16 @@ var routeSegments = (route) => route.split("/").filter(Boolean).map((segment) =>
6129
6134
  return segment;
6130
6135
  });
6131
6136
  var routeFile = (project, route) => join14(project, "app", ...routeSegments(route), "index.tsx");
6132
- var expoPackage = () => ({
6137
+ var expoPackage = (auth, sync) => ({
6133
6138
  dependencies: {
6139
+ ...auth ? {
6140
+ "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
6141
+ [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
6142
+ } : {},
6143
+ ...sync ? {
6144
+ "@absolutejs/sync": ABSOLUTE_EXPO_SYNC_CORE_VERSION,
6145
+ [ABSOLUTE_EXPO_SYNC_PACKAGE]: ABSOLUTE_EXPO_SYNC_VERSION
6146
+ } : {},
6134
6147
  expo: "~57.0.9",
6135
6148
  "expo-asset": "~57.0.15",
6136
6149
  "expo-constants": "~57.0.16",
@@ -6138,7 +6151,18 @@ var expoPackage = () => ({
6138
6151
  "expo-file-system": "~57.0.6",
6139
6152
  "expo-haptics": "~57.0.2",
6140
6153
  "expo-linking": "~57.0.8",
6154
+ ...sync ? {
6155
+ "expo-background-task": "~57.0.14",
6156
+ "expo-network": "~57.0.1",
6157
+ "expo-sqlite": "~57.0.2",
6158
+ "expo-task-manager": "~57.0.14",
6159
+ "expo-updates": "~57.0.19"
6160
+ } : {},
6141
6161
  "expo-router": "~57.0.17",
6162
+ ...auth ? {
6163
+ "expo-secure-store": "~57.0.2",
6164
+ "expo-web-browser": "~57.0.2"
6165
+ } : {},
6142
6166
  react: "19.2.3",
6143
6167
  "react-native": "0.86.3",
6144
6168
  "react-native-safe-area-context": "~5.7.0",
@@ -6159,7 +6183,7 @@ var expoPackage = () => ({
6159
6183
  },
6160
6184
  version: "0.0.0"
6161
6185
  });
6162
- var expoAppConfig = (config) => ({
6186
+ var expoAppConfig = (config, auth, sync) => ({
6163
6187
  expo: {
6164
6188
  android: {
6165
6189
  intentFilters: config.deepLinkHosts.map((host2) => ({
@@ -6179,7 +6203,9 @@ var expoAppConfig = (config) => ({
6179
6203
  name: config.appName,
6180
6204
  plugins: [
6181
6205
  "expo-router",
6182
- ["expo-dev-client", { launchMode: "most-recent" }]
6206
+ ["expo-dev-client", { launchMode: "most-recent" }],
6207
+ ...auth ? ["expo-secure-store"] : [],
6208
+ ...sync ? ["expo-sqlite", "expo-background-task", "expo-task-manager"] : []
6183
6209
  ],
6184
6210
  runtimeVersion: { policy: "appVersion" },
6185
6211
  scheme: config.deepLinkScheme,
@@ -6253,9 +6279,19 @@ config.watchFolders = [appRoot];
6253
6279
 
6254
6280
  module.exports = config;
6255
6281
  `;
6256
- var layoutSource = `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
6282
+ var layoutSource = (auth, sync) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
6283
+ ${auth ? `import { useEffect, useState } from 'react';
6284
+ import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
6285
+ ${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
6257
6286
 
6258
6287
  export default function AbsoluteLayout() {
6288
+ ${auth ? `const [ready, setReady] = useState(false);
6289
+ useEffect(() => {
6290
+ let active = true;
6291
+ void ${sync ? "startAbsoluteExpoSync" : "startAbsoluteExpoAuth"}().then(() => { if (active) setReady(true); });
6292
+ return () => { active = false; };
6293
+ }, []);
6294
+ if (!ready) return null;` : ""}
6259
6295
  return <Stack screenOptions={{ headerShown: false }} />;
6260
6296
  }
6261
6297
  `;
@@ -6290,7 +6326,137 @@ const styles = StyleSheet.create({
6290
6326
  title: { color: '#f8fafc', fontSize: 32, fontWeight: '800' }
6291
6327
  });
6292
6328
  `;
6293
- var webHostSource = (config) => {
6329
+ var authRuntimeSource = (auth, appId) => {
6330
+ const storageIdentity = createHash10("sha256").update(appId).digest("hex").slice(0, 24);
6331
+ return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
6332
+ import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
6333
+
6334
+ export const absoluteExpoAuth = createAbsoluteExpoAuthClient({
6335
+ allowedOrigins: [${JSON.stringify(auth.issuer)}],
6336
+ clientId: ${JSON.stringify(auth.clientId)},
6337
+ issuer: ${JSON.stringify(auth.issuer)},
6338
+ redirectUri: ${JSON.stringify(auth.redirectUri)},
6339
+ resource: ${JSON.stringify(auth.issuer)},
6340
+ scopes: ${JSON.stringify(auth.scopes)},
6341
+ storagePrefix: ${JSON.stringify(`absolutejs.auth.${storageIdentity}`)}
6342
+ });
6343
+ installAuthClientRuntimeTransport(createMobileAuthTransport(absoluteExpoAuth, { baseUrl: ${JSON.stringify(auth.issuer)} }));
6344
+
6345
+ let currentPrincipal: Awaited<ReturnType<typeof absoluteExpoAuth.principal>> = null;
6346
+ absoluteExpoAuth.onPrincipalChange(principal => {
6347
+ currentPrincipal = principal;
6348
+ });
6349
+ export const getAbsoluteExpoAuthPrincipal = () => currentPrincipal;
6350
+
6351
+ let startPromise: Promise<void> | undefined;
6352
+ export const startAbsoluteExpoAuth = () => {
6353
+ startPromise ??= absoluteExpoAuth.start().then(async () => {
6354
+ currentPrincipal = await absoluteExpoAuth.principal();
6355
+ });
6356
+
6357
+ return startPromise;
6358
+ };
6359
+ `;
6360
+ };
6361
+ var syncRuntimeSource = (config, schema) => {
6362
+ const storageIdentity = createHash10("sha256").update(config.appId).digest("hex").slice(0, 24);
6363
+ const backgroundEndpoint = new URL("/__absolute/sync/background", config.productionOrigin).href;
6364
+ const backgroundTask = `${config.appId}.absolutejs.sync`;
6365
+ return `${EXPO_GENERATED_HEADER}import { runHeadlessSync } from '@absolutejs/sync/client/headless';
6366
+ import type { SyncLocalStoreSchemaBundle } from '@absolutejs/sync/client';
6367
+ import { installSyncClientRuntimeTransport } from '@absolutejs/sync/client/runtime';
6368
+ import {
6369
+ createExpoSyncBridgeHost,
6370
+ createExpoSyncLocalStore,
6371
+ createExpoSyncProtection,
6372
+ createExpoSyncSocketBridgeHost,
6373
+ defineExpoSyncBackgroundTask,
6374
+ installExpoSyncLifecycle,
6375
+ registerExpoSyncBackgroundTask
6376
+ } from '@absolutejs/sync-expo';
6377
+ import * as Updates from 'expo-updates';
6378
+ import { absoluteExpoAuth, startAbsoluteExpoAuth } from './AbsoluteAuth';
6379
+
6380
+ const BACKGROUND_TASK = ${JSON.stringify(backgroundTask)};
6381
+ const BACKGROUND_ENDPOINT = ${JSON.stringify(backgroundEndpoint)};
6382
+ const PRODUCTION_ORIGIN = ${JSON.stringify(config.productionOrigin)};
6383
+ const STORAGE_SCHEMA: SyncLocalStoreSchemaBundle = ${JSON.stringify(schema)};
6384
+ const store = createExpoSyncLocalStore({
6385
+ databaseName: ${JSON.stringify(`absolutejs-sync-${storageIdentity}.db`)},
6386
+ protection: createExpoSyncProtection({ storagePrefix: ${JSON.stringify(`absolutejs.sync.${storageIdentity}`)} }),
6387
+ storageSchema: STORAGE_SCHEMA
6388
+ });
6389
+
6390
+ const runBackgroundSync = async () => {
6391
+ await startAbsoluteExpoAuth();
6392
+ const principal = await absoluteExpoAuth.principal();
6393
+ if (!principal) return;
6394
+ await runHeadlessSync({
6395
+ endpoint: BACKGROUND_ENDPOINT,
6396
+ fetch: (url, init) => absoluteExpoAuth.fetch(url, init),
6397
+ namespace: principal.namespace,
6398
+ store
6399
+ });
6400
+ };
6401
+ defineExpoSyncBackgroundTask(BACKGROUND_TASK, runBackgroundSync);
6402
+
6403
+ let activeNamespace: string | undefined;
6404
+ let started = false;
6405
+ let startPromise: Promise<void> | undefined;
6406
+ export const startAbsoluteExpoSync = () => {
6407
+ startPromise ??= (async () => {
6408
+ await startAbsoluteExpoAuth();
6409
+ const principal = await absoluteExpoAuth.principal();
6410
+ activeNamespace = principal?.namespace;
6411
+ installSyncClientRuntimeTransport({
6412
+ ...(principal ? { durable: { namespace: principal.namespace, store }, socketTicket: () => absoluteExpoAuth.socketTicket() } : {}),
6413
+ registerClient: client => installExpoSyncLifecycle({ client })
6414
+ });
6415
+ await registerExpoSyncBackgroundTask(BACKGROUND_TASK, { minimumInterval: 15 });
6416
+ started = true;
6417
+ })();
6418
+
6419
+ return startPromise;
6420
+ };
6421
+
6422
+ absoluteExpoAuth.onPrincipalChange(principal => {
6423
+ if (!started || principal?.namespace === activeNamespace) return;
6424
+ void Updates.reloadAsync();
6425
+ });
6426
+
6427
+ export const createAbsoluteExpoSyncBridge = async (
6428
+ emit: (event: 'sync.socket' | 'sync.wake', payload: Record<string, unknown>) => void
6429
+ ) => {
6430
+ await startAbsoluteExpoSync();
6431
+ const principal = await absoluteExpoAuth.principal();
6432
+ if (!principal) return {
6433
+ close: () => undefined,
6434
+ request: async () => { throw new Error('Expo Sync requires an authenticated principal.'); }
6435
+ };
6436
+ const transactions = createExpoSyncBridgeHost({ namespace: principal.namespace, store });
6437
+ const sockets = createExpoSyncSocketBridgeHost({
6438
+ allowedOrigin: PRODUCTION_ORIGIN,
6439
+ emit: payload => emit('sync.socket', payload),
6440
+ socketTicket: audience => absoluteExpoAuth.socketTicket(audience)
6441
+ });
6442
+ const removeLifecycle = installExpoSyncLifecycle({
6443
+ client: { reconnect: () => emit('sync.wake', {}) }
6444
+ });
6445
+
6446
+ return {
6447
+ close: async () => {
6448
+ removeLifecycle();
6449
+ await Promise.all([transactions.close(), sockets.close()]);
6450
+ },
6451
+ request: (method: string, params: Record<string, unknown>) =>
6452
+ method.startsWith('sync.socket.')
6453
+ ? sockets.request(method, params)
6454
+ : transactions.request(method, params)
6455
+ };
6456
+ };
6457
+ `;
6458
+ };
6459
+ var webHostSource = (config, auth, sync) => {
6294
6460
  const nativeRoutes = [
6295
6461
  "/__absolute/native",
6296
6462
  ...Object.keys(config.expoNativeRoutes)
@@ -6302,8 +6468,10 @@ import { useEffect, useRef, useState } from 'react';
6302
6468
  import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
6303
6469
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
6304
6470
  import { materializeAbsoluteWebBundle } from './webAssets';
6471
+ ${auth ? "import { absoluteExpoAuth, getAbsoluteExpoAuthPrincipal, startAbsoluteExpoAuth } from './AbsoluteAuth';" : ""}
6472
+ ${sync ? "import { createAbsoluteExpoSyncBridge, startAbsoluteExpoSync } from './AbsoluteSync';" : ""}
6305
6473
 
6306
- const BRIDGE_FORMAT = 1;
6474
+ const BRIDGE_FORMAT = 3;
6307
6475
  const MAX_MESSAGE_BYTES = 64 * 1024;
6308
6476
  const MAX_HTTP_BODY_BYTES = 48 * 1024;
6309
6477
  const NATIVE_ROUTES = new Set(${JSON.stringify(nativeRoutes)});
@@ -6312,6 +6480,8 @@ const DEV_ORIGIN = Platform.OS === 'android'
6312
6480
  ? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
6313
6481
  : process.env.EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN;
6314
6482
  const HMR_TARGET = Platform.OS === 'android' ? 'expo-android' : 'expo-ios';
6483
+ const AUTH_ENABLED = ${auth ? "true" : "false"};
6484
+ const SYNC_ENABLED = ${sync ? "true" : "false"};
6315
6485
 
6316
6486
  const bridgeBootstrap = (path: string) => {
6317
6487
  const initialPath = DEV_ORIGIN
@@ -6319,6 +6489,7 @@ const bridgeBootstrap = (path: string) => {
6319
6489
  : JSON.stringify(path);
6320
6490
  return \`(() => {
6321
6491
  const pending = new Map();
6492
+ const listeners = new Map();
6322
6493
  let sequence = 0;
6323
6494
  let currentPath = \${initialPath};
6324
6495
  const send = value => {
@@ -6328,6 +6499,10 @@ const bridgeBootstrap = (path: string) => {
6328
6499
  };
6329
6500
  globalThis.__absoluteExpoReceive = source => {
6330
6501
  const message = JSON.parse(source);
6502
+ if (message.kind === 'event') {
6503
+ for (const listener of listeners.get(message.event) || []) listener(message.payload || {});
6504
+ return;
6505
+ }
6331
6506
  const operation = pending.get(message.id);
6332
6507
  if (!operation) return;
6333
6508
  pending.delete(message.id);
@@ -6335,9 +6510,18 @@ const bridgeBootstrap = (path: string) => {
6335
6510
  message.error ? operation.reject(new Error(message.error.message)) : operation.resolve(message.result);
6336
6511
  };
6337
6512
  globalThis.__absoluteExpoBridge = {
6513
+ on(event, listener) {
6514
+ const values = listeners.get(event) || new Set();
6515
+ values.add(listener);
6516
+ listeners.set(event, values);
6517
+ return () => {
6518
+ values.delete(listener);
6519
+ if (values.size === 0) listeners.delete(event);
6520
+ };
6521
+ },
6338
6522
  request(method, params) {
6339
6523
  const id = 'web_' + Date.now().toString(36) + '_' + (++sequence).toString(36);
6340
- send({ format: 1, id, kind: 'request', method, params, path: currentPath });
6524
+ send({ format: 3, id, kind: 'request', method, params, path: currentPath });
6341
6525
  return new Promise((resolve, reject) => {
6342
6526
  const timer = setTimeout(() => {
6343
6527
  pending.delete(id);
@@ -6348,7 +6532,7 @@ const bridgeBootstrap = (path: string) => {
6348
6532
  },
6349
6533
  setPath(path) {
6350
6534
  currentPath = path;
6351
- send({ format: 1, kind: 'event', event: 'navigation', path });
6535
+ send({ format: 3, kind: 'event', event: 'navigation', path });
6352
6536
  }
6353
6537
  };
6354
6538
  if (\${DEV_ORIGIN ? 'true' : 'false'}) {
@@ -6356,7 +6540,7 @@ const bridgeBootstrap = (path: string) => {
6356
6540
  const path = location.pathname + location.search + location.hash;
6357
6541
  if (path === currentPath) return;
6358
6542
  currentPath = path;
6359
- send({ format: 1, kind: 'event', event: 'navigation', path });
6543
+ send({ format: 3, kind: 'event', event: 'navigation', path });
6360
6544
  };
6361
6545
  for (const method of ['pushState', 'replaceState']) {
6362
6546
  const original = history[method];
@@ -6375,9 +6559,9 @@ const bridgeBootstrap = (path: string) => {
6375
6559
  const url = new URL(anchor.href, location.href);
6376
6560
  if (!${JSON.stringify(nativeRoutes)}.includes(url.pathname)) return;
6377
6561
  event.preventDefault();
6378
- send({ format: 1, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
6562
+ send({ format: 3, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
6379
6563
  }, true);
6380
- send({ format: 1, kind: 'event', event: 'ready', path: currentPath });
6564
+ send({ format: 3, kind: 'event', event: 'ready', path: currentPath });
6381
6565
  })(); true;\`;
6382
6566
  };
6383
6567
 
@@ -6393,16 +6577,16 @@ const impact = async (params: Record<string, unknown>) => {
6393
6577
  };
6394
6578
 
6395
6579
  const bridgeFetch = async (params: Record<string, unknown>) => {
6396
- if (params.method !== 'GET' || typeof params.url !== 'string' || typeof params.headers !== 'object' || params.headers === null || Array.isArray(params.headers)) throw new Error('Expo bridge HTTP request is invalid.');
6580
+ if (typeof params.method !== 'string' || !['DELETE', 'GET', 'PATCH', 'POST', 'PUT'].includes(params.method) || typeof params.url !== 'string' || typeof params.headers !== 'object' || params.headers === null || Array.isArray(params.headers) || params.body !== undefined && typeof params.body !== 'string') throw new Error('Expo bridge HTTP request is invalid.');
6397
6581
  const url = new URL(params.url);
6398
6582
  if (url.origin !== PRODUCTION_ORIGIN || url.username || url.password) throw new Error('Expo bridge HTTP request left productionOrigin.');
6399
6583
  const headers = new Headers();
6400
6584
  for (const [name, value] of Object.entries(params.headers as Record<string, unknown>)) {
6401
6585
  const normalized = name.toLowerCase();
6402
- if (typeof value !== 'string' || (normalized !== 'accept' && !normalized.startsWith('x-absolute-mobile-'))) throw new Error('Expo bridge HTTP header is not allowed.');
6586
+ if (typeof value !== 'string' || (normalized !== 'accept' && normalized !== 'content-type' && !normalized.startsWith('x-absolute-mobile-'))) throw new Error('Expo bridge HTTP header is not allowed.');
6403
6587
  headers.set(normalized, value);
6404
6588
  }
6405
- const response = await fetch(url, { headers, method: 'GET', redirect: 'manual' });
6589
+ const response = await ${auth ? "absoluteExpoAuth.fetchOptional" : "fetch"}(url, { ...(typeof params.body === 'string' ? { body: params.body } : {}), headers, method: params.method, redirect: 'manual' });
6406
6590
  if (new URL(response.url || url.href).origin !== PRODUCTION_ORIGIN || response.status >= 300 && response.status < 400) throw new Error('Expo bridge HTTP redirects are not allowed.');
6407
6591
  const body = await response.text();
6408
6592
  if (new TextEncoder().encode(body).byteLength > MAX_HTTP_BODY_BYTES) throw new Error('Expo bridge HTTP response exceeds 48 KiB.');
@@ -6414,13 +6598,45 @@ const bridgeFetch = async (params: Record<string, unknown>) => {
6414
6598
  return { body, headers: responseHeaders, status: response.status };
6415
6599
  };
6416
6600
 
6601
+ const authStatus = async () => {
6602
+ ${auth ? `const user = await absoluteExpoAuth.status();
6603
+ const principal = getAbsoluteExpoAuthPrincipal();
6604
+ return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
6605
+ };
6606
+
6417
6607
  export function AbsoluteWebHost() {
6418
6608
  const pathname = usePathname() || '/';
6419
6609
  const webView = useRef<WebView>(null);
6610
+ const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
6420
6611
  const [indexUri, setIndexUri] = useState<string>();
6421
6612
  const [canGoBack, setCanGoBack] = useState(false);
6613
+ const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
6422
6614
  const activeWebPath = useRef(pathname);
6423
6615
 
6616
+ useEffect(() => {
6617
+ if (!AUTH_ENABLED && !SYNC_ENABLED) return;
6618
+ let active = true;
6619
+ ${auth ? `const stop = absoluteExpoAuth.onPrincipalChange(principal => {
6620
+ if (!active) return;
6621
+ const source = JSON.stringify({ event: 'auth.principal', format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload: { principal: principal ? { namespace: principal.namespace } : null } });
6622
+ webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
6623
+ });
6624
+ void ${sync ? "startAbsoluteExpoSync" : "startAbsoluteExpoAuth"}().then(async () => {
6625
+ ${sync ? `syncBridge.current = await createAbsoluteExpoSyncBridge((event, payload) => {
6626
+ const source = JSON.stringify({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
6627
+ webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
6628
+ });` : ""}
6629
+ if (active) setRuntimeReady(true);
6630
+ });
6631
+ return () => {
6632
+ active = false;
6633
+ stop();
6634
+ const bridge = syncBridge.current;
6635
+ syncBridge.current = undefined;
6636
+ void bridge?.close();
6637
+ };` : ""}
6638
+ }, []);
6639
+
6424
6640
  useEffect(() => {
6425
6641
  if (DEV_ORIGIN) {
6426
6642
  const target = new URL(pathname, DEV_ORIGIN);
@@ -6470,6 +6686,19 @@ export function AbsoluteWebHost() {
6470
6686
  respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });
6471
6687
  } else if (message.method === 'http.fetch') {
6472
6688
  respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await bridgeFetch(message.params as Record<string, unknown>) });
6689
+ } else if (message.method === 'auth.signIn') {
6690
+ ${auth ? `const params = message.params as Record<string, unknown>;
6691
+ if (typeof params.email !== 'string' || typeof params.signup !== 'boolean') throw new Error('Expo Auth sign-in params are invalid.');
6692
+ await absoluteExpoAuth.signIn({ authorizationParameters: { login_hint: params.email, ...(params.signup ? { screen_hint: 'signup' } : {}) } });
6693
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });` : "throw new Error('Expo Auth is not configured.');"}
6694
+ } else if (message.method === 'auth.signOut') {
6695
+ ${auth ? `await absoluteExpoAuth.signOut();
6696
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });` : "throw new Error('Expo Auth is not configured.');"}
6697
+ } else if (message.method === 'auth.status') {
6698
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });
6699
+ } else if (typeof message.method === 'string' && message.method.startsWith('sync.')) {
6700
+ if (!syncBridge.current) throw new Error('Expo Sync bridge is unavailable.');
6701
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await syncBridge.current.request(message.method, message.params as Record<string, unknown>) });
6473
6702
  } else {
6474
6703
  throw new Error('Expo bridge method is not allowed.');
6475
6704
  }
@@ -6478,7 +6707,7 @@ export function AbsoluteWebHost() {
6478
6707
  }
6479
6708
  };
6480
6709
 
6481
- if (!indexUri) return <View style={styles.loading}><ActivityIndicator /></View>;
6710
+ if (!indexUri || !runtimeReady) return <View style={styles.loading}><ActivityIndicator /></View>;
6482
6711
  return <WebView
6483
6712
  allowFileAccess
6484
6713
  allowFileAccessFromFileURLs
@@ -6511,9 +6740,31 @@ export default AbsoluteWebHost;
6511
6740
  `;
6512
6741
  var nativeWrapperSource = (wrapper, module) => `${EXPO_GENERATED_HEADER}export { default } from ${JSON.stringify(portableRelative2(dirname10(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
6513
6742
  `;
6514
- var expoTsConfig = (projectRoot, project) => ({
6743
+ var expoTsConfig = (projectRoot, project, auth, sync) => ({
6515
6744
  compilerOptions: {
6516
6745
  paths: {
6746
+ ...auth ? {
6747
+ "@absolutejs/auth": [
6748
+ "./node_modules/@absolutejs/auth/dist/index.d.ts"
6749
+ ],
6750
+ "@absolutejs/auth/*": [
6751
+ "./node_modules/@absolutejs/auth/dist/*"
6752
+ ]
6753
+ } : {},
6754
+ ...sync ? {
6755
+ "@absolutejs/sync": [
6756
+ "./node_modules/@absolutejs/sync/dist/index.d.ts"
6757
+ ],
6758
+ "@absolutejs/sync-expo": [
6759
+ "./node_modules/@absolutejs/sync-expo/dist/index.d.ts"
6760
+ ],
6761
+ "@absolutejs/sync-expo/*": [
6762
+ "./node_modules/@absolutejs/sync-expo/dist/*"
6763
+ ],
6764
+ "@absolutejs/sync/*": [
6765
+ "./node_modules/@absolutejs/sync/dist/*"
6766
+ ]
6767
+ } : {},
6517
6768
  "*": [
6518
6769
  "./node_modules/*",
6519
6770
  `${portableRelative2(project, projectRoot)}/node_modules/*`
@@ -6551,6 +6802,9 @@ var writeAbsoluteExpoProject = async (config, options) => {
6551
6802
  throw new TypeError("Expo project generation requires mobile.engine: expo.");
6552
6803
  const projectRoot = resolve12(options.projectRoot);
6553
6804
  const project = config.nativeProjectDirectory;
6805
+ const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
6806
+ const syncEnabled = Boolean(auth && projectUsesAbsoluteSync(projectRoot));
6807
+ const syncSchema = syncEnabled ? { components: discoverAbsoluteSyncSchema(projectRoot).components } : undefined;
6554
6808
  const routeModules = Object.entries(config.expoNativeRoutes);
6555
6809
  const moduleChecks = await Promise.all(routeModules.map(async ([route, module]) => ({
6556
6810
  exists: await exists3(module),
@@ -6571,6 +6825,7 @@ var writeAbsoluteExpoProject = async (config, options) => {
6571
6825
  await mkdir11(project, { recursive: true });
6572
6826
  await writeFile12(marker, `format=1
6573
6827
  `);
6828
+ const authEnabled = Boolean(auth);
6574
6829
  const files = new Map([
6575
6830
  [
6576
6831
  join14(project, ".gitignore"),
@@ -6580,9 +6835,15 @@ ios/
6580
6835
  node_modules/
6581
6836
  `
6582
6837
  ],
6583
- [join14(project, "app.json"), jsonSource(expoAppConfig(config))],
6838
+ [
6839
+ join14(project, "app.json"),
6840
+ jsonSource(expoAppConfig(config, authEnabled, syncEnabled))
6841
+ ],
6584
6842
  [join14(project, "app.config.js"), expoDynamicAppConfig],
6585
- [join14(project, "package.json"), jsonSource(expoPackage())],
6843
+ [
6844
+ join14(project, "package.json"),
6845
+ jsonSource(expoPackage(authEnabled, syncEnabled))
6846
+ ],
6586
6847
  [join14(project, "metro.config.js"), metroConfig(projectRoot)],
6587
6848
  [
6588
6849
  join14(project, "plugins", "withAbsoluteDevelopmentCa.js"),
@@ -6590,18 +6851,27 @@ node_modules/
6590
6851
  ],
6591
6852
  [
6592
6853
  join14(project, "tsconfig.json"),
6593
- jsonSource(expoTsConfig(projectRoot, project))
6854
+ jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
6855
+ ],
6856
+ [
6857
+ join14(project, "app", "_layout.tsx"),
6858
+ layoutSource(authEnabled, syncEnabled)
6594
6859
  ],
6595
- [join14(project, "app", "_layout.tsx"), layoutSource],
6596
6860
  [
6597
6861
  join14(project, "app", "__absolute", "native", "index.tsx"),
6598
6862
  nativeDiagnosticSource
6599
6863
  ],
6600
6864
  [
6601
6865
  join14(project, "src", "generated", "AbsoluteWebHost.tsx"),
6602
- webHostSource(config)
6866
+ webHostSource(config, auth, syncEnabled)
6603
6867
  ]
6604
6868
  ]);
6869
+ if (auth) {
6870
+ files.set(join14(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
6871
+ }
6872
+ if (syncSchema) {
6873
+ files.set(join14(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
6874
+ }
6605
6875
  const webAssetsPath = join14(project, "src", "generated", "webAssets.ts");
6606
6876
  if (!await exists3(webAssetsPath)) {
6607
6877
  files.set(webAssetsPath, emptyWebAssetsSource);
@@ -6800,9 +7070,6 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
6800
7070
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
6801
7071
  });
6802
7072
  const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
6803
- if (mobile.engine === "expo" && auth) {
6804
- throw new TypeError("Expo mobile Auth is not released yet. The experimental Expo shell cannot safely substitute Capacitor credentials; remove engine: 'expo' or wait for @absolutejs/auth-expo.");
6805
- }
6806
7073
  const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
6807
7074
  const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
6808
7075
  const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
@@ -6964,11 +7231,31 @@ var installAbsoluteMobileSyncRemediation = (bridge = {
6964
7231
  init_deviceCapabilities();
6965
7232
 
6966
7233
  // src/mobile/expoBridge.ts
6967
- var ABSOLUTE_EXPO_BRIDGE_FORMAT = 1;
7234
+ var ABSOLUTE_EXPO_BRIDGE_FORMAT = 3;
6968
7235
  var ABSOLUTE_EXPO_BRIDGE_MAX_BYTES = 64 * 1024;
6969
7236
  var ABSOLUTE_EXPO_BRIDGE_METHODS = [
6970
7237
  "devices.haptics.impact",
6971
- "http.fetch"
7238
+ "http.fetch",
7239
+ "auth.signIn",
7240
+ "auth.signOut",
7241
+ "auth.status",
7242
+ "sync.store.begin",
7243
+ "sync.store.deleteNamespace",
7244
+ "sync.store.end",
7245
+ "sync.store.schema",
7246
+ "sync.tx.deleteCollection",
7247
+ "sync.tx.deleteMutation",
7248
+ "sync.tx.getCollection",
7249
+ "sync.tx.getInstallationId",
7250
+ "sync.tx.getMutation",
7251
+ "sync.tx.listCollections",
7252
+ "sync.tx.listMutations",
7253
+ "sync.tx.putCollection",
7254
+ "sync.tx.putMutation",
7255
+ "sync.tx.setInstallationId",
7256
+ "sync.socket.close",
7257
+ "sync.socket.open",
7258
+ "sync.socket.sendChunk"
6972
7259
  ];
6973
7260
  var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
6974
7261
  var validId = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,80}$/u.test(value);
@@ -7008,15 +7295,27 @@ var parseRequest = (value) => {
7008
7295
  const loopbackHttp = url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]");
7009
7296
  if (url.protocol !== "https:" && !loopbackHttp)
7010
7297
  throw new TypeError("Expo bridge HTTP URL must use HTTPS.");
7011
- if (value.params.method !== "GET")
7298
+ if (typeof value.params.method !== "string" || !["DELETE", "GET", "PATCH", "POST", "PUT"].includes(value.params.method))
7012
7299
  throw new TypeError("Expo bridge HTTP method is not allowed.");
7300
+ if (value.params.body !== undefined && typeof value.params.body !== "string")
7301
+ throw new TypeError("Expo bridge HTTP body is invalid.");
7302
+ if (typeof value.params.body === "string" && new TextEncoder().encode(value.params.body).byteLength > 48 * 1024)
7303
+ throw new TypeError("Expo bridge HTTP body exceeds 48 KiB.");
7304
+ if ((value.params.method === "GET" || value.params.method === "DELETE") && value.params.body !== undefined)
7305
+ throw new TypeError("Expo bridge HTTP method cannot contain a body.");
7013
7306
  if (!isRecord8(value.params.headers))
7014
7307
  throw new TypeError("Expo bridge HTTP headers must be an object.");
7015
- const headersAllowed = Object.entries(value.params.headers).every(([name, header]) => typeof header === "string" && (name.toLowerCase() === "accept" || name.toLowerCase().startsWith("x-absolute-mobile-")));
7308
+ const headersAllowed = Object.entries(value.params.headers).every(([name, header]) => typeof header === "string" && (name.toLowerCase() === "accept" || name.toLowerCase() === "content-type" || name.toLowerCase().startsWith("x-absolute-mobile-")));
7016
7309
  if (!headersAllowed) {
7017
7310
  throw new TypeError("Expo bridge HTTP header is not allowed.");
7018
7311
  }
7019
7312
  }
7313
+ if (method === "auth.signIn") {
7314
+ if (typeof value.params.email !== "string" || value.params.email.length > 320 || typeof value.params.signup !== "boolean")
7315
+ throw new TypeError("Expo bridge Auth sign-in params are invalid.");
7316
+ }
7317
+ if ((method === "auth.signOut" || method === "auth.status") && Object.keys(value.params).length !== 0)
7318
+ throw new TypeError("Expo bridge Auth params must be empty.");
7020
7319
  return {
7021
7320
  format: ABSOLUTE_EXPO_BRIDGE_FORMAT,
7022
7321
  id: value.id,
@@ -7055,7 +7354,7 @@ var parseResponse = (value) => {
7055
7354
  };
7056
7355
  };
7057
7356
  var parseEvent = (value) => {
7058
- if (value.event !== "ready" && value.event !== "navigation") {
7357
+ if (value.event !== "ready" && value.event !== "navigation" && value.event !== "auth.principal" && value.event !== "sync.socket" && value.event !== "sync.wake") {
7059
7358
  throw new TypeError("Expo bridge event is not allowed.");
7060
7359
  }
7061
7360
  if (typeof value.path !== "string" || !validPath(value.path))
@@ -7445,6 +7744,10 @@ var startAbsoluteExpoDevSession = async (options) => {
7445
7744
  throw error;
7446
7745
  }
7447
7746
  };
7747
+
7748
+ // src/mobile/index.ts
7749
+ init_config();
7750
+
7448
7751
  // src/mobile/ciWorkflow.ts
7449
7752
  import { existsSync as existsSync3 } from "fs";
7450
7753
  import { access as access11, mkdir as mkdir12, readFile as readFile16, writeFile as writeFile13 } from "fs/promises";
@@ -8667,6 +8970,10 @@ var applyAbsoluteNativeDeviceCapabilities = async (projectRoot, config, platform
8667
8970
  changed: results.filter(({ didChange }) => didChange).map(({ platform: platform2 }) => platform2)
8668
8971
  };
8669
8972
  };
8973
+
8974
+ // src/mobile/index.ts
8975
+ init_nativeAuth();
8976
+
8670
8977
  // src/mobile/releasePublisher.ts
8671
8978
  import { access as access12 } from "fs/promises";
8672
8979
  import { isAbsolute as isAbsolute6, relative as relative12, resolve as resolve15, sep as sep7 } from "path";
@@ -9500,157 +9807,163 @@ var http = createAbsoluteHttpClient();
9500
9807
  // src/mobile/shellHttp.ts
9501
9808
  var installAbsoluteMobileShellHttp = (origin, fetch2 = globalThis.fetch) => installAbsoluteHttpTransport(createAbsoluteHttpTransport({ fetch: fetch2, origin, runtime: "native" }));
9502
9809
  export {
9503
- writeAbsoluteMobileGithubWorkflow,
9504
- writeAbsoluteExpoProject,
9505
- writeAbsoluteCapacitorConfig,
9506
- waitForAbsoluteIosHmrLog,
9507
- verifyAbsoluteMobileCompatibilityProducer,
9508
- verifyAbsoluteMobileAssociationFiles,
9509
- validateAbsoluteSshDestination,
9510
- validateAbsoluteRemoteMacProfileName,
9511
- testAbsoluteIosPhysicalDevice,
9512
- syncAbsoluteRemoteMacProject,
9513
- syncAbsoluteExpoWebAssets,
9514
- startAbsoluteRemoteIosDevSession,
9515
- startAbsoluteRemoteExpoIosDevSession,
9516
- startAbsoluteIosTcpRelay,
9517
- startAbsoluteIosDevSession,
9518
- startAbsoluteIosCaEnrollmentServer,
9519
- startAbsoluteExpoDevSession,
9520
- serializeAbsoluteMobileAuthEnvironment,
9521
- runWithAbsoluteMobileProducer,
9522
- runAbsoluteAndroidUpgradeConformance,
9523
- retainAbsoluteMobileCompatibilityArtifacts,
9524
- resolveAbsoluteMobileRoute,
9525
- resolveAbsoluteMobileNavigation,
9526
- resolveAbsoluteMobileDeepLink,
9527
- resolveAbsoluteMobileCompatibilityRelease,
9528
- resolveAbsoluteMobileAuthManifest,
9529
- resolveAbsoluteDeviceCapabilityPlan,
9530
- repairAbsoluteIosDevSession,
9531
- removeAbsoluteRemoteMacProfile,
9532
- redactAbsoluteIosLog,
9533
- readAbsoluteMobileMaterializedReleases,
9534
- publishAbsoluteIosRelease,
9535
- publishAbsoluteAndroidRelease,
9536
- projectUsesAbsoluteSync,
9537
- projectUsesAbsoluteAuth,
9538
- projectImportsAbsoluteDeviceCapability,
9539
- prepareAbsoluteIosRelease,
9540
- prepareAbsoluteIosDevProject,
9541
- prepareAbsoluteAndroidRelease,
9542
- planAbsoluteExpoDevSession,
9543
- parseIosSimulators,
9544
- parseIosRuntimes,
9545
- parseIosDeviceTypes,
9546
- parseAbsoluteMobilePageRequest,
9547
- parseAbsoluteMobilePageEnvelope,
9548
- parseAbsoluteMobileCompatibilityArtifact,
9549
- parseAbsoluteMobileBuildPageMetadata,
9550
- parseAbsoluteIosLogLine,
9551
- parseAbsoluteIosHmrLog,
9552
- parseAbsoluteExpoBridgeMessage,
9553
- parseAbsoluteAndroidInstalledApp,
9554
- pairAbsoluteRemoteMac,
9555
- normalizeAbsoluteMobileConfig,
9556
- normalizeAbsoluteIosDeviceIdentifier,
9557
- normalizeAbsoluteIosDeviceHost,
9558
- navigateAbsoluteMobilePage,
9559
- missingAbsoluteDeviceCapabilityPackages,
9560
- materializeAbsoluteRemoteMacAgent,
9561
- materializeAbsoluteMobileCompatibilityBundle,
9562
- materializeAbsoluteMobileAssociationFiles,
9563
- materializeAbsoluteCapacitorWebBundle,
9564
- matchesAbsoluteMobileRoutePattern,
9565
- loadAbsoluteNativeReleasePublisher,
9566
- loadAbsoluteMobileMaterializedBundle,
9567
- loadAbsoluteDeviceCapabilityProviders,
9568
- listAbsoluteRemoteMacProfiles,
9569
- isAbsoluteIosNativeRootInput,
9570
- installAbsoluteRemoteMacAgent,
9571
- installAbsoluteMobileSyncRemediation,
9572
- installAbsoluteMobileShellHttp,
9573
- installAbsoluteMobileAuthEnvironment,
9574
- inspectAbsoluteRemoteMacLanHost,
9575
- inspectAbsoluteRemoteMac,
9576
- inspectAbsoluteMobileRouteMetadata,
9577
- inspectAbsoluteAndroidInstalledApp,
9578
- hashAbsoluteMobilePropsSchema,
9579
- getCurrentAbsoluteMobileProducerContext,
9580
- getAbsoluteRemoteMacProfile,
9581
- getAbsoluteMobileSyncRemediation,
9582
- fingerprintAbsoluteIosNativeProject,
9583
- fingerprintAbsoluteIosDevProject,
9584
- finalizeAbsoluteMobilePage,
9585
- finalizeAbsoluteMobileCompatibilityBuild,
9586
- fetchAbsoluteMobilePage,
9587
- disposeAbsoluteMobilePage,
9588
- discoverAbsoluteSyncSchema,
9589
- discoverAbsoluteDeviceCapabilities,
9590
- directAbsoluteProjectPackages,
9591
- createAbsoluteRemoteIosDevProject,
9592
- createAbsoluteRemoteExpoIosDevProject,
9593
- createAbsoluteMobileUpgradeResponse,
9594
- createAbsoluteMobileRouteMetadataPlugin,
9595
- createAbsoluteMobilePreviewPlugin,
9596
- createAbsoluteMobilePageRequest,
9597
- createAbsoluteMobilePageErrorResponse,
9598
- createAbsoluteMobileInvalidRequestResponse,
9599
- createAbsoluteMobileGithubWorkflow,
9600
- createAbsoluteMobileFileArtifactStore,
9601
- createAbsoluteMobileCompatibilityDispatcher,
9602
- createAbsoluteMobileCompatibilityArtifact,
9603
- createAbsoluteMobileBlobArtifactStore,
9604
- createAbsoluteMobileAuthManifest,
9605
- createAbsoluteMobileAssociationPlugin,
9606
- createAbsoluteMobileAssociationDocuments,
9607
- createAbsoluteIosNativeWatcher,
9608
- createAbsoluteExpoBridgeResponse,
9609
- createAbsoluteExpoBridgeError,
9610
- carryForwardAbsoluteMobileCompatibilityReleases,
9611
- captureAbsoluteRemoteMacCommand,
9612
- captureAbsoluteMobileRouteGraph,
9613
- buildAbsoluteMobileCompatibilityRelease,
9614
- buildAbsoluteIosRelease,
9615
- buildAbsoluteAndroidRelease,
9616
- assertAbsoluteDeviceCapabilityPackages,
9617
- applyAbsoluteNativeDeviceCapabilities,
9618
- applyAbsoluteNativeDeepLinks,
9619
- activateAbsoluteMobilePage,
9620
- acceptsAbsoluteMobilePage,
9621
- absoluteRemoteProjectSyncCommands,
9622
- absoluteRemoteMacSshBase,
9623
- absoluteMobilePreviewDocument,
9624
- absoluteIosDeviceAcceptanceCommands,
9625
- absoluteExpoExecutable,
9626
- absoluteDeviceNativeRequirements,
9627
- MOBILE_PAGE_REQUEST_HEADERS,
9628
- AbsoluteMobilePageProtocolError,
9629
- APPLE_ASSOCIATION_PATH,
9630
- ANDROID_ASSOCIATION_PATH,
9631
- ABSOLUTE_SYNC_PACKAGE,
9632
- ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION,
9633
- ABSOLUTE_REMOTE_MAC_EVENT_PREFIX,
9634
- ABSOLUTE_NATIVE_AUTH_SCOPES,
9635
- ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
9636
- ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL,
9637
- ABSOLUTE_MOBILE_ROUTE_DETAIL,
9638
- ABSOLUTE_MOBILE_RETAINED_GENERATIONS,
9639
- ABSOLUTE_MOBILE_PREVIEW_PATH,
9640
- ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
9641
- ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE,
9642
- ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
9643
- ABSOLUTE_MOBILE_COMPATIBILITY_FORMAT,
9644
- ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
9645
- ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT,
9646
- ABSOLUTE_IOS_SIMULATOR_NAME,
9647
- ABSOLUTE_IOS_RELEASE_FORMAT,
9648
- ABSOLUTE_EXPO_BRIDGE_METHODS,
9649
- ABSOLUTE_EXPO_BRIDGE_MAX_BYTES,
9650
- ABSOLUTE_EXPO_BRIDGE_FORMAT,
9810
+ ABSOLUTE_ANDROID_RELEASE_FORMAT,
9651
9811
  ABSOLUTE_AUTH_PACKAGE,
9652
- ABSOLUTE_ANDROID_RELEASE_FORMAT
9812
+ ABSOLUTE_EXPO_AUTH_CORE_VERSION,
9813
+ ABSOLUTE_EXPO_AUTH_PACKAGE,
9814
+ ABSOLUTE_EXPO_AUTH_VERSION,
9815
+ ABSOLUTE_EXPO_BRIDGE_FORMAT,
9816
+ ABSOLUTE_EXPO_BRIDGE_MAX_BYTES,
9817
+ ABSOLUTE_EXPO_BRIDGE_METHODS,
9818
+ ABSOLUTE_EXPO_SYNC_CORE_VERSION,
9819
+ ABSOLUTE_EXPO_SYNC_PACKAGE,
9820
+ ABSOLUTE_EXPO_SYNC_VERSION,
9821
+ ABSOLUTE_IOS_RELEASE_FORMAT,
9822
+ ABSOLUTE_IOS_SIMULATOR_NAME,
9823
+ ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT,
9824
+ ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
9825
+ ABSOLUTE_MOBILE_COMPATIBILITY_FORMAT,
9826
+ ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
9827
+ ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE,
9828
+ ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
9829
+ ABSOLUTE_MOBILE_PREVIEW_PATH,
9830
+ ABSOLUTE_MOBILE_RETAINED_GENERATIONS,
9831
+ ABSOLUTE_MOBILE_ROUTE_DETAIL,
9832
+ ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL,
9833
+ ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
9834
+ ABSOLUTE_NATIVE_AUTH_SCOPES,
9835
+ ABSOLUTE_REMOTE_MAC_EVENT_PREFIX,
9836
+ ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION,
9837
+ ABSOLUTE_SYNC_PACKAGE,
9838
+ ANDROID_ASSOCIATION_PATH,
9839
+ APPLE_ASSOCIATION_PATH,
9840
+ AbsoluteMobilePageProtocolError,
9841
+ MOBILE_PAGE_REQUEST_HEADERS,
9842
+ absoluteDeviceNativeRequirements,
9843
+ absoluteExpoExecutable,
9844
+ absoluteIosDeviceAcceptanceCommands,
9845
+ absoluteMobilePreviewDocument,
9846
+ absoluteRemoteMacSshBase,
9847
+ absoluteRemoteProjectSyncCommands,
9848
+ acceptsAbsoluteMobilePage,
9849
+ activateAbsoluteMobilePage,
9850
+ applyAbsoluteNativeDeepLinks,
9851
+ applyAbsoluteNativeDeviceCapabilities,
9852
+ assertAbsoluteDeviceCapabilityPackages,
9853
+ buildAbsoluteAndroidRelease,
9854
+ buildAbsoluteIosRelease,
9855
+ buildAbsoluteMobileCompatibilityRelease,
9856
+ captureAbsoluteMobileRouteGraph,
9857
+ captureAbsoluteRemoteMacCommand,
9858
+ carryForwardAbsoluteMobileCompatibilityReleases,
9859
+ createAbsoluteExpoBridgeError,
9860
+ createAbsoluteExpoBridgeResponse,
9861
+ createAbsoluteIosNativeWatcher,
9862
+ createAbsoluteMobileAssociationDocuments,
9863
+ createAbsoluteMobileAssociationPlugin,
9864
+ createAbsoluteMobileAuthManifest,
9865
+ createAbsoluteMobileBlobArtifactStore,
9866
+ createAbsoluteMobileCompatibilityArtifact,
9867
+ createAbsoluteMobileCompatibilityDispatcher,
9868
+ createAbsoluteMobileFileArtifactStore,
9869
+ createAbsoluteMobileGithubWorkflow,
9870
+ createAbsoluteMobileInvalidRequestResponse,
9871
+ createAbsoluteMobilePageErrorResponse,
9872
+ createAbsoluteMobilePageRequest,
9873
+ createAbsoluteMobilePreviewPlugin,
9874
+ createAbsoluteMobileRouteMetadataPlugin,
9875
+ createAbsoluteMobileUpgradeResponse,
9876
+ createAbsoluteRemoteExpoIosDevProject,
9877
+ createAbsoluteRemoteIosDevProject,
9878
+ directAbsoluteProjectPackages,
9879
+ discoverAbsoluteDeviceCapabilities,
9880
+ discoverAbsoluteSyncSchema,
9881
+ disposeAbsoluteMobilePage,
9882
+ fetchAbsoluteMobilePage,
9883
+ finalizeAbsoluteMobileCompatibilityBuild,
9884
+ finalizeAbsoluteMobilePage,
9885
+ fingerprintAbsoluteIosDevProject,
9886
+ fingerprintAbsoluteIosNativeProject,
9887
+ getAbsoluteMobileSyncRemediation,
9888
+ getAbsoluteRemoteMacProfile,
9889
+ getCurrentAbsoluteMobileProducerContext,
9890
+ hashAbsoluteMobilePropsSchema,
9891
+ inspectAbsoluteAndroidInstalledApp,
9892
+ inspectAbsoluteMobileRouteMetadata,
9893
+ inspectAbsoluteRemoteMac,
9894
+ inspectAbsoluteRemoteMacLanHost,
9895
+ installAbsoluteMobileAuthEnvironment,
9896
+ installAbsoluteMobileShellHttp,
9897
+ installAbsoluteMobileSyncRemediation,
9898
+ installAbsoluteRemoteMacAgent,
9899
+ isAbsoluteIosNativeRootInput,
9900
+ listAbsoluteRemoteMacProfiles,
9901
+ loadAbsoluteDeviceCapabilityProviders,
9902
+ loadAbsoluteMobileMaterializedBundle,
9903
+ loadAbsoluteNativeReleasePublisher,
9904
+ matchesAbsoluteMobileRoutePattern,
9905
+ materializeAbsoluteCapacitorWebBundle,
9906
+ materializeAbsoluteMobileAssociationFiles,
9907
+ materializeAbsoluteMobileCompatibilityBundle,
9908
+ materializeAbsoluteRemoteMacAgent,
9909
+ missingAbsoluteDeviceCapabilityPackages,
9910
+ navigateAbsoluteMobilePage,
9911
+ normalizeAbsoluteIosDeviceHost,
9912
+ normalizeAbsoluteIosDeviceIdentifier,
9913
+ normalizeAbsoluteMobileConfig,
9914
+ pairAbsoluteRemoteMac,
9915
+ parseAbsoluteAndroidInstalledApp,
9916
+ parseAbsoluteExpoBridgeMessage,
9917
+ parseAbsoluteIosHmrLog,
9918
+ parseAbsoluteIosLogLine,
9919
+ parseAbsoluteMobileBuildPageMetadata,
9920
+ parseAbsoluteMobileCompatibilityArtifact,
9921
+ parseAbsoluteMobilePageEnvelope,
9922
+ parseAbsoluteMobilePageRequest,
9923
+ parseIosDeviceTypes,
9924
+ parseIosRuntimes,
9925
+ parseIosSimulators,
9926
+ planAbsoluteExpoDevSession,
9927
+ prepareAbsoluteAndroidRelease,
9928
+ prepareAbsoluteIosDevProject,
9929
+ prepareAbsoluteIosRelease,
9930
+ projectImportsAbsoluteDeviceCapability,
9931
+ projectUsesAbsoluteAuth,
9932
+ projectUsesAbsoluteSync,
9933
+ publishAbsoluteAndroidRelease,
9934
+ publishAbsoluteIosRelease,
9935
+ readAbsoluteMobileMaterializedReleases,
9936
+ redactAbsoluteIosLog,
9937
+ removeAbsoluteRemoteMacProfile,
9938
+ repairAbsoluteIosDevSession,
9939
+ resolveAbsoluteDeviceCapabilityPlan,
9940
+ resolveAbsoluteMobileAuthManifest,
9941
+ resolveAbsoluteMobileCompatibilityRelease,
9942
+ resolveAbsoluteMobileDeepLink,
9943
+ resolveAbsoluteMobileNavigation,
9944
+ resolveAbsoluteMobileRoute,
9945
+ retainAbsoluteMobileCompatibilityArtifacts,
9946
+ runAbsoluteAndroidUpgradeConformance,
9947
+ runWithAbsoluteMobileProducer,
9948
+ serializeAbsoluteMobileAuthEnvironment,
9949
+ startAbsoluteExpoDevSession,
9950
+ startAbsoluteIosCaEnrollmentServer,
9951
+ startAbsoluteIosDevSession,
9952
+ startAbsoluteIosTcpRelay,
9953
+ startAbsoluteRemoteExpoIosDevSession,
9954
+ startAbsoluteRemoteIosDevSession,
9955
+ syncAbsoluteExpoWebAssets,
9956
+ syncAbsoluteRemoteMacProject,
9957
+ testAbsoluteIosPhysicalDevice,
9958
+ validateAbsoluteRemoteMacProfileName,
9959
+ validateAbsoluteSshDestination,
9960
+ verifyAbsoluteMobileAssociationFiles,
9961
+ verifyAbsoluteMobileCompatibilityProducer,
9962
+ waitForAbsoluteIosHmrLog,
9963
+ writeAbsoluteCapacitorConfig,
9964
+ writeAbsoluteExpoProject,
9965
+ writeAbsoluteMobileGithubWorkflow
9653
9966
  };
9654
9967
 
9655
- //# debugId=97C358B153ACDA7B64756E2164756E21
9968
+ //# debugId=735330FB398C20EB64756E2164756E21
9656
9969
  //# sourceMappingURL=index.js.map