@absolutejs/absolute 0.20.0-beta.4 → 0.20.0-beta.6

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/angular/components/core/streamingSlotRegistrar.js +1 -1
  2. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  3. package/dist/angular/index.js +341 -22
  4. package/dist/angular/index.js.map +8 -5
  5. package/dist/angular/server.js +341 -22
  6. package/dist/angular/server.js.map +8 -5
  7. package/dist/build.js +94 -22
  8. package/dist/build.js.map +9 -9
  9. package/dist/cli/index.js +986 -557
  10. package/dist/dev/client/cssUtils.ts +16 -2
  11. package/dist/dev/client/handlers/rebuild.ts +11 -1
  12. package/dist/dev/client/hmrTiming.ts +14 -7
  13. package/dist/index.js +364 -191
  14. package/dist/index.js.map +17 -17
  15. package/dist/mobile/browser.js +14 -1
  16. package/dist/mobile/browser.js.map +3 -3
  17. package/dist/mobile/index.js +588 -99
  18. package/dist/mobile/index.js.map +15 -13
  19. package/dist/mobile/remoteMacAgentEntry.js +8 -8
  20. package/dist/src/angular/pageHandler.d.ts +3 -0
  21. package/dist/src/cli/config/server.d.ts +1 -1
  22. package/dist/src/core/pageHandlers.d.ts +11 -2
  23. package/dist/src/mobile/androidEmulatorController.d.ts +6 -1
  24. package/dist/src/mobile/buildPipeline.d.ts +1 -0
  25. package/dist/src/mobile/capacitorBundle.d.ts +11 -1
  26. package/dist/src/mobile/client.d.ts +4 -0
  27. package/dist/src/mobile/index.d.ts +1 -0
  28. package/dist/src/mobile/nativeAuth.d.ts +17 -0
  29. package/dist/src/mobile/releaseArtifact.d.ts +2 -0
  30. package/dist/src/mobile/shellAuth.d.ts +8 -0
  31. package/dist/src/mobile/shellBootstrap.d.ts +11 -1
  32. package/dist/src/mobile/shellSync.d.ts +2 -0
  33. package/dist/src/mobile/staticDocument.d.ts +5 -0
  34. package/dist/src/mobile/transport.d.ts +9 -1
  35. package/dist/src/plugins/imageOptimizer.d.ts +1 -1
  36. package/dist/src/svelte/pageHandler.d.ts +3 -0
  37. package/dist/src/vue/pageHandler.d.ts +3 -0
  38. package/dist/svelte/index.js +312 -23
  39. package/dist/svelte/index.js.map +7 -4
  40. package/dist/svelte/server.js +307 -18
  41. package/dist/svelte/server.js.map +7 -4
  42. package/dist/vue/index.js +312 -23
  43. package/dist/vue/index.js.map +7 -4
  44. package/dist/vue/server.js +307 -18
  45. package/dist/vue/server.js.map +7 -4
  46. package/package.json +21 -9
@@ -159,6 +159,14 @@ var init_startupBanner = __esm(() => {
159
159
  ];
160
160
  });
161
161
 
162
+ // src/utils/stringModifiers.ts
163
+ 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) => {
164
+ if (!str.includes("-") && !str.includes("_")) {
165
+ return str.charAt(0).toUpperCase() + str.slice(1);
166
+ }
167
+ return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
168
+ };
169
+
162
170
  // src/mobile/artifactStore.ts
163
171
  import { createHash as createHash2 } from "crypto";
164
172
  import {
@@ -249,13 +257,19 @@ var parseCompatibilityPage = (value) => {
249
257
  if (!isCanonicalRecord(value) || !isPageFramework(value.framework)) {
250
258
  throw new TypeError("Compatibility artifact contains an invalid page.");
251
259
  }
260
+ const styleBundleHash = typeof value.styleBundleHash === "string" ? value.styleBundleHash : undefined;
261
+ const styleBundlePath = typeof value.styleBundlePath === "string" ? value.styleBundlePath : undefined;
262
+ if (Boolean(styleBundleHash) !== Boolean(styleBundlePath)) {
263
+ throw new TypeError("Compatibility page style hash and path must be provided together.");
264
+ }
252
265
  return {
253
266
  bundleHash: readString(value.bundleHash, "page.bundleHash"),
254
267
  bundlePath: readString(value.bundlePath, "page.bundlePath"),
255
268
  contract: readString(value.contract, "page.contract"),
256
269
  framework: value.framework,
257
270
  pageId: readString(value.pageId, "page.pageId"),
258
- propsSchemaHash: readString(value.propsSchemaHash, "page.propsSchemaHash")
271
+ propsSchemaHash: readString(value.propsSchemaHash, "page.propsSchemaHash"),
272
+ ...styleBundleHash && styleBundlePath ? { styleBundleHash, styleBundlePath } : {}
259
273
  };
260
274
  };
261
275
  var parseCompatibilityRoute = (value) => {
@@ -287,14 +301,23 @@ var validateProducerModule = (module) => {
287
301
  }
288
302
  return module;
289
303
  };
290
- var normalizePage = (page) => ({
291
- bundleHash: requireNonEmpty(page.bundleHash, "page.bundleHash"),
292
- bundlePath: requireNonEmpty(page.bundlePath, "page.bundlePath"),
293
- contract: requireNonEmpty(page.contract, "page.contract"),
294
- framework: page.framework,
295
- pageId: requireNonEmpty(page.pageId, "page.pageId"),
296
- propsSchemaHash: requireNonEmpty(page.propsSchemaHash, "page.propsSchemaHash")
297
- });
304
+ var normalizePage = (page) => {
305
+ if (Boolean(page.styleBundleHash) !== Boolean(page.styleBundlePath)) {
306
+ throw new TypeError("Compatibility page style hash and path must be provided together.");
307
+ }
308
+ return {
309
+ bundleHash: requireNonEmpty(page.bundleHash, "page.bundleHash"),
310
+ bundlePath: requireNonEmpty(page.bundlePath, "page.bundlePath"),
311
+ contract: requireNonEmpty(page.contract, "page.contract"),
312
+ framework: page.framework,
313
+ pageId: requireNonEmpty(page.pageId, "page.pageId"),
314
+ propsSchemaHash: requireNonEmpty(page.propsSchemaHash, "page.propsSchemaHash"),
315
+ ...page.styleBundleHash && page.styleBundlePath ? {
316
+ styleBundleHash: requireNonEmpty(page.styleBundleHash, "page.styleBundleHash"),
317
+ styleBundlePath: requireNonEmpty(page.styleBundlePath, "page.styleBundlePath")
318
+ } : {}
319
+ };
320
+ };
298
321
  var normalizeRoute = (route) => {
299
322
  if (!route.pattern.startsWith("/")) {
300
323
  throw new TypeError("route.pattern must start with /.");
@@ -1059,11 +1082,11 @@ var hashNativeTree = async (root, label, ignorePublicBundle) => {
1059
1082
  const records = await collectNativeDirectory(resolvedRoot, label, resolvedRoot, ignorePublicBundle);
1060
1083
  return createHash3("sha256").update(records.join("")).digest("hex");
1061
1084
  };
1062
- var fingerprintAbsoluteAndroidNativeProject = async (project) => {
1085
+ var fingerprintAbsoluteAndroidNativeProject = async (project, options = {}) => {
1063
1086
  const { dependencies } = await nativeDependencySources(project.nativeDirectory);
1064
1087
  const roots = [
1065
1088
  {
1066
- ignorePublicBundle: true,
1089
+ ignorePublicBundle: options.includePublicBundle !== true,
1067
1090
  label: "android",
1068
1091
  source: project.nativeDirectory
1069
1092
  },
@@ -3143,8 +3166,9 @@ var normalizeEntry = (entry) => {
3143
3166
  };
3144
3167
  var normalizeProductionOrigin = (value) => {
3145
3168
  const parsed = new URL(requireText(value, "mobile.server.productionOrigin"));
3146
- if (parsed.protocol !== "https:") {
3147
- throw new TypeError("mobile.server.productionOrigin must use HTTPS in production.");
3169
+ const isLoopbackHttp = parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1" || parsed.hostname === "[::1]");
3170
+ if (parsed.protocol !== "https:" && !isLoopbackHttp) {
3171
+ throw new TypeError("mobile.server.productionOrigin must use HTTPS, except for a loopback development origin.");
3148
3172
  }
3149
3173
  if (parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
3150
3174
  throw new TypeError("mobile.server.productionOrigin must be an origin without credentials, path, query, or hash.");
@@ -3168,9 +3192,8 @@ var normalizeHosts = (hosts, productionOrigin) => {
3168
3192
  }
3169
3193
  return value;
3170
3194
  };
3171
- const normalized = new Set([
3172
- normalizeHostname(new URL(productionOrigin).hostname)
3173
- ]);
3195
+ const productionHostname = new URL(productionOrigin).hostname;
3196
+ const normalized = new Set(productionHostname === "[::1]" ? [] : [normalizeHostname(productionHostname)]);
3174
3197
  for (const host of hosts ?? []) {
3175
3198
  normalized.add(normalizeHostname(host));
3176
3199
  }
@@ -3208,7 +3231,7 @@ var normalizeAbsoluteMobileConfig = (config, projectRoot) => {
3208
3231
  throw new TypeError("mobile.appId must use reverse-domain notation, for example com.example.app.");
3209
3232
  }
3210
3233
  const productionOrigin = normalizeProductionOrigin(config.server.productionOrigin);
3211
- const deepLinkScheme = config.deepLinks?.scheme?.trim().toLowerCase();
3234
+ const deepLinkScheme = (config.deepLinks?.scheme ?? appId).trim().toLowerCase();
3212
3235
  if (deepLinkScheme && !SCHEME_PATTERN.test(deepLinkScheme)) {
3213
3236
  throw new TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");
3214
3237
  }
@@ -3472,14 +3495,22 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
3472
3495
  };
3473
3496
  // src/mobile/buildPipeline.ts
3474
3497
  import { readFile as readFile13 } from "fs/promises";
3475
- import { join as join11, resolve as resolve10 } from "path";
3498
+ import { join as join12, resolve as resolve10 } from "path";
3476
3499
  import { pathToFileURL as pathToFileURL2 } from "url";
3477
3500
 
3478
3501
  // src/mobile/buildRelease.ts
3479
3502
  import { createHash as createHash8 } from "crypto";
3480
- import { readFile as readFile10 } from "fs/promises";
3481
- import { join as join8, relative as relative7, resolve as resolve8 } from "path";
3503
+ import { mkdir as mkdir8, readFile as readFile10, writeFile as writeFile9 } from "fs/promises";
3504
+ import { basename as basename2, dirname as dirname6, extname, join as join8, relative as relative7, resolve as resolve8 } from "path";
3482
3505
  var sha256 = (bytes) => createHash8("sha256").update(bytes).digest("hex");
3506
+ var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
3507
+ var rewriteStaticScriptPaths = (source, manifest) => source.replace(STATIC_SCRIPT_PATTERN, (match, prefix, path, suffix) => {
3508
+ if (path.endsWith("/htmx.min.js"))
3509
+ return match;
3510
+ const key = toPascal(basename2(path, extname(path)));
3511
+ const builtPath = manifest[key];
3512
+ return builtPath ? `${prefix}${builtPath}${suffix}` : match;
3513
+ });
3483
3514
  var readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]);
3484
3515
  var resolveAssetPath = (buildDirectory, assetPath) => {
3485
3516
  const resolvedBuildDirectory = resolve8(buildDirectory);
@@ -3494,16 +3525,38 @@ var pageFor = async (metadata, manifest, buildDirectory) => {
3494
3525
  if (!assetPath) {
3495
3526
  throw new TypeError(`Mobile page ${metadata.pageId} references missing manifest asset ${metadata.bundleKey}.`);
3496
3527
  }
3497
- const resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
3498
- const bytes = await readFile10(resolvedAssetPath);
3528
+ let resolvedAssetPath = resolveAssetPath(buildDirectory, assetPath);
3529
+ if (metadata.framework === "html" || metadata.framework === "htmx") {
3530
+ const source = await readFile10(resolvedAssetPath, "utf8");
3531
+ const rewritten = rewriteStaticScriptPaths(source, manifest);
3532
+ const documentHash = sha256(new TextEncoder().encode(rewritten));
3533
+ resolvedAssetPath = join8(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
3534
+ await mkdir8(dirname6(resolvedAssetPath), { recursive: true });
3535
+ await writeFile9(resolvedAssetPath, rewritten);
3536
+ }
3537
+ const pageAssetKey = metadata.bundleKey.replace(/Index$/u, "");
3538
+ const styleAssetPath = [
3539
+ `${pageAssetKey}BundledCSS`,
3540
+ `${pageAssetKey}CompiledCSS`
3541
+ ].map((key) => manifest[key]).find((path) => typeof path === "string");
3542
+ const resolvedStylePath = styleAssetPath ? resolveAssetPath(buildDirectory, styleAssetPath) : undefined;
3543
+ const [bytes, styleBytes] = await Promise.all([
3544
+ readFile10(resolvedAssetPath),
3545
+ resolvedStylePath ? readFile10(resolvedStylePath) : undefined
3546
+ ]);
3499
3547
  const bundlePath = `/${relative7(resolve8(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
3548
+ const styleBundlePath = resolvedStylePath ? `/${relative7(resolve8(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
3500
3549
  return {
3501
3550
  bundleHash: sha256(bytes),
3502
3551
  bundlePath,
3503
3552
  contract: metadata.contract,
3504
3553
  framework: metadata.framework,
3505
3554
  pageId: metadata.pageId,
3506
- propsSchemaHash: metadata.propsSchemaHash
3555
+ propsSchemaHash: metadata.propsSchemaHash,
3556
+ ...styleBytes && styleBundlePath ? {
3557
+ styleBundleHash: sha256(styleBytes),
3558
+ styleBundlePath
3559
+ } : {}
3507
3560
  };
3508
3561
  };
3509
3562
  var buildAbsoluteMobileCompatibilityRelease = async (options) => {
@@ -3525,11 +3578,19 @@ var buildAbsoluteMobileCompatibilityRelease = async (options) => {
3525
3578
  const pages = await Promise.all([...metadataByPage.values()].map((metadata) => pageFor(metadata, options.manifest, options.buildDirectory)));
3526
3579
  const producerHash = sha256(producerBytes);
3527
3580
  const appBuild = `ambuild_${sha256(new TextEncoder().encode(JSON.stringify({
3528
- pages: pages.map(({ bundleHash, bundlePath, contract, pageId }) => ({
3581
+ pages: pages.map(({
3582
+ bundleHash,
3583
+ bundlePath,
3584
+ contract,
3585
+ pageId,
3586
+ styleBundleHash,
3587
+ styleBundlePath
3588
+ }) => ({
3529
3589
  bundleHash,
3530
3590
  bundlePath,
3531
3591
  contract,
3532
- pageId
3592
+ pageId,
3593
+ ...styleBundleHash && styleBundlePath ? { styleBundleHash, styleBundlePath } : {}
3533
3594
  })),
3534
3595
  producerHash,
3535
3596
  runtime: options.runtime
@@ -3589,16 +3650,17 @@ var captureAbsoluteMobileRouteGraph = async (app) => {
3589
3650
 
3590
3651
  // src/mobile/capacitorBundle.ts
3591
3652
  import {
3653
+ cp,
3592
3654
  copyFile as copyFile5,
3593
- mkdir as mkdir8,
3655
+ mkdir as mkdir9,
3594
3656
  mkdtemp as mkdtemp4,
3595
3657
  readFile as readFile11,
3596
3658
  rename as rename9,
3597
3659
  rm as rm7,
3598
- writeFile as writeFile9
3660
+ writeFile as writeFile10
3599
3661
  } from "fs/promises";
3600
3662
  import { existsSync as existsSync2 } from "fs";
3601
- import { basename as basename2, dirname as dirname6, extname, join as join9, resolve as resolve9 } from "path";
3663
+ import { basename as basename3, dirname as dirname7, extname as extname2, join as join9, relative as relative8, resolve as resolve9 } from "path";
3602
3664
 
3603
3665
  // src/mobile/routeMatcher.ts
3604
3666
  var REGEXP_SPECIAL_CHARACTERS = /[.*+?^${}()|[\]\\]/g;
@@ -3871,6 +3933,13 @@ class AbsoluteMobilePageProtocolError extends Error {
3871
3933
  this.code = code;
3872
3934
  }
3873
3935
  }
3936
+ var disposeAbsoluteMobilePage = async (target = window) => {
3937
+ const dispose = target.__ABSOLUTE_PAGE_DISPOSE__;
3938
+ target.__ABSOLUTE_PAGE_DISPOSE__ = undefined;
3939
+ target.__ABSOLUTE_PAGE_READY__ = undefined;
3940
+ if (dispose)
3941
+ await dispose();
3942
+ };
3874
3943
  var frameworks4 = new Set([
3875
3944
  "angular",
3876
3945
  "ember",
@@ -3926,12 +3995,17 @@ var activateAbsoluteMobilePage = async (value, options) => {
3926
3995
  throw new AbsoluteMobilePageProtocolError("invalid-envelope", "Expected a renderable mobile page response.");
3927
3996
  }
3928
3997
  const target = options.target ?? window;
3998
+ await disposeAbsoluteMobilePage(target);
3929
3999
  target.__INITIAL_PROPS__ = envelope.response.props;
4000
+ target.__ABS_ANGULAR_REQUEST_CONTEXT__ = envelope.response.props;
3930
4001
  target.__ABSOLUTE_PAGE_RENDER_MODE__ = "client";
3931
4002
  await options.loadPage({
3932
4003
  contract: envelope.response.contract,
3933
4004
  pageId: envelope.response.pageId
3934
4005
  });
4006
+ if (target.__ABSOLUTE_PAGE_READY__) {
4007
+ await target.__ABSOLUTE_PAGE_READY__;
4008
+ }
3935
4009
  return {
3936
4010
  contract: envelope.response.contract,
3937
4011
  kind: "rendered",
@@ -4024,12 +4098,32 @@ var resolveAbsoluteMobileDeepLink = (manifest, value) => {
4024
4098
  }
4025
4099
  return `${url.pathname || "/"}${url.search}${url.hash}`;
4026
4100
  };
4101
+ var resolveAbsoluteMobileNavigation = (manifest, value, localOrigin) => {
4102
+ const url = new URL(value, `${localOrigin}/`);
4103
+ const local = new URL(localOrigin);
4104
+ const production = new URL(manifest.productionOrigin);
4105
+ const matches = (candidate, allowed) => candidate.protocol === allowed.protocol && candidate.host === allowed.host;
4106
+ if (!matches(url, local) && !matches(url, production)) {
4107
+ return;
4108
+ }
4109
+ return `${url.pathname}${url.search}${url.hash}`;
4110
+ };
4027
4111
 
4028
4112
  // src/mobile/capacitorBundle.ts
4029
4113
  var MANIFEST_FILE = "absolute-mobile-manifest.json";
4030
4114
  var BOOTSTRAP_FILE = "absolute-mobile-bootstrap.js";
4031
4115
  var INDEX_FILE = "index.html";
4032
- var CLIENT_IMPORT_PATTERN = /(?:\bfrom\s*|\bimport\s*\(\s*|\bimport\s*)["'](\/[^"']+)["']/gu;
4116
+ var CLIENT_CSS_DEPENDENCY_PATTERN = /(?:@import\s+(?:url\(\s*)?|url\(\s*)["']?((?:\/|\.\.\/|\.\/)[^"')\s]+)["']?\s*\)?/gu;
4117
+ var CLIENT_MARKUP_DEPENDENCY_PATTERN = /<(?:script\b[^>]*\bsrc|link\b[^>]*\bhref|img\b[^>]*\bsrc|source\b[^>]*\bsrcset)\s*=\s*["']((?:\/|\.\.\/|\.\/)[^"',\s]+)/giu;
4118
+ var CAPACITOR_CLIENT_FRAMEWORKS = new Set([
4119
+ "angular",
4120
+ "html",
4121
+ "htmx",
4122
+ "react",
4123
+ "svelte",
4124
+ "vue"
4125
+ ]);
4126
+ var CLIENT_ASSET_DIRECTORIES = ["assets", "html", "htmx", "indexes"];
4033
4127
  var errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code;
4034
4128
  var shellBootstrapModule = () => {
4035
4129
  const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync2);
@@ -4037,6 +4131,18 @@ var shellBootstrapModule = () => {
4037
4131
  return candidate;
4038
4132
  throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
4039
4133
  };
4134
+ var shellAuthModule = () => {
4135
+ const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellAuth.${extension}`)).find(existsSync2);
4136
+ if (candidate)
4137
+ return candidate;
4138
+ throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
4139
+ };
4140
+ var shellSyncModule = () => {
4141
+ const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellSync.${extension}`)).find(existsSync2);
4142
+ if (candidate)
4143
+ return candidate;
4144
+ throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
4145
+ };
4040
4146
  var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
4041
4147
  var indexHtml = (appName) => `<!doctype html>
4042
4148
  <html>
@@ -4060,11 +4166,16 @@ var sourceAssetPath = (buildDirectory, bundlePath) => {
4060
4166
  }
4061
4167
  return asset;
4062
4168
  };
4063
- var buildShellBootstrap = async (staging) => {
4169
+ var buildShellBootstrap = async (staging, auth, sync) => {
4064
4170
  const modulePath = shellBootstrapModule();
4171
+ const authImport = auth ? `import { createAbsoluteMobileShellAuth } from ${JSON.stringify(shellAuthModule())};
4172
+ ` : "";
4173
+ const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
4174
+ const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
4175
+ ` : "";
4065
4176
  const entryPath = join9(staging, ".absolute-mobile-entry.ts");
4066
- await writeFile9(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
4067
- void startAbsoluteMobileShell();
4177
+ await writeFile10(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
4178
+ ${authImport}${syncImport}void startAbsoluteMobileShell(${options});
4068
4179
  `);
4069
4180
  const build = await Bun.build({
4070
4181
  entrypoints: [entryPath],
@@ -4107,21 +4218,62 @@ var installBundle = async (staging, destination) => {
4107
4218
  }
4108
4219
  };
4109
4220
  var copyClientPage = async (page, buildDirectory, staging, copiedDependencies) => {
4110
- if (page.framework !== "react") {
4111
- throw new TypeError(`Capacitor spike currently supports React pages; ${page.pageId} is ${page.framework}.`);
4221
+ if (!CAPACITOR_CLIENT_FRAMEWORKS.has(page.framework)) {
4222
+ throw new TypeError(`Capacitor client rendering does not yet support ${page.framework} page ${page.pageId}.`);
4112
4223
  }
4113
- const extension = extname(page.bundlePath) || ".js";
4224
+ const extension = extname2(page.bundlePath) || ".js";
4114
4225
  const localBundlePath = `./pages/${page.bundleHash}${extension}`;
4115
4226
  const source = sourceAssetPath(buildDirectory, page.bundlePath);
4116
4227
  await copyFile5(source, join9(staging, localBundlePath));
4117
4228
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
4118
- return { ...page, localBundlePath };
4229
+ let localStylePath;
4230
+ if (page.styleBundlePath && page.styleBundleHash) {
4231
+ const styleExtension = extname2(page.styleBundlePath) || ".css";
4232
+ localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
4233
+ const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
4234
+ await mkdir9(dirname7(join9(staging, localStylePath)), {
4235
+ recursive: true
4236
+ });
4237
+ await copyFile5(styleSource, join9(staging, localStylePath));
4238
+ await copyAbsoluteClientDependencies(styleSource, buildDirectory, staging, copiedDependencies);
4239
+ }
4240
+ return {
4241
+ ...page,
4242
+ localBundlePath,
4243
+ ...localStylePath ? { localStylePath } : {}
4244
+ };
4119
4245
  };
4120
- var absoluteClientImports = async (sourcePath) => {
4246
+ var absoluteClientImports = async (sourcePath, buildDirectory) => {
4121
4247
  const source = await readFile11(sourcePath, "utf8");
4122
- return [...source.matchAll(CLIENT_IMPORT_PATTERN)].flatMap((match) => {
4123
- const [specifier] = match.slice(1);
4124
- return specifier ? [specifier.split(/[?#]/u, 1)[0] ?? specifier] : [];
4248
+ const extension = extname2(sourcePath).toLowerCase();
4249
+ let scriptLoader;
4250
+ if (extension === ".tsx")
4251
+ scriptLoader = "tsx";
4252
+ else if (extension === ".ts")
4253
+ scriptLoader = "ts";
4254
+ else if (extension === ".jsx")
4255
+ scriptLoader = "jsx";
4256
+ else if ([".js", ".mjs", ".cjs"].includes(extension))
4257
+ scriptLoader = "js";
4258
+ const scriptImports = scriptLoader ? new Bun.Transpiler({ loader: scriptLoader }).scanImports(source).map(({ path }) => path) : [];
4259
+ const cssImports = extension === ".css" ? [...source.matchAll(CLIENT_CSS_DEPENDENCY_PATTERN)].flatMap((match) => match[1] ?? []) : [];
4260
+ const markupImports = extension === ".html" ? [...source.matchAll(CLIENT_MARKUP_DEPENDENCY_PATTERN)].flatMap((match) => match[1] ?? []) : [];
4261
+ return [...scriptImports, ...cssImports, ...markupImports].flatMap((specifier) => {
4262
+ if (!specifier)
4263
+ return [];
4264
+ if (!specifier.startsWith("/") && !specifier.startsWith("./") && !specifier.startsWith("../")) {
4265
+ return [];
4266
+ }
4267
+ const clean = specifier.split(/[?#]/u, 1)[0] ?? specifier;
4268
+ if (clean.startsWith("/"))
4269
+ return [clean];
4270
+ const resolved = resolve9(dirname7(sourcePath), clean);
4271
+ const root = resolve9(buildDirectory);
4272
+ const relativePath = relative8(root, resolved).replaceAll("\\", "/");
4273
+ if (relativePath === ".." || relativePath.startsWith("../")) {
4274
+ throw new TypeError(`Mobile client dependency escaped the build directory: ${specifier}`);
4275
+ }
4276
+ return [`/${relativePath}`];
4125
4277
  });
4126
4278
  };
4127
4279
  var copyAbsoluteClientDependency = async (specifier, buildDirectory, staging, copied) => {
@@ -4130,12 +4282,12 @@ var copyAbsoluteClientDependency = async (specifier, buildDirectory, staging, co
4130
4282
  copied.add(specifier);
4131
4283
  const source = sourceAssetPath(buildDirectory, specifier);
4132
4284
  const destination = join9(staging, specifier.replace(/^\/+/, ""));
4133
- await mkdir8(dirname6(destination), { recursive: true });
4285
+ await mkdir9(dirname7(destination), { recursive: true });
4134
4286
  await copyFile5(source, destination);
4135
4287
  await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
4136
4288
  };
4137
4289
  var copyAbsoluteClientDependencies = async (sourcePath, buildDirectory, staging, copied) => {
4138
- const dependencies = await absoluteClientImports(sourcePath);
4290
+ const dependencies = await absoluteClientImports(sourcePath, buildDirectory);
4139
4291
  await Promise.all(dependencies.map((specifier) => copyAbsoluteClientDependency(specifier, buildDirectory, staging, copied)));
4140
4292
  };
4141
4293
  var materializeAbsoluteCapacitorWebBundle = async (options) => {
@@ -4143,15 +4295,20 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
4143
4295
  throw new TypeError(`mobile.entry ${options.config.entry} is not a captured mobile page route.`);
4144
4296
  }
4145
4297
  const destination = options.config.bundleDirectory;
4146
- await mkdir8(dirname6(destination), { recursive: true });
4147
- const staging = await mkdtemp4(join9(dirname6(destination), `.${basename2(destination)}.stage-`));
4298
+ await mkdir9(dirname7(destination), { recursive: true });
4299
+ const staging = await mkdtemp4(join9(dirname7(destination), `.${basename3(destination)}.stage-`));
4148
4300
  try {
4149
4301
  const pageDirectory = join9(staging, "pages");
4150
- await mkdir8(pageDirectory, { recursive: true });
4302
+ await mkdir9(pageDirectory, { recursive: true });
4303
+ await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
4304
+ destination: join9(staging, directory),
4305
+ source: join9(options.buildDirectory, directory)
4306
+ })).filter(({ source }) => existsSync2(source)).map(({ destination: assetDestination, source }) => cp(source, assetDestination, { recursive: true })));
4151
4307
  const copiedDependencies = new Set;
4152
4308
  const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
4153
4309
  const manifest = {
4154
4310
  appBuild: options.artifact.appBuild,
4311
+ ...options.auth ? { auth: options.auth } : {},
4155
4312
  appId: options.config.appId,
4156
4313
  appName: options.config.appName,
4157
4314
  deepLinkHosts: options.config.deepLinkHosts,
@@ -4161,13 +4318,14 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
4161
4318
  pages,
4162
4319
  productionOrigin: options.config.productionOrigin,
4163
4320
  routes: options.artifact.routes,
4164
- runtime: options.artifact.runtime
4321
+ runtime: options.artifact.runtime,
4322
+ ...options.sync ? { sync: { socketTickets: true } } : {}
4165
4323
  };
4166
4324
  await Promise.all([
4167
- writeFile9(join9(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
4325
+ writeFile10(join9(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
4168
4326
  `),
4169
- writeFile9(join9(staging, INDEX_FILE), indexHtml(options.config.appName)),
4170
- buildShellBootstrap(staging)
4327
+ writeFile10(join9(staging, INDEX_FILE), indexHtml(options.config.appName)),
4328
+ buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true)
4171
4329
  ]);
4172
4330
  await installBundle(staging, destination);
4173
4331
  return manifest;
@@ -4181,14 +4339,14 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
4181
4339
  import { createHash as createHash9 } from "crypto";
4182
4340
  import {
4183
4341
  access as access8,
4184
- mkdir as mkdir9,
4342
+ mkdir as mkdir10,
4185
4343
  mkdtemp as mkdtemp5,
4186
4344
  readFile as readFile12,
4187
4345
  rename as rename10,
4188
4346
  rm as rm8,
4189
- writeFile as writeFile10
4347
+ writeFile as writeFile11
4190
4348
  } from "fs/promises";
4191
- import { dirname as dirname7, join as join10, resolve as resolvePath3 } from "path";
4349
+ import { dirname as dirname8, join as join10, resolve as resolvePath3 } from "path";
4192
4350
  import { pathToFileURL } from "url";
4193
4351
  var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1;
4194
4352
  var CURRENT_BUNDLE_FILE = "current.json";
@@ -4230,11 +4388,11 @@ var parseBundleIndex = (value) => {
4230
4388
  var writeRelease = async (root, release) => {
4231
4389
  const directory = join10(root, release.artifact.releaseId);
4232
4390
  const producerPath = join10(directory, release.artifact.producer.module);
4233
- await mkdir9(dirname7(producerPath), { recursive: true });
4391
+ await mkdir10(dirname8(producerPath), { recursive: true });
4234
4392
  await Promise.all([
4235
- writeFile10(join10(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
4393
+ writeFile11(join10(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
4236
4394
  `),
4237
- writeFile10(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
4395
+ writeFile11(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
4238
4396
  ]);
4239
4397
  };
4240
4398
  var installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
@@ -4316,7 +4474,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
4316
4474
  });
4317
4475
  const root = resolvePath3(input.root);
4318
4476
  const bundlesRoot = join10(root, BUNDLES_DIRECTORY);
4319
- await mkdir9(bundlesRoot, { recursive: true });
4477
+ await mkdir10(bundlesRoot, { recursive: true });
4320
4478
  const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
4321
4479
  await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
4322
4480
  const index = {
@@ -4327,7 +4485,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
4327
4485
  };
4328
4486
  const pointerPath = join10(root, CURRENT_BUNDLE_FILE);
4329
4487
  const temporaryPointerPath = join10(root, `.current-${crypto.randomUUID()}.json`);
4330
- await writeFile10(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
4488
+ await writeFile11(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
4331
4489
  `, { flag: "wx" });
4332
4490
  await rename10(temporaryPointerPath, pointerPath);
4333
4491
  return index;
@@ -4354,6 +4512,58 @@ var readAbsoluteMobileMaterializedReleases = async (root) => {
4354
4512
  }
4355
4513
  };
4356
4514
 
4515
+ // src/mobile/nativeAuth.ts
4516
+ import { readFileSync as readFileSync2 } from "fs";
4517
+ import { join as join11 } from "path";
4518
+ var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth";
4519
+ var ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS";
4520
+ var ABSOLUTE_NATIVE_AUTH_SCOPES = ["openid", "profile"];
4521
+ var ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync";
4522
+ var readPackageManifest = (projectRoot) => {
4523
+ try {
4524
+ return JSON.parse(readFileSync2(join11(projectRoot, "package.json"), "utf8"));
4525
+ } catch {
4526
+ return;
4527
+ }
4528
+ };
4529
+ var packageManifestHas = (manifest, packageName) => {
4530
+ if (typeof manifest !== "object" || manifest === null)
4531
+ return false;
4532
+ return [
4533
+ Reflect.get(manifest, "dependencies"),
4534
+ Reflect.get(manifest, "devDependencies"),
4535
+ Reflect.get(manifest, "optionalDependencies"),
4536
+ Reflect.get(manifest, "peerDependencies")
4537
+ ].some((dependencies) => typeof dependencies === "object" && dependencies !== null && Object.hasOwn(dependencies, packageName));
4538
+ };
4539
+ var createAbsoluteMobileAuthManifest = (config) => {
4540
+ const scheme = config.deepLinkScheme ?? config.appId.toLowerCase();
4541
+ return {
4542
+ clientId: `absolutejs-native:${config.appId}`,
4543
+ issuer: config.productionOrigin,
4544
+ redirectUri: `${scheme}://auth/callback`,
4545
+ scopes: [...ABSOLUTE_NATIVE_AUTH_SCOPES]
4546
+ };
4547
+ };
4548
+ var installAbsoluteMobileAuthEnvironment = (projectRoot, config) => {
4549
+ const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
4550
+ const serialized = serializeAbsoluteMobileAuthEnvironment(config, auth);
4551
+ if (serialized === undefined)
4552
+ delete process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV];
4553
+ else
4554
+ process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV] = serialized;
4555
+ return auth;
4556
+ };
4557
+ var projectUsesAbsoluteAuth = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_AUTH_PACKAGE);
4558
+ var projectUsesAbsoluteSync = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_SYNC_PACKAGE);
4559
+ var resolveAbsoluteMobileAuthManifest = (projectRoot, config) => projectUsesAbsoluteAuth(projectRoot) ? createAbsoluteMobileAuthManifest(config) : undefined;
4560
+ var serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefined ? undefined : JSON.stringify([
4561
+ {
4562
+ ...auth,
4563
+ name: `${config.appName} native app`
4564
+ }
4565
+ ]);
4566
+
4357
4567
  // src/mobile/buildPipeline.ts
4358
4568
  var isElysiaApp = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "compile") === "function" && Array.isArray(Reflect.get(value, "routes"));
4359
4569
  var isStringRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
@@ -4364,12 +4574,11 @@ var serverExportName = (loaded, app) => {
4364
4574
  return "app";
4365
4575
  return "default";
4366
4576
  };
4367
- var restoreBuildDirectory = (previous) => {
4368
- if (previous !== undefined) {
4369
- process.env.ABSOLUTE_BUILD_DIR = previous;
4370
- return;
4371
- }
4372
- delete process.env.ABSOLUTE_BUILD_DIR;
4577
+ var restoreEnvironmentVariable = (name, previous) => {
4578
+ if (previous !== undefined)
4579
+ process.env[name] = previous;
4580
+ else
4581
+ delete process.env[name];
4373
4582
  };
4374
4583
  var requireRelease = (releases, releaseId) => {
4375
4584
  const release = releases.get(releaseId);
@@ -4391,9 +4600,9 @@ var loadServerApp = async (producerPath) => {
4391
4600
  var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
4392
4601
  const buildDirectory = resolve10(options.buildDirectory);
4393
4602
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
4394
- const root = join11(buildDirectory, ".absolutejs", "mobile-compatibility");
4603
+ const root = join12(buildDirectory, ".absolutejs", "mobile-compatibility");
4395
4604
  const [manifestSource, previous] = await Promise.all([
4396
- readFile13(join11(buildDirectory, "manifest.json"), "utf8"),
4605
+ readFile13(join12(buildDirectory, "manifest.json"), "utf8"),
4397
4606
  readAbsoluteMobileMaterializedReleases(root)
4398
4607
  ]);
4399
4608
  const manifest = JSON.parse(manifestSource);
@@ -4401,12 +4610,20 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
4401
4610
  throw new TypeError("Invalid AbsoluteJS build manifest for mobile capture.");
4402
4611
  }
4403
4612
  const previousBuildDirectory = process.env.ABSOLUTE_BUILD_DIR;
4613
+ const previousCompiledRuntime = process.env.ABSOLUTE_COMPILED_RUNTIME;
4614
+ const previousConfigPath = process.env.ABSOLUTE_CONFIG;
4404
4615
  process.env.ABSOLUTE_BUILD_DIR = buildDirectory;
4616
+ process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
4617
+ if (options.configPath) {
4618
+ process.env.ABSOLUTE_CONFIG = resolve10(options.projectRoot, options.configPath);
4619
+ }
4405
4620
  let loaded;
4406
4621
  try {
4407
4622
  loaded = await loadServerApp(resolve10(options.producerPath));
4408
4623
  } finally {
4409
- restoreBuildDirectory(previousBuildDirectory);
4624
+ restoreEnvironmentVariable("ABSOLUTE_BUILD_DIR", previousBuildDirectory);
4625
+ restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
4626
+ restoreEnvironmentVariable("ABSOLUTE_CONFIG", previousConfigPath);
4410
4627
  }
4411
4628
  const current = await buildAbsoluteMobileCompatibilityRelease({
4412
4629
  app: loaded.app,
@@ -4418,6 +4635,11 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
4418
4635
  producerPath: resolve10(options.producerPath),
4419
4636
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
4420
4637
  });
4638
+ const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
4639
+ const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
4640
+ if (auth && !loaded.app.routes.some((route) => route.path === "/.well-known/openid-configuration")) {
4641
+ throw new TypeError("@absolutejs/auth is installed, but its OIDC provider is not mounted. Native authentication requires the auth oidc configuration so AbsoluteJS can provision a public PKCE client.");
4642
+ }
4421
4643
  const releasesById = new Map([current, ...previous].map((release) => [
4422
4644
  release.artifact.releaseId,
4423
4645
  release
@@ -4430,8 +4652,10 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
4430
4652
  });
4431
4653
  await materializeAbsoluteCapacitorWebBundle({
4432
4654
  artifact: current.artifact,
4655
+ ...auth ? { auth } : {},
4433
4656
  buildDirectory,
4434
- config: mobile
4657
+ config: mobile,
4658
+ ...sync ? { sync: true } : {}
4435
4659
  });
4436
4660
  return current.artifact;
4437
4661
  };
@@ -4456,6 +4680,64 @@ var ensureProducerStorage = () => {
4456
4680
  var runWithAbsoluteMobileProducer = (context, callback) => ensureProducerStorage().run(context, callback);
4457
4681
 
4458
4682
  // src/mobile/compatibilityDispatcher.ts
4683
+ var MOBILE_WEBVIEW_ORIGINS = new Set([
4684
+ "capacitor://localhost",
4685
+ "http://localhost",
4686
+ "https://localhost"
4687
+ ]);
4688
+ var MOBILE_REQUEST_HEADER_NAMES = Object.values(MOBILE_PAGE_REQUEST_HEADERS);
4689
+ var MOBILE_CORS_ALLOW_HEADERS = [
4690
+ "accept",
4691
+ "content-type",
4692
+ "authorization",
4693
+ "hx-current-url",
4694
+ "hx-request",
4695
+ "hx-target",
4696
+ "hx-trigger",
4697
+ "hx-trigger-name",
4698
+ ...MOBILE_REQUEST_HEADER_NAMES
4699
+ ].join(", ");
4700
+ var MOBILE_CORS_METHODS = new Set([
4701
+ "DELETE",
4702
+ "GET",
4703
+ "HEAD",
4704
+ "OPTIONS",
4705
+ "PATCH",
4706
+ "POST",
4707
+ "PUT"
4708
+ ]);
4709
+ var mobileWebViewOrigin = (request) => {
4710
+ const origin = request.headers.get("origin");
4711
+ return origin && MOBILE_WEBVIEW_ORIGINS.has(origin) ? origin : undefined;
4712
+ };
4713
+ var applyMobileCorsHeaders = (response, origin) => {
4714
+ response.headers.set("access-control-allow-credentials", "true");
4715
+ response.headers.set("access-control-allow-origin", origin);
4716
+ response.headers.append("vary", "Origin");
4717
+ return response;
4718
+ };
4719
+ var mobilePreflightResponse = (request) => {
4720
+ if (request.method !== "OPTIONS")
4721
+ return;
4722
+ const origin = mobileWebViewOrigin(request);
4723
+ if (!origin)
4724
+ return;
4725
+ const requestedHeaders = request.headers.get("access-control-request-headers");
4726
+ const requestedMethod = request.headers.get("access-control-request-method")?.toUpperCase() ?? "";
4727
+ if (!MOBILE_CORS_METHODS.has(requestedMethod))
4728
+ return;
4729
+ return new Response(null, {
4730
+ headers: {
4731
+ "access-control-allow-credentials": "true",
4732
+ "access-control-allow-headers": requestedHeaders || MOBILE_CORS_ALLOW_HEADERS,
4733
+ "access-control-allow-methods": [...MOBILE_CORS_METHODS].join(", "),
4734
+ "access-control-allow-origin": origin,
4735
+ "access-control-max-age": "600",
4736
+ vary: "Origin, Access-Control-Request-Headers"
4737
+ },
4738
+ status: 204
4739
+ });
4740
+ };
4459
4741
  var artifactOwnsRequest = (artifact, pageId, request) => {
4460
4742
  const { pathname } = new URL(request.url);
4461
4743
  return artifact.routes.some((route) => route.pageId === pageId && route.method === request.method && matchesAbsoluteMobileRoutePattern(route.pattern, pathname));
@@ -4483,6 +4765,9 @@ var createAbsoluteMobileCompatibilityDispatcher = (options) => {
4483
4765
  return new Elysia2({ name: "absolutejs-mobile-compatibility-dispatcher" }).request(async ({ request }) => {
4484
4766
  if (getCurrentAbsoluteMobileProducerContext())
4485
4767
  return;
4768
+ const preflight = mobilePreflightResponse(request);
4769
+ if (preflight)
4770
+ return preflight;
4486
4771
  const parsed = parseAbsoluteMobilePageRequest(request);
4487
4772
  if (parsed.kind !== "mobile")
4488
4773
  return;
@@ -4506,11 +4791,16 @@ var createAbsoluteMobileCompatibilityDispatcher = (options) => {
4506
4791
  console.error(`[Mobile] Failed to load retained producer ${resolved.artifact.releaseId}:`, error);
4507
4792
  return createAbsoluteMobilePageErrorResponse(parsed.client.pageId);
4508
4793
  }
4794
+ }).afterHandle("global", ({ request, responseValue }) => {
4795
+ const origin = mobileWebViewOrigin(request);
4796
+ if (!origin || !(responseValue instanceof Response))
4797
+ return;
4798
+ applyMobileCorsHeaders(responseValue, origin);
4509
4799
  }).as("global");
4510
4800
  };
4511
4801
  // src/mobile/nativeDeepLinks.ts
4512
- import { readFile as readFile14, rename as rename11, writeFile as writeFile11 } from "fs/promises";
4513
- import { join as join12 } from "path";
4802
+ import { readFile as readFile14, rename as rename11, writeFile as writeFile12 } from "fs/promises";
4803
+ import { join as join13 } from "path";
4514
4804
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
4515
4805
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
4516
4806
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
@@ -4521,7 +4811,7 @@ var writeChangedFile = async (path, source) => {
4521
4811
  if (current === source)
4522
4812
  return false;
4523
4813
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
4524
- await writeFile11(temporary, source, { flag: "wx" });
4814
+ await writeFile12(temporary, source, { flag: "wx" });
4525
4815
  await rename11(temporary, path);
4526
4816
  return true;
4527
4817
  };
@@ -4567,7 +4857,7 @@ ${hosts}
4567
4857
  `;
4568
4858
  };
4569
4859
  var configureAndroid = async (config) => {
4570
- const path = join12(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
4860
+ const path = join13(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
4571
4861
  const source = await readFile14(path, "utf8");
4572
4862
  const mainActivity = source.indexOf('android:name=".MainActivity"');
4573
4863
  if (mainActivity === NOT_FOUND) {
@@ -4593,7 +4883,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
4593
4883
  ${END_MARKER}
4594
4884
  `;
4595
4885
  var configureIosInfo = async (config) => {
4596
- const path = join12(config.nativeProjectDirectory, "ios/App/App/Info.plist");
4886
+ const path = join13(config.nativeProjectDirectory, "ios/App/App/Info.plist");
4597
4887
  const source = await readFile14(path, "utf8");
4598
4888
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
4599
4889
  ${END_MARKER}
@@ -4617,7 +4907,7 @@ ${domains}
4617
4907
  `;
4618
4908
  };
4619
4909
  var configureIosEntitlements = async (config) => {
4620
- const path = join12(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
4910
+ const path = join13(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
4621
4911
  let current = "";
4622
4912
  try {
4623
4913
  current = await readFile14(path, "utf8");
@@ -4630,12 +4920,12 @@ var configureIosEntitlements = async (config) => {
4630
4920
  if (current === source)
4631
4921
  return false;
4632
4922
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
4633
- await writeFile11(temporary, source, { flag: "wx" });
4923
+ await writeFile12(temporary, source, { flag: "wx" });
4634
4924
  await rename11(temporary, path);
4635
4925
  return true;
4636
4926
  };
4637
4927
  var configureIosProject = async (config) => {
4638
- const path = join12(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
4928
+ const path = join13(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
4639
4929
  const source = await readFile14(path, "utf8");
4640
4930
  const declarations = [
4641
4931
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
@@ -4675,7 +4965,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
4675
4965
  };
4676
4966
  // src/mobile/releasePublisher.ts
4677
4967
  import { access as access9 } from "fs/promises";
4678
- import { isAbsolute as isAbsolute6, relative as relative8, resolve as resolve11, sep as sep6 } from "path";
4968
+ import { isAbsolute as isAbsolute6, relative as relative9, resolve as resolve11, sep as sep6 } from "path";
4679
4969
  import { pathToFileURL as pathToFileURL3 } from "url";
4680
4970
  var prepareAbsoluteIosRelease = async (publisher, options) => {
4681
4971
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -4703,7 +4993,7 @@ var isPublisher = (value) => isRecord8(value) && typeof value.publish === "funct
4703
4993
  var publisherModulePath = (projectRoot, requested) => {
4704
4994
  const root = resolve11(projectRoot);
4705
4995
  const path = resolve11(root, requested);
4706
- const projectRelative = relative8(root, path);
4996
+ const projectRelative = relative9(root, path);
4707
4997
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep6}`) || isAbsolute6(projectRelative)) {
4708
4998
  throw new TypeError("mobile publish --registry must remain inside the project.");
4709
4999
  }
@@ -4772,14 +5062,59 @@ var publishAbsoluteIosRelease = async (options) => {
4772
5062
  return publication;
4773
5063
  };
4774
5064
  // src/mobile/routeMetadataTransform.ts
4775
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
4776
- import { dirname as dirname8, extname as extname2, relative as relative9, resolve as resolve12 } from "path";
5065
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
5066
+ import { dirname as dirname9, extname as extname3, relative as relative10, resolve as resolve12 } from "path";
4777
5067
  import ts from "typescript";
4778
5068
  var ROUTE_METHODS = new Set(["get", "head"]);
4779
5069
  var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
4780
- var PAGE_HANDLER = "handleReactPageRequest";
5070
+ var PAGE_HANDLERS = new Map([
5071
+ [
5072
+ "handleHTMLPageRequest",
5073
+ { framework: "html", inputKind: "static", propsProperty: "props" }
5074
+ ],
5075
+ [
5076
+ "handleHTMXPageRequest",
5077
+ { framework: "htmx", inputKind: "static", propsProperty: "props" }
5078
+ ],
5079
+ [
5080
+ "handleAngularPageRequest",
5081
+ {
5082
+ bundleProperty: "indexPath",
5083
+ framework: "angular",
5084
+ propsProperty: "requestContext",
5085
+ sourceProperty: "pagePath"
5086
+ }
5087
+ ],
5088
+ [
5089
+ "handleReactPageRequest",
5090
+ {
5091
+ bundleProperty: "index",
5092
+ framework: "react",
5093
+ pageProperty: "Page",
5094
+ propsProperty: "props"
5095
+ }
5096
+ ],
5097
+ [
5098
+ "handleSveltePageRequest",
5099
+ {
5100
+ bundleProperty: "indexPath",
5101
+ framework: "svelte",
5102
+ propsProperty: "props",
5103
+ sourceProperty: "pagePath"
5104
+ }
5105
+ ],
5106
+ [
5107
+ "handleVuePageRequest",
5108
+ {
5109
+ bundleProperty: "indexPath",
5110
+ framework: "vue",
5111
+ propsProperty: "props",
5112
+ sourceProperty: "pagePath"
5113
+ }
5114
+ ]
5115
+ ]);
4781
5116
  var posixPath = (value) => value.replace(/\\/g, "/");
4782
- var findTsconfig = (entry, projectRoot) => ts.findConfigFile(dirname8(entry), existsSync3, "tsconfig.json") ?? ts.findConfigFile(projectRoot, existsSync3, "tsconfig.json");
5117
+ var findTsconfig = (entry, projectRoot) => ts.findConfigFile(dirname9(entry), existsSync3, "tsconfig.json") ?? ts.findConfigFile(projectRoot, existsSync3, "tsconfig.json");
4783
5118
  var createProgram = (entry, projectRoot) => {
4784
5119
  const configPath = findTsconfig(entry, projectRoot);
4785
5120
  if (!configPath) {
@@ -4791,7 +5126,7 @@ var createProgram = (entry, projectRoot) => {
4791
5126
  target: ts.ScriptTarget.ESNext
4792
5127
  });
4793
5128
  }
4794
- const parsed = ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, (path) => readFileSync2(path, "utf8")).config, ts.sys, dirname8(configPath));
5129
+ const parsed = ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, (path) => readFileSync3(path, "utf8")).config, ts.sys, dirname9(configPath));
4795
5130
  if (!parsed.fileNames.includes(entry))
4796
5131
  parsed.fileNames.push(entry);
4797
5132
  return ts.createProgram(parsed.fileNames, parsed.options);
@@ -4897,7 +5232,7 @@ var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
4897
5232
  const declaration = symbol?.declarations?.[0];
4898
5233
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
4899
5234
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
4900
- const source = posixPath(relative9(projectRoot, file));
5235
+ const source = posixPath(relative10(projectRoot, file));
4901
5236
  return `${source}#${exportedName}`;
4902
5237
  };
4903
5238
  var resolveAlias = (symbol, checker) => {
@@ -4929,13 +5264,108 @@ var assetKey = (expression, checker, seen = new Set) => {
4929
5264
  const [, key] = expression.arguments;
4930
5265
  return key && ts.isStringLiteralLike(key) ? key.text : undefined;
4931
5266
  };
5267
+ var staticString = (expression, bindings) => {
5268
+ if (ts.isStringLiteralLike(expression))
5269
+ return expression.text;
5270
+ if (ts.isIdentifier(expression))
5271
+ return bindings.get(expression.text);
5272
+ if (ts.isNoSubstitutionTemplateLiteral(expression))
5273
+ return expression.text;
5274
+ if (!ts.isTemplateExpression(expression))
5275
+ return;
5276
+ let value = expression.head.text;
5277
+ for (const span of expression.templateSpans) {
5278
+ const substitution = staticString(span.expression, bindings);
5279
+ if (substitution === undefined)
5280
+ return;
5281
+ value += substitution + span.literal.text;
5282
+ }
5283
+ return value;
5284
+ };
5285
+ var assetKeyWithBindings = (expression, checker, bindings = new Map) => {
5286
+ if (!expression)
5287
+ return;
5288
+ if (ts.isCallExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "asset") {
5289
+ const [, key] = expression.arguments;
5290
+ return key ? staticString(key, bindings) : undefined;
5291
+ }
5292
+ return assetKey(expression, checker);
5293
+ };
5294
+ var callableObject = (call, checker) => {
5295
+ const symbol = checker.getSymbolAtLocation(call.expression);
5296
+ const resolved = symbol ? resolveAlias(symbol, checker) : undefined;
5297
+ const declaration = resolved?.valueDeclaration ?? resolved?.declarations?.[0];
5298
+ let callable;
5299
+ if (declaration && ts.isFunctionDeclaration(declaration)) {
5300
+ callable = declaration;
5301
+ } else if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer && (ts.isArrowFunction(declaration.initializer) || ts.isFunctionExpression(declaration.initializer))) {
5302
+ callable = declaration.initializer;
5303
+ }
5304
+ if (!callable)
5305
+ return;
5306
+ const bindings = new Map;
5307
+ callable.parameters.forEach((parameter, index) => {
5308
+ if (!ts.isIdentifier(parameter.name))
5309
+ return;
5310
+ const argument = call.arguments[index];
5311
+ if (!argument)
5312
+ return;
5313
+ const value = staticString(argument, new Map);
5314
+ if (value !== undefined)
5315
+ bindings.set(parameter.name.text, value);
5316
+ });
5317
+ const { body } = callable;
5318
+ if (!body)
5319
+ return;
5320
+ const expressionBody = ts.isParenthesizedExpression(body) ? body.expression : body;
5321
+ if (ts.isObjectLiteralExpression(expressionBody)) {
5322
+ return { bindings, object: expressionBody };
5323
+ }
5324
+ if (ts.isBlock(body)) {
5325
+ const returned = body.statements.find(ts.isReturnStatement)?.expression;
5326
+ if (returned && ts.isObjectLiteralExpression(returned)) {
5327
+ return { bindings, object: returned };
5328
+ }
5329
+ }
5330
+ return;
5331
+ };
5332
+ var spreadObject = (expression, checker, bindings) => {
5333
+ if (ts.isObjectLiteralExpression(expression)) {
5334
+ return { bindings, object: expression };
5335
+ }
5336
+ if (!ts.isCallExpression(expression))
5337
+ return;
5338
+ return callableObject(expression, checker);
5339
+ };
5340
+ var objectAssetKey = (object, name, checker, bindings = new Map) => {
5341
+ for (const property of [...object.properties].reverse()) {
5342
+ if (propertyName(property) === name && ts.isShorthandPropertyAssignment(property)) {
5343
+ return assetKeyWithBindings(property.name, checker, bindings);
5344
+ }
5345
+ if (propertyName(property) === name && ts.isPropertyAssignment(property)) {
5346
+ return assetKeyWithBindings(property.initializer, checker, bindings);
5347
+ }
5348
+ if (!ts.isSpreadAssignment(property))
5349
+ continue;
5350
+ const nestedObject = spreadObject(property.expression, checker, bindings);
5351
+ if (!nestedObject)
5352
+ continue;
5353
+ const nested = objectAssetKey(nestedObject.object, name, checker, nestedObject.bindings);
5354
+ if (nested)
5355
+ return nested;
5356
+ }
5357
+ return;
5358
+ };
4932
5359
  var findPageCall = (nodes) => {
4933
5360
  let found;
4934
5361
  const visit = (candidate) => {
4935
5362
  if (found)
4936
5363
  return;
4937
- if (ts.isCallExpression(candidate) && ts.isIdentifier(candidate.expression) && candidate.expression.text === PAGE_HANDLER) {
4938
- found = candidate;
5364
+ if (ts.isCallExpression(candidate) && ts.isIdentifier(candidate.expression) && PAGE_HANDLERS.has(candidate.expression.text)) {
5365
+ const definition = PAGE_HANDLERS.get(candidate.expression.text);
5366
+ if (!definition)
5367
+ return;
5368
+ found = { definition, node: candidate };
4939
5369
  return;
4940
5370
  }
4941
5371
  ts.forEachChild(candidate, visit);
@@ -4954,30 +5384,67 @@ var analyzeRouteCall = (node, sourceFile, checker, projectRoot) => {
4954
5384
  const [routePath] = node.arguments;
4955
5385
  if (!routePath || !ts.isStringLiteralLike(routePath))
4956
5386
  return;
4957
- const pageCall = findPageCall(node.arguments.slice(1));
5387
+ const foundPageCall = findPageCall(node.arguments.slice(1));
5388
+ const pageCall = foundPageCall?.node;
5389
+ const definition = foundPageCall?.definition;
4958
5390
  const [input] = pageCall?.arguments ?? [];
4959
- if (!pageCall || !input || !ts.isObjectLiteralExpression(input)) {
5391
+ if (!pageCall || !input) {
4960
5392
  return;
4961
5393
  }
4962
- const page = objectPropertyExpression(input, "Page");
4963
- if (!page)
5394
+ if (!definition)
5395
+ return;
5396
+ if (definition.inputKind === "static") {
5397
+ const bundleKey2 = assetKey(input, checker);
5398
+ if (!bundleKey2)
5399
+ return;
5400
+ const pageId2 = `${definition.framework}:${bundleKey2}`;
5401
+ const propsSchemaHash2 = hashAbsoluteMobilePropsSchema({
5402
+ properties: {},
5403
+ type: "object"
5404
+ });
5405
+ return {
5406
+ inputKind: "static",
5407
+ metadata: {
5408
+ bundleKey: bundleKey2,
5409
+ contract: `${definition.framework}:${pageId2}:${propsSchemaHash2}`,
5410
+ framework: definition.framework,
5411
+ pageId: pageId2,
5412
+ propsSchemaHash: propsSchemaHash2
5413
+ },
5414
+ pageCallStart: pageCall.getStart(sourceFile),
5415
+ routeCallSpan: `${node.getStart(sourceFile)}:${node.end}`
5416
+ };
5417
+ }
5418
+ if (!ts.isObjectLiteralExpression(input) || !definition.bundleProperty) {
5419
+ return;
5420
+ }
5421
+ const page = definition.pageProperty ? objectPropertyExpression(input, definition.pageProperty) : undefined;
5422
+ const source = definition.sourceProperty ? objectAssetKey(input, definition.sourceProperty, checker) : undefined;
5423
+ if (definition.pageProperty && !page)
5424
+ return;
5425
+ if (definition.sourceProperty && !source)
4964
5426
  return;
4965
- const props = objectPropertyExpression(input, "props");
4966
- const index = objectPropertyExpression(input, "index");
4967
- const bundleKey = assetKey(index, checker);
5427
+ const props = objectPropertyExpression(input, definition.propsProperty);
5428
+ const bundleKey = objectAssetKey(input, definition.bundleProperty, checker);
4968
5429
  if (!bundleKey)
4969
5430
  return;
4970
- const pageId = resolvePageIdentity(page, sourceFile, checker, projectRoot);
4971
- const schema = serializeType(pagePropsType(page, props, checker), checker);
5431
+ const pageId = page ? resolvePageIdentity(page, sourceFile, checker, projectRoot) : `${definition.framework}:${source}`;
5432
+ let propsType;
5433
+ if (page)
5434
+ propsType = pagePropsType(page, props, checker);
5435
+ else if (props)
5436
+ propsType = checker.getTypeAtLocation(props);
5437
+ const schema = propsType ? serializeType(propsType, checker) : { properties: {}, type: "object" };
4972
5438
  const propsSchemaHash = hashAbsoluteMobilePropsSchema(schema);
4973
5439
  const metadata = {
4974
5440
  bundleKey,
4975
- contract: `react:${pageId}:${propsSchemaHash}`,
4976
- framework: "react",
5441
+ contract: `${definition.framework}:${pageId}:${propsSchemaHash}`,
5442
+ framework: definition.framework,
4977
5443
  pageId,
4978
5444
  propsSchemaHash
4979
5445
  };
4980
5446
  const result = {
5447
+ inputKind: "object",
4981
5448
  metadata,
4982
5449
  pageCallStart: pageCall.getStart(sourceFile),
4983
5450
  routeCallSpan: `${node.getStart(sourceFile)}:${node.end}`
@@ -5034,6 +5501,16 @@ var routeOptions = (existing, metadata) => {
5034
5501
  var transformPageCall = (node, page) => {
5035
5502
  if (!page)
5036
5503
  return;
5504
+ if (page.inputKind === "static") {
5505
+ const [pagePath, existingOptions, ...rest] = node.arguments;
5506
+ if (!pagePath)
5507
+ return;
5508
+ const options = ts.factory.createObjectLiteralExpression([
5509
+ ...existingOptions ? [ts.factory.createSpreadAssignment(existingOptions)] : [],
5510
+ ts.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
5511
+ ]);
5512
+ return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [pagePath, options, ...rest]);
5513
+ }
5037
5514
  const [input] = node.arguments;
5038
5515
  if (!input || !ts.isObjectLiteralExpression(input))
5039
5516
  return;
@@ -5100,7 +5577,7 @@ var createAbsoluteMobileRouteMetadataPlugin = (options) => {
5100
5577
  const source = await Bun.file(path).text();
5101
5578
  return {
5102
5579
  contents: transformFile(source, path, analysis),
5103
- loader: extname2(path).endsWith("x") ? "tsx" : "ts"
5580
+ loader: extname3(path).endsWith("x") ? "tsx" : "ts"
5104
5581
  };
5105
5582
  });
5106
5583
  }
@@ -5111,7 +5588,7 @@ var inspectAbsoluteMobileRouteMetadata = (options) => {
5111
5588
  const entry = resolve12(options.entry);
5112
5589
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
5113
5590
  return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
5114
- file: posixPath(relative9(projectRoot, file)),
5591
+ file: posixPath(relative10(projectRoot, file)),
5115
5592
  metadata
5116
5593
  })));
5117
5594
  };
@@ -5125,17 +5602,22 @@ export {
5125
5602
  syncAbsoluteRemoteMacProject,
5126
5603
  startAbsoluteRemoteIosDevSession,
5127
5604
  startAbsoluteIosDevSession,
5605
+ serializeAbsoluteMobileAuthEnvironment,
5128
5606
  runWithAbsoluteMobileProducer,
5129
5607
  retainAbsoluteMobileCompatibilityArtifacts,
5130
5608
  resolveAbsoluteMobileRoute,
5609
+ resolveAbsoluteMobileNavigation,
5131
5610
  resolveAbsoluteMobileDeepLink,
5132
5611
  resolveAbsoluteMobileCompatibilityRelease,
5612
+ resolveAbsoluteMobileAuthManifest,
5133
5613
  repairAbsoluteIosDevSession,
5134
5614
  removeAbsoluteRemoteMacProfile,
5135
5615
  redactAbsoluteIosLog,
5136
5616
  readAbsoluteMobileMaterializedReleases,
5137
5617
  publishAbsoluteIosRelease,
5138
5618
  publishAbsoluteAndroidRelease,
5619
+ projectUsesAbsoluteSync,
5620
+ projectUsesAbsoluteAuth,
5139
5621
  prepareAbsoluteIosRelease,
5140
5622
  prepareAbsoluteIosDevProject,
5141
5623
  prepareAbsoluteAndroidRelease,
@@ -5161,6 +5643,7 @@ export {
5161
5643
  listAbsoluteRemoteMacProfiles,
5162
5644
  isAbsoluteIosNativeRootInput,
5163
5645
  installAbsoluteRemoteMacAgent,
5646
+ installAbsoluteMobileAuthEnvironment,
5164
5647
  inspectAbsoluteRemoteMac,
5165
5648
  inspectAbsoluteMobileRouteMetadata,
5166
5649
  hashAbsoluteMobilePropsSchema,
@@ -5171,6 +5654,7 @@ export {
5171
5654
  finalizeAbsoluteMobilePage,
5172
5655
  finalizeAbsoluteMobileCompatibilityBuild,
5173
5656
  fetchAbsoluteMobilePage,
5657
+ disposeAbsoluteMobilePage,
5174
5658
  createAbsoluteRemoteIosDevProject,
5175
5659
  createAbsoluteMobileUpgradeResponse,
5176
5660
  createAbsoluteMobileRouteMetadataPlugin,
@@ -5181,6 +5665,7 @@ export {
5181
5665
  createAbsoluteMobileCompatibilityDispatcher,
5182
5666
  createAbsoluteMobileCompatibilityArtifact,
5183
5667
  createAbsoluteMobileBlobArtifactStore,
5668
+ createAbsoluteMobileAuthManifest,
5184
5669
  createAbsoluteMobileAssociationPlugin,
5185
5670
  createAbsoluteMobileAssociationDocuments,
5186
5671
  createAbsoluteIosNativeWatcher,
@@ -5198,8 +5683,11 @@ export {
5198
5683
  AbsoluteMobilePageProtocolError,
5199
5684
  APPLE_ASSOCIATION_PATH,
5200
5685
  ANDROID_ASSOCIATION_PATH,
5686
+ ABSOLUTE_SYNC_PACKAGE,
5201
5687
  ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION,
5202
5688
  ABSOLUTE_REMOTE_MAC_EVENT_PREFIX,
5689
+ ABSOLUTE_NATIVE_AUTH_SCOPES,
5690
+ ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
5203
5691
  ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL,
5204
5692
  ABSOLUTE_MOBILE_ROUTE_DETAIL,
5205
5693
  ABSOLUTE_MOBILE_RETAINED_GENERATIONS,
@@ -5210,8 +5698,9 @@ export {
5210
5698
  ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
5211
5699
  ABSOLUTE_IOS_SIMULATOR_NAME,
5212
5700
  ABSOLUTE_IOS_RELEASE_FORMAT,
5701
+ ABSOLUTE_AUTH_PACKAGE,
5213
5702
  ABSOLUTE_ANDROID_RELEASE_FORMAT
5214
5703
  };
5215
5704
 
5216
- //# debugId=5FE7B7589D1661C064756E2164756E21
5705
+ //# debugId=7AFC88B0A927AFE564756E2164756E21
5217
5706
  //# sourceMappingURL=index.js.map