@absolutejs/absolute 0.20.0-beta.16 → 0.20.0-beta.18

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.
@@ -168,7 +168,7 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
168
168
  };
169
169
 
170
170
  // node_modules/@absolutejs/sync/dist/client/index.js
171
- var RUNTIME_TRANSPORT, host, isRegistry = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations")), registry, SyncLocalDataPolicyError, SyncLocalStoreSchemaError, positiveVersion = (value, label) => {
171
+ 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) => {
172
172
  if (!Number.isSafeInteger(value) || value < 1)
173
173
  throw new SyncLocalStoreSchemaError("INVALID_PLAN", `${label} must be a positive safe integer`);
174
174
  return value;
@@ -189,6 +189,12 @@ var RUNTIME_TRANSPORT, host, isRegistry = (value) => typeof value === "object" &
189
189
  }
190
190
  for (const [index, rule] of (policy.mutations ?? []).entries()) {
191
191
  validatePolicyMatch(rule.match, `${label}.mutations[${index}]`);
192
+ if (rule.conflict !== undefined && rule.conflict.strategy !== "client-wins" && rule.conflict.strategy !== "manual" && rule.conflict.strategy !== "server-wins")
193
+ throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.strategy is invalid.`);
194
+ if (rule.conflict?.maxAttempts !== undefined && (!Number.isSafeInteger(rule.conflict.maxAttempts) || rule.conflict.maxAttempts < 1))
195
+ throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.maxAttempts must be a positive safe integer.`);
196
+ if (rule.conflict?.maxAttempts !== undefined && rule.conflict.strategy !== "client-wins")
197
+ throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.maxAttempts is only valid for client-wins.`);
192
198
  if (rule.persistence === "memory-only" && rule.protection === "required")
193
199
  throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}] cannot require at-rest protection when it is memory-only.`);
194
200
  if (rule.sensitivity !== undefined && rule.sensitivity !== "public" && rule.protection !== "required" && rule.persistence !== "memory-only")
@@ -254,7 +260,11 @@ var init_client = __esm(() => {
254
260
  const existing = host[RUNTIME_TRANSPORT];
255
261
  if (isRegistry(existing))
256
262
  return existing;
257
- const created = { installations: [] };
263
+ if (typeof existing === "object" && existing !== null && Array.isArray(Reflect.get(existing, "installations"))) {
264
+ Reflect.set(existing, "clients", []);
265
+ return existing;
266
+ }
267
+ const created = { clients: [], installations: [] };
258
268
  Object.defineProperty(host, RUNTIME_TRANSPORT, {
259
269
  configurable: false,
260
270
  enumerable: false,
@@ -442,6 +452,7 @@ var object = (value) => typeof value === "object" && value !== null && !Array.is
442
452
  const mutations = Array.isArray(mutationRules) ? mutationRules.map((entry, index) => {
443
453
  const rule = requireObject(entry, id, `localData.mutations[${index}] must be an object.`);
444
454
  const allowedRuleKeys = new Set([
455
+ "conflict",
445
456
  "match",
446
457
  "onProtectionUnavailable",
447
458
  "persistence",
@@ -455,6 +466,26 @@ var object = (value) => typeof value === "object" && value !== null && !Array.is
455
466
  const sensitivity = unknownField(rule, "sensitivity");
456
467
  const persistence = unknownField(rule, "persistence");
457
468
  const onProtectionUnavailable = unknownField(rule, "onProtectionUnavailable");
469
+ const declaredConflict = unknownField(rule, "conflict");
470
+ let conflict;
471
+ if (declaredConflict !== undefined) {
472
+ const conflictRecord = requireObject(declaredConflict, id, `localData.mutations[${index}].conflict must be an object.`);
473
+ const unsupportedConflictKey = Object.keys(conflictRecord).find((key) => key !== "maxAttempts" && key !== "strategy");
474
+ if (unsupportedConflictKey)
475
+ throw metadataError(id, `localData.mutations[${index}].conflict.${unsupportedConflictKey} is not supported.`);
476
+ const strategy = unknownField(conflictRecord, "strategy");
477
+ if (strategy !== "client-wins" && strategy !== "manual" && strategy !== "server-wins")
478
+ throw metadataError(id, `localData.mutations[${index}].conflict.strategy is invalid.`);
479
+ const maxAttempts = unknownField(conflictRecord, "maxAttempts");
480
+ if (maxAttempts !== undefined && strategy !== "client-wins")
481
+ throw metadataError(id, `localData.mutations[${index}].conflict.maxAttempts requires client-wins.`);
482
+ conflict = {
483
+ strategy,
484
+ ...maxAttempts === undefined ? {} : {
485
+ maxAttempts: positiveVersion2(maxAttempts, id, `localData.mutations[${index}].conflict.maxAttempts`)
486
+ }
487
+ };
488
+ }
458
489
  if (protection !== undefined && protection !== "none" && protection !== "required")
459
490
  throw metadataError(id, `localData.mutations[${index}].protection is invalid.`);
460
491
  if (sensitivity !== undefined && sensitivity !== "public" && sensitivity !== "private" && sensitivity !== "secret")
@@ -465,6 +496,7 @@ var object = (value) => typeof value === "object" && value !== null && !Array.is
465
496
  throw metadataError(id, `localData.mutations[${index}].persistence is invalid.`);
466
497
  return {
467
498
  match: nonEmpty(Reflect.get(rule, "match"), id, `localData.mutations[${index}].match`),
499
+ ...conflict ? { conflict } : {},
468
500
  ...sensitivity ? { sensitivity } : {},
469
501
  ...onProtectionUnavailable ? { onProtectionUnavailable } : {},
470
502
  ...persistence ? {
@@ -3895,7 +3927,7 @@ var parseAbsoluteMobileBuildPageMetadata = (value) => {
3895
3927
  };
3896
3928
  // src/mobile/buildPipeline.ts
3897
3929
  import { readFile as readFile13 } from "fs/promises";
3898
- import { join as join13, resolve as resolve11 } from "path";
3930
+ import { join as join14, resolve as resolve12 } from "path";
3899
3931
  import { pathToFileURL as pathToFileURL2 } from "url";
3900
3932
 
3901
3933
  // src/mobile/buildRelease.ts
@@ -4566,16 +4598,51 @@ var sourceAssetPath = (buildDirectory, bundlePath) => {
4566
4598
  }
4567
4599
  return asset;
4568
4600
  };
4569
- var buildShellBootstrap = async (staging, auth, sync) => {
4601
+ var importEntryTarget = (entry) => {
4602
+ if (typeof entry === "string")
4603
+ return entry;
4604
+ if (typeof entry === "object" && entry !== null)
4605
+ return Reflect.get(entry, "import");
4606
+ return;
4607
+ };
4608
+ var resolveProjectImport = async (projectRoot, specifier) => {
4609
+ const segments = specifier.split("/");
4610
+ const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
4611
+ const subpath = specifier.slice(packageName.length);
4612
+ const packageDirectory = join9(resolve9(projectRoot), "node_modules", packageName);
4613
+ const manifest = JSON.parse(await readFile11(join9(packageDirectory, "package.json"), "utf8"));
4614
+ const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
4615
+ const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
4616
+ const target = importEntryTarget(entry);
4617
+ if (typeof target !== "string" || !target.startsWith("./"))
4618
+ throw new TypeError(`${specifier} does not publish an import entry.`);
4619
+ const resolved = resolve9(packageDirectory, target);
4620
+ if (!resolved.startsWith(`${resolve9(packageDirectory)}/`))
4621
+ throw new TypeError(`${specifier} has an unsafe import entry.`);
4622
+ return resolved;
4623
+ };
4624
+ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, deviceCapabilities, projectRoot) => {
4570
4625
  const modulePath = shellBootstrapModule();
4571
4626
  const authImport = auth ? `import { createAbsoluteMobileShellAuth } from ${JSON.stringify(shellAuthModule())};
4572
4627
  ` : "";
4573
4628
  const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
4574
4629
  const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
4575
4630
  ` : "";
4631
+ const capabilityImports = (await Promise.all(deviceCapabilities.capabilities.map(async (name, index) => {
4632
+ const provider = deviceCapabilities.providers[name];
4633
+ if (!provider)
4634
+ throw new TypeError(`Missing device capability provider ${name}.`);
4635
+ return `import { ${provider.factory} as absoluteDeviceCapability${index} } from ${JSON.stringify(await resolveProjectImport(projectRoot, provider.module))};`;
4636
+ }))).join(`
4637
+ `);
4638
+ const capabilityOptions = deviceCapabilities.capabilities.map((name, index) => `${JSON.stringify(name)}: absoluteDeviceCapability${index}()`).join(", ");
4576
4639
  const entryPath = join9(staging, ".absolute-mobile-entry.ts");
4640
+ const baseAdapterModule = await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor");
4577
4641
  await writeFile10(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
4578
- ${authImport}${syncImport}void startAbsoluteMobileShell(${options});
4642
+ import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};
4643
+ ${authImport}${syncImport}${capabilityImports}
4644
+ installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });
4645
+ void startAbsoluteMobileShell(${options});
4579
4646
  `);
4580
4647
  const build = await Bun.build({
4581
4648
  entrypoints: [entryPath],
@@ -4713,6 +4780,7 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
4713
4780
  appName: options.config.appName,
4714
4781
  deepLinkHosts: options.config.deepLinkHosts,
4715
4782
  deepLinkScheme: options.config.deepLinkScheme,
4783
+ deviceCapabilities: options.deviceCapabilities.capabilities,
4716
4784
  entry: options.config.entry,
4717
4785
  format: ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
4718
4786
  pages,
@@ -4738,7 +4806,7 @@ var materializeAbsoluteCapacitorWebBundle = async (options) => {
4738
4806
  writeFile10(join9(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
4739
4807
  `),
4740
4808
  writeFile10(join9(staging, INDEX_FILE), indexHtml(options.config.appName)),
4741
- buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true)
4809
+ buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.deviceCapabilities, options.projectRoot)
4742
4810
  ]);
4743
4811
  await installBundle(staging, destination);
4744
4812
  return manifest;
@@ -4979,6 +5047,164 @@ var serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefine
4979
5047
 
4980
5048
  // src/mobile/buildPipeline.ts
4981
5049
  init_syncSchema();
5050
+
5051
+ // src/mobile/deviceCapabilities.ts
5052
+ import { readFileSync as readFileSync4 } from "fs";
5053
+ import { extname as extname3, join as join13, relative as relative9, resolve as resolve11 } from "path";
5054
+ import ts from "typescript";
5055
+ var DEVICES_PACKAGE = "@absolutejs/devices";
5056
+ var CAPACITOR_ADAPTER = "@absolutejs/devices-capacitor";
5057
+ var SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
5058
+ var IGNORED_DIRECTORIES = new Set([
5059
+ ".absolutejs",
5060
+ ".git",
5061
+ ".test-builds",
5062
+ ".test-shards",
5063
+ "build",
5064
+ "dist",
5065
+ "node_modules",
5066
+ "test",
5067
+ "tests"
5068
+ ]);
5069
+ var IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
5070
+ var CAPACITOR_MODULE_PATTERN = /^@absolutejs\/devices-capacitor\/[a-z][a-z0-9-]*$/u;
5071
+ var CAPACITOR_PACKAGE_PATTERN = /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u;
5072
+ var object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5073
+ var readJson = (path) => {
5074
+ const value = JSON.parse(readFileSync4(path, "utf8"));
5075
+ if (!object2(value))
5076
+ throw new TypeError(`${path} must contain an object.`);
5077
+ return value;
5078
+ };
5079
+ var text = (value, field) => {
5080
+ if (typeof value !== "string" || value.length === 0)
5081
+ throw new TypeError(`${field} must be a non-empty string.`);
5082
+ return value;
5083
+ };
5084
+ var parseProvider = (name, value) => {
5085
+ if (!IDENTIFIER_PATTERN.test(name))
5086
+ throw new TypeError("Device capability names must be identifiers.");
5087
+ if (!object2(value))
5088
+ throw new TypeError(`Device capability ${name} must be an object.`);
5089
+ const factory = text(value.factory, `${name}.factory`);
5090
+ const module = text(value.module, `${name}.module`);
5091
+ if (!IDENTIFIER_PATTERN.test(factory))
5092
+ throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
5093
+ if (!CAPACITOR_MODULE_PATTERN.test(module))
5094
+ throw new TypeError(`${name}.module must be an official devices-capacitor subpath.`);
5095
+ if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && CAPACITOR_PACKAGE_PATTERN.test(spec)))
5096
+ throw new TypeError(`${name}.packages must contain exact official Capacitor package versions.`);
5097
+ return { factory, module, packages: [...value.packages] };
5098
+ };
5099
+ var loadAbsoluteDeviceCapabilityProviders = (projectRoot) => {
5100
+ const path = join13(resolve11(projectRoot), "node_modules", CAPACITOR_ADAPTER, "package.json");
5101
+ const manifest = readJson(path);
5102
+ const { absolutejs } = manifest;
5103
+ const devices = object2(absolutejs) ? absolutejs.devices : undefined;
5104
+ if (!object2(devices) || devices.format !== 1 || devices.provider !== "capacitor" || !object2(devices.capabilities))
5105
+ throw new TypeError(`${CAPACITOR_ADAPTER} does not publish supported capability metadata.`);
5106
+ const entries = Object.entries(devices.capabilities).map(([name, provider]) => ({
5107
+ name,
5108
+ provider: parseProvider(name, provider)
5109
+ }));
5110
+ return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider }) => [name, provider]));
5111
+ };
5112
+ var isIgnored = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment));
5113
+ var importedCapabilities = (source, file) => {
5114
+ const names = new Set;
5115
+ const namespaces = new Set;
5116
+ const visit = (node) => {
5117
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
5118
+ const bindings = node.importClause?.namedBindings;
5119
+ if (bindings && ts.isNamedImports(bindings)) {
5120
+ for (const element of bindings.elements)
5121
+ if (!element.isTypeOnly)
5122
+ names.add((element.propertyName ?? element.name).text);
5123
+ }
5124
+ if (bindings && ts.isNamespaceImport(bindings))
5125
+ namespaces.add(bindings.name.text);
5126
+ }
5127
+ if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && ts.isNamedExports(node.exportClause)) {
5128
+ for (const element of node.exportClause.elements)
5129
+ if (!element.isTypeOnly)
5130
+ names.add((element.propertyName ?? element.name).text);
5131
+ }
5132
+ if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && namespaces.has(node.expression.text))
5133
+ names.add(node.name.text);
5134
+ ts.forEachChild(node, visit);
5135
+ };
5136
+ const extension = extname3(file).toLowerCase();
5137
+ const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
5138
+ for (const [index, script] of sources.entries())
5139
+ visit(ts.createSourceFile(`${file}#script-${index}`, script, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX));
5140
+ return names;
5141
+ };
5142
+ var assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
5143
+ const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
5144
+ const mismatched = plan.requiredPackages.filter((spec) => {
5145
+ const separator = spec.lastIndexOf("@");
5146
+ const packageName = spec.slice(0, separator);
5147
+ if (missing.includes(spec))
5148
+ return false;
5149
+ try {
5150
+ return readJson(join13(resolve11(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
5151
+ } catch {
5152
+ return true;
5153
+ }
5154
+ });
5155
+ const unmet = [...missing, ...mismatched];
5156
+ if (unmet.length > 0)
5157
+ throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
5158
+ };
5159
+ var directAbsoluteProjectPackages = (projectRoot) => {
5160
+ const manifest = readJson(join13(resolve11(projectRoot), "package.json"));
5161
+ const packages = new Set;
5162
+ for (const field of ["dependencies", "devDependencies"]) {
5163
+ const dependencies = manifest[field];
5164
+ if (object2(dependencies))
5165
+ for (const name of Object.keys(dependencies))
5166
+ packages.add(name);
5167
+ }
5168
+ return packages;
5169
+ };
5170
+ var discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
5171
+ const root = resolve11(projectRoot);
5172
+ const known = new Set(Object.keys(providers));
5173
+ const capabilities = new Set;
5174
+ for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
5175
+ const portable = relative9(root, resolve11(root, path)).replaceAll("\\", "/");
5176
+ if (isIgnored(portable))
5177
+ continue;
5178
+ const source = readFileSync4(resolve11(root, portable), "utf8");
5179
+ for (const name of importedCapabilities(source, portable))
5180
+ if (known.has(name))
5181
+ capabilities.add(name);
5182
+ }
5183
+ return [...capabilities].sort();
5184
+ };
5185
+ var missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
5186
+ const packageName = spec.slice(0, spec.lastIndexOf("@"));
5187
+ return !directPackages.has(packageName);
5188
+ });
5189
+ var resolveAbsoluteDeviceCapabilityPlan = (projectRoot) => {
5190
+ const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot);
5191
+ const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
5192
+ const providers = {};
5193
+ for (const name of capabilities) {
5194
+ const provider = allProviders[name];
5195
+ if (provider)
5196
+ providers[name] = provider;
5197
+ }
5198
+ return {
5199
+ capabilities,
5200
+ providers,
5201
+ requiredPackages: [
5202
+ ...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
5203
+ ].sort()
5204
+ };
5205
+ };
5206
+
5207
+ // src/mobile/buildPipeline.ts
4982
5208
  var isElysiaApp = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "compile") === "function" && Array.isArray(Reflect.get(value, "routes"));
4983
5209
  var isStringRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
4984
5210
  var serverExportName = (loaded, app) => {
@@ -5012,11 +5238,11 @@ var loadServerApp = async (producerPath) => {
5012
5238
  return { app, exportName };
5013
5239
  };
5014
5240
  var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5015
- const buildDirectory = resolve11(options.buildDirectory);
5241
+ const buildDirectory = resolve12(options.buildDirectory);
5016
5242
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
5017
- const root = join13(buildDirectory, ".absolutejs", "mobile-compatibility");
5243
+ const root = join14(buildDirectory, ".absolutejs", "mobile-compatibility");
5018
5244
  const [manifestSource, previous] = await Promise.all([
5019
- readFile13(join13(buildDirectory, "manifest.json"), "utf8"),
5245
+ readFile13(join14(buildDirectory, "manifest.json"), "utf8"),
5020
5246
  readAbsoluteMobileMaterializedReleases(root)
5021
5247
  ]);
5022
5248
  const manifest = JSON.parse(manifestSource);
@@ -5029,11 +5255,11 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5029
5255
  process.env.ABSOLUTE_BUILD_DIR = buildDirectory;
5030
5256
  process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
5031
5257
  if (options.configPath) {
5032
- process.env.ABSOLUTE_CONFIG = resolve11(options.projectRoot, options.configPath);
5258
+ process.env.ABSOLUTE_CONFIG = resolve12(options.projectRoot, options.configPath);
5033
5259
  }
5034
5260
  let loaded;
5035
5261
  try {
5036
- loaded = await loadServerApp(resolve11(options.producerPath));
5262
+ loaded = await loadServerApp(resolve12(options.producerPath));
5037
5263
  } finally {
5038
5264
  restoreEnvironmentVariable("ABSOLUTE_BUILD_DIR", previousBuildDirectory);
5039
5265
  restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
@@ -5046,12 +5272,14 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5046
5272
  manifest,
5047
5273
  previousArtifacts: previous.map(({ artifact }) => artifact),
5048
5274
  producerExport: loaded.exportName,
5049
- producerPath: resolve11(options.producerPath),
5275
+ producerPath: resolve12(options.producerPath),
5050
5276
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
5051
5277
  });
5052
5278
  const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
5053
5279
  const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
5054
5280
  const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
5281
+ const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
5282
+ assertAbsoluteDeviceCapabilityPackages(options.projectRoot, deviceCapabilities);
5055
5283
  if (auth && !loaded.app.routes.some((route) => route.path === "/.well-known/openid-configuration")) {
5056
5284
  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.");
5057
5285
  }
@@ -5070,6 +5298,8 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5070
5298
  ...auth ? { auth } : {},
5071
5299
  buildDirectory,
5072
5300
  config: mobile,
5301
+ deviceCapabilities,
5302
+ projectRoot: options.projectRoot,
5073
5303
  ...sync ? { sync: true } : {},
5074
5304
  ...syncSchema ? { syncSchema: { components: syncSchema.components } } : {}
5075
5305
  });
@@ -5079,6 +5309,113 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
5079
5309
  // src/mobile/index.ts
5080
5310
  init_syncSchema();
5081
5311
 
5312
+ // node_modules/@absolutejs/sync/dist/client/runtimeTransport.js
5313
+ var RUNTIME_TRANSPORT2 = Symbol.for("@absolutejs/sync/client-runtime-transport");
5314
+ var host2 = globalThis;
5315
+ var isRegistry2 = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations")) && Array.isArray(Reflect.get(value, "clients"));
5316
+ var registry2 = (() => {
5317
+ const existing = host2[RUNTIME_TRANSPORT2];
5318
+ if (isRegistry2(existing))
5319
+ return existing;
5320
+ if (typeof existing === "object" && existing !== null && Array.isArray(Reflect.get(existing, "installations"))) {
5321
+ Reflect.set(existing, "clients", []);
5322
+ return existing;
5323
+ }
5324
+ const created = { clients: [], installations: [] };
5325
+ Object.defineProperty(host2, RUNTIME_TRANSPORT2, {
5326
+ configurable: false,
5327
+ enumerable: false,
5328
+ value: created,
5329
+ writable: false
5330
+ });
5331
+ return created;
5332
+ })();
5333
+ var maximum = (values) => {
5334
+ const present = values.filter((value) => value !== undefined);
5335
+ return present.length === 0 ? undefined : Math.max(...present);
5336
+ };
5337
+ var minimum = (values) => {
5338
+ const present = values.filter((value) => value !== undefined);
5339
+ return present.length === 0 ? undefined : Math.min(...present);
5340
+ };
5341
+ var inspectSyncRuntime = async () => {
5342
+ const clients = [...registry2.clients];
5343
+ const statuses = clients.map((client) => client.status());
5344
+ const deadLetters = (await Promise.all(clients.map((client) => client.listDeadLetters()))).flat().map((record) => ({
5345
+ attempts: record.attempts,
5346
+ ...record.rejection?.code ? { code: record.rejection.code } : {},
5347
+ createdAt: record.createdAt,
5348
+ ...record.deadLetteredAt === undefined ? {} : { deadLetteredAt: record.deadLetteredAt },
5349
+ ...record.rejection?.kind ? { kind: record.rejection.kind } : {},
5350
+ ...record.rejection?.message ? { message: record.rejection.message } : {},
5351
+ name: record.name,
5352
+ operationId: record.operationId
5353
+ })).sort((left, right) => (left.deadLetteredAt ?? left.createdAt) - (right.deadLetteredAt ?? right.createdAt) || left.operationId.localeCompare(right.operationId));
5354
+ const lastError = statuses.findLast((status) => status.lastError)?.lastError;
5355
+ return {
5356
+ automaticResolutions: statuses.reduce((total, status) => total + status.automaticResolutions, 0),
5357
+ clients: clients.length,
5358
+ conflicts: deadLetters.filter((record) => record.kind === "conflict").length,
5359
+ deadLetters,
5360
+ ...lastError ? { lastError } : {},
5361
+ ...maximum(statuses.map((status) => status.lastSuccessfulPullAt)) === undefined ? {} : {
5362
+ lastSuccessfulPullAt: maximum(statuses.map((status) => status.lastSuccessfulPullAt))
5363
+ },
5364
+ ...maximum(statuses.map((status) => status.lastSuccessfulPushAt)) === undefined ? {} : {
5365
+ lastSuccessfulPushAt: maximum(statuses.map((status) => status.lastSuccessfulPushAt))
5366
+ },
5367
+ ...minimum(statuses.map((status) => status.oldestDeadLetterAt)) === undefined ? {} : {
5368
+ oldestDeadLetterAt: minimum(statuses.map((status) => status.oldestDeadLetterAt))
5369
+ },
5370
+ ...minimum(statuses.map((status) => status.oldestPendingAt)) === undefined ? {} : {
5371
+ oldestPendingAt: minimum(statuses.map((status) => status.oldestPendingAt))
5372
+ },
5373
+ pending: statuses.reduce((total, status) => total + status.pending, 0)
5374
+ };
5375
+ };
5376
+ var clientWithDeadLetter = async (operationId) => {
5377
+ for (const client of registry2.clients)
5378
+ if ((await client.listDeadLetters()).some((record) => record.operationId === operationId))
5379
+ return client;
5380
+ throw new Error(`Unknown Sync dead letter "${operationId}"`);
5381
+ };
5382
+ var retrySyncRuntimeDeadLetter = async (operationId) => (await clientWithDeadLetter(operationId)).retryDeadLetter(operationId);
5383
+ var discardSyncRuntimeDeadLetter = async (operationId) => (await clientWithDeadLetter(operationId)).discardDeadLetter(operationId);
5384
+ var rebaseSyncRuntimeDeadLetter = async (operationId, args) => (await clientWithDeadLetter(operationId)).rebaseDeadLetter(operationId, args);
5385
+
5386
+ // src/mobile/syncRemediation.ts
5387
+ var REMEDIATION_REGISTRY = Symbol.for("@absolutejs/mobile-sync-remediation");
5388
+ var LAST_INSTALLATION_OFFSET = -1;
5389
+ var isRegistry3 = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations"));
5390
+ var resolveRegistry = () => {
5391
+ const existing = Reflect.get(globalThis, REMEDIATION_REGISTRY);
5392
+ if (isRegistry3(existing))
5393
+ return existing;
5394
+ const created = { installations: [] };
5395
+ Object.defineProperty(globalThis, REMEDIATION_REGISTRY, {
5396
+ configurable: false,
5397
+ enumerable: false,
5398
+ value: created,
5399
+ writable: false
5400
+ });
5401
+ return created;
5402
+ };
5403
+ var registry3 = resolveRegistry();
5404
+ var getAbsoluteMobileSyncRemediation = () => registry3.installations.at(LAST_INSTALLATION_OFFSET)?.bridge;
5405
+ var installAbsoluteMobileSyncRemediation = (bridge = {
5406
+ discard: discardSyncRuntimeDeadLetter,
5407
+ inspect: inspectSyncRuntime,
5408
+ rebase: rebaseSyncRuntimeDeadLetter,
5409
+ retry: retrySyncRuntimeDeadLetter
5410
+ }) => {
5411
+ const installation = { bridge };
5412
+ registry3.installations.push(installation);
5413
+ return () => {
5414
+ const index = registry3.installations.indexOf(installation);
5415
+ if (index >= 0)
5416
+ registry3.installations.splice(index, 1);
5417
+ };
5418
+ };
5082
5419
  // src/mobile/compatibilityDispatcher.ts
5083
5420
  import { Elysia as Elysia2 } from "elysia";
5084
5421
 
@@ -5220,7 +5557,7 @@ var createAbsoluteMobileCompatibilityDispatcher = (options) => {
5220
5557
  };
5221
5558
  // src/mobile/nativeDeepLinks.ts
5222
5559
  import { readFile as readFile14, rename as rename11, writeFile as writeFile12 } from "fs/promises";
5223
- import { join as join14 } from "path";
5560
+ import { join as join15 } from "path";
5224
5561
  var START_MARKER = "<!-- absolutejs:deep-links:start -->";
5225
5562
  var END_MARKER = "<!-- absolutejs:deep-links:end -->";
5226
5563
  var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
@@ -5256,7 +5593,7 @@ var replaceManagedRegion = (source, region, insertAt) => {
5256
5593
  return `${source.slice(0, index)}${region}${source.slice(index)}`;
5257
5594
  };
5258
5595
  var androidRegion = (config) => {
5259
- const hosts = config.deepLinkHosts.map((host2) => ` <data android:scheme="https" android:host="${escapeXml(host2)}" />`).join(`
5596
+ const hosts = config.deepLinkHosts.map((host3) => ` <data android:scheme="https" android:host="${escapeXml(host3)}" />`).join(`
5260
5597
  `);
5261
5598
  const customScheme = config.deepLinkScheme ? `
5262
5599
 
@@ -5277,7 +5614,7 @@ ${hosts}
5277
5614
  `;
5278
5615
  };
5279
5616
  var configureAndroid = async (config) => {
5280
- const path = join14(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
5617
+ const path = join15(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
5281
5618
  const source = await readFile14(path, "utf8");
5282
5619
  const mainActivity = source.indexOf('android:name=".MainActivity"');
5283
5620
  if (mainActivity === NOT_FOUND) {
@@ -5303,7 +5640,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
5303
5640
  ${END_MARKER}
5304
5641
  `;
5305
5642
  var configureIosInfo = async (config) => {
5306
- const path = join14(config.nativeProjectDirectory, "ios/App/App/Info.plist");
5643
+ const path = join15(config.nativeProjectDirectory, "ios/App/App/Info.plist");
5307
5644
  const source = await readFile14(path, "utf8");
5308
5645
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
5309
5646
  ${END_MARKER}
@@ -5312,7 +5649,7 @@ var configureIosInfo = async (config) => {
5312
5649
  return writeChangedFile(path, updated);
5313
5650
  };
5314
5651
  var iosEntitlementsSource = (config) => {
5315
- const domains = config.deepLinkHosts.map((host2) => ` <string>applinks:${escapeXml(host2)}</string>`).join(`
5652
+ const domains = config.deepLinkHosts.map((host3) => ` <string>applinks:${escapeXml(host3)}</string>`).join(`
5316
5653
  `);
5317
5654
  return `<?xml version="1.0" encoding="UTF-8"?>
5318
5655
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -5327,7 +5664,7 @@ ${domains}
5327
5664
  `;
5328
5665
  };
5329
5666
  var configureIosEntitlements = async (config) => {
5330
- const path = join14(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
5667
+ const path = join15(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
5331
5668
  let current = "";
5332
5669
  try {
5333
5670
  current = await readFile14(path, "utf8");
@@ -5345,7 +5682,7 @@ var configureIosEntitlements = async (config) => {
5345
5682
  return true;
5346
5683
  };
5347
5684
  var configureIosProject = async (config) => {
5348
- const path = join14(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
5685
+ const path = join15(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
5349
5686
  const source = await readFile14(path, "utf8");
5350
5687
  const declarations = [
5351
5688
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
@@ -5385,7 +5722,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
5385
5722
  };
5386
5723
  // src/mobile/releasePublisher.ts
5387
5724
  import { access as access9 } from "fs/promises";
5388
- import { isAbsolute as isAbsolute6, relative as relative9, resolve as resolve12, sep as sep6 } from "path";
5725
+ import { isAbsolute as isAbsolute6, relative as relative10, resolve as resolve13, sep as sep6 } from "path";
5389
5726
  import { pathToFileURL as pathToFileURL3 } from "url";
5390
5727
  var prepareAbsoluteIosRelease = async (publisher, options) => {
5391
5728
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -5411,9 +5748,9 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
5411
5748
  var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
5412
5749
  var isPublisher = (value) => isRecord8(value) && typeof value.publish === "function";
5413
5750
  var publisherModulePath = (projectRoot, requested) => {
5414
- const root = resolve12(projectRoot);
5415
- const path = resolve12(root, requested);
5416
- const projectRelative = relative9(root, path);
5751
+ const root = resolve13(projectRoot);
5752
+ const path = resolve13(root, requested);
5753
+ const projectRelative = relative10(root, path);
5417
5754
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep6}`) || isAbsolute6(projectRelative)) {
5418
5755
  throw new TypeError("mobile publish --registry must remain inside the project.");
5419
5756
  }
@@ -5482,9 +5819,9 @@ var publishAbsoluteIosRelease = async (options) => {
5482
5819
  return publication;
5483
5820
  };
5484
5821
  // src/mobile/routeMetadataTransform.ts
5485
- import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
5486
- import { dirname as dirname10, extname as extname3, relative as relative10, resolve as resolve13 } from "path";
5487
- import ts from "typescript";
5822
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
5823
+ import { dirname as dirname10, extname as extname4, relative as relative11, resolve as resolve14 } from "path";
5824
+ import ts2 from "typescript";
5488
5825
  var ROUTE_METHODS = new Set(["get", "head"]);
5489
5826
  var SOURCE_FILTER = /\.[cm]?[jt]sx?$/;
5490
5827
  var PAGE_HANDLERS = new Map([
@@ -5534,60 +5871,60 @@ var PAGE_HANDLERS = new Map([
5534
5871
  ]
5535
5872
  ]);
5536
5873
  var posixPath = (value) => value.replace(/\\/g, "/");
5537
- var findTsconfig = (entry, projectRoot) => ts.findConfigFile(dirname10(entry), existsSync3, "tsconfig.json") ?? ts.findConfigFile(projectRoot, existsSync3, "tsconfig.json");
5874
+ var findTsconfig = (entry, projectRoot) => ts2.findConfigFile(dirname10(entry), existsSync3, "tsconfig.json") ?? ts2.findConfigFile(projectRoot, existsSync3, "tsconfig.json");
5538
5875
  var createProgram = (entry, projectRoot) => {
5539
5876
  const configPath = findTsconfig(entry, projectRoot);
5540
5877
  if (!configPath) {
5541
- return ts.createProgram([entry], {
5878
+ return ts2.createProgram([entry], {
5542
5879
  allowJs: true,
5543
- jsx: ts.JsxEmit.ReactJSX,
5544
- module: ts.ModuleKind.ESNext,
5545
- moduleResolution: ts.ModuleResolutionKind.Bundler,
5546
- target: ts.ScriptTarget.ESNext
5880
+ jsx: ts2.JsxEmit.ReactJSX,
5881
+ module: ts2.ModuleKind.ESNext,
5882
+ moduleResolution: ts2.ModuleResolutionKind.Bundler,
5883
+ target: ts2.ScriptTarget.ESNext
5547
5884
  });
5548
5885
  }
5549
- const parsed = ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, (path) => readFileSync4(path, "utf8")).config, ts.sys, dirname10(configPath));
5886
+ const parsed = ts2.parseJsonConfigFileContent(ts2.readConfigFile(configPath, (path) => readFileSync5(path, "utf8")).config, ts2.sys, dirname10(configPath));
5550
5887
  if (!parsed.fileNames.includes(entry))
5551
5888
  parsed.fileNames.push(entry);
5552
- return ts.createProgram(parsed.fileNames, parsed.options);
5889
+ return ts2.createProgram(parsed.fileNames, parsed.options);
5553
5890
  };
5554
5891
  var propertyName = (property) => {
5555
5892
  if (!("name" in property) || !property.name)
5556
5893
  return;
5557
- if (ts.isIdentifier(property.name))
5894
+ if (ts2.isIdentifier(property.name))
5558
5895
  return property.name.text;
5559
- if (ts.isStringLiteralLike(property.name))
5896
+ if (ts2.isStringLiteralLike(property.name))
5560
5897
  return property.name.text;
5561
5898
  return;
5562
5899
  };
5563
- var objectPropertyExpression = (object2, name) => {
5564
- const property = object2.properties.find((candidate) => propertyName(candidate) === name);
5565
- if (property && ts.isPropertyAssignment(property)) {
5900
+ var objectPropertyExpression = (object3, name) => {
5901
+ const property = object3.properties.find((candidate) => propertyName(candidate) === name);
5902
+ if (property && ts2.isPropertyAssignment(property)) {
5566
5903
  return property.initializer;
5567
5904
  }
5568
- if (property && ts.isShorthandPropertyAssignment(property)) {
5905
+ if (property && ts2.isShorthandPropertyAssignment(property)) {
5569
5906
  return property.name;
5570
5907
  }
5571
5908
  return;
5572
5909
  };
5573
5910
  var serializeType = (type, checker, ancestors = new Set) => {
5574
- if (type.flags & ts.TypeFlags.Any)
5911
+ if (type.flags & ts2.TypeFlags.Any)
5575
5912
  return { type: "any" };
5576
- if (type.flags & ts.TypeFlags.Unknown)
5913
+ if (type.flags & ts2.TypeFlags.Unknown)
5577
5914
  return { type: "unknown" };
5578
- if (type.flags & ts.TypeFlags.Never)
5915
+ if (type.flags & ts2.TypeFlags.Never)
5579
5916
  return { type: "never" };
5580
- if (type.flags & ts.TypeFlags.StringLike)
5917
+ if (type.flags & ts2.TypeFlags.StringLike)
5581
5918
  return { type: "string" };
5582
- if (type.flags & ts.TypeFlags.NumberLike)
5919
+ if (type.flags & ts2.TypeFlags.NumberLike)
5583
5920
  return { type: "number" };
5584
- if (type.flags & ts.TypeFlags.BooleanLike)
5921
+ if (type.flags & ts2.TypeFlags.BooleanLike)
5585
5922
  return { type: "boolean" };
5586
- if (type.flags & ts.TypeFlags.BigIntLike)
5923
+ if (type.flags & ts2.TypeFlags.BigIntLike)
5587
5924
  return { type: "bigint" };
5588
- if (type.flags & ts.TypeFlags.Null)
5925
+ if (type.flags & ts2.TypeFlags.Null)
5589
5926
  return { type: "null" };
5590
- if (type.flags & ts.TypeFlags.Undefined)
5927
+ if (type.flags & ts2.TypeFlags.Undefined)
5591
5928
  return { type: "undefined" };
5592
5929
  if (type.isUnion()) {
5593
5930
  return {
@@ -5601,11 +5938,11 @@ var serializeType = (type, checker, ancestors = new Set) => {
5601
5938
  }
5602
5939
  if (ancestors.has(type)) {
5603
5940
  return {
5604
- ref: checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation)
5941
+ ref: checker.typeToString(type, undefined, ts2.TypeFormatFlags.NoTruncation)
5605
5942
  };
5606
5943
  }
5607
5944
  ancestors.add(type);
5608
- const arrayElement = checker.getIndexTypeOfType(type, ts.IndexKind.Number);
5945
+ const arrayElement = checker.getIndexTypeOfType(type, ts2.IndexKind.Number);
5609
5946
  const properties = checker.getPropertiesOfType(type);
5610
5947
  let schema;
5611
5948
  if (arrayElement && properties.some(({ name }) => name === "length")) {
@@ -5620,7 +5957,7 @@ var serializeType = (type, checker, ancestors = new Set) => {
5620
5957
  return [
5621
5958
  property.name,
5622
5959
  {
5623
- optional: Boolean(property.flags & ts.SymbolFlags.Optional),
5960
+ optional: Boolean(property.flags & ts2.SymbolFlags.Optional),
5624
5961
  schema: serializeType(propertyType, checker, ancestors)
5625
5962
  }
5626
5963
  ];
@@ -5628,7 +5965,7 @@ var serializeType = (type, checker, ancestors = new Set) => {
5628
5965
  schema = { properties: Object.fromEntries(entries), type: "object" };
5629
5966
  } else {
5630
5967
  schema = {
5631
- type: checker.typeToString(type, undefined, ts.TypeFormatFlags.NoTruncation)
5968
+ type: checker.typeToString(type, undefined, ts2.TypeFormatFlags.NoTruncation)
5632
5969
  };
5633
5970
  }
5634
5971
  ancestors.delete(type);
@@ -5646,25 +5983,25 @@ var pagePropsType = (pageExpression, propsExpression, checker) => {
5646
5983
  };
5647
5984
  var resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
5648
5985
  let symbol = checker.getSymbolAtLocation(expression);
5649
- if (symbol?.flags && symbol.flags & ts.SymbolFlags.Alias) {
5986
+ if (symbol?.flags && symbol.flags & ts2.SymbolFlags.Alias) {
5650
5987
  symbol = checker.getAliasedSymbol(symbol);
5651
5988
  }
5652
5989
  const declaration = symbol?.declarations?.[0];
5653
5990
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
5654
5991
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
5655
- const source = posixPath(relative10(projectRoot, file));
5992
+ const source = posixPath(relative11(projectRoot, file));
5656
5993
  return `${source}#${exportedName}`;
5657
5994
  };
5658
5995
  var resolveAlias = (symbol, checker) => {
5659
- if (!(symbol.flags & ts.SymbolFlags.Alias))
5996
+ if (!(symbol.flags & ts2.SymbolFlags.Alias))
5660
5997
  return symbol;
5661
5998
  return checker.getAliasedSymbol(symbol);
5662
5999
  };
5663
6000
  var assetKey = (expression, checker, seen = new Set) => {
5664
6001
  if (!expression)
5665
6002
  return;
5666
- if (ts.isIdentifier(expression)) {
5667
- const unresolved = ts.isShorthandPropertyAssignment(expression.parent) ? checker.getShorthandAssignmentValueSymbol(expression.parent) : checker.getSymbolAtLocation(expression);
6003
+ if (ts2.isIdentifier(expression)) {
6004
+ const unresolved = ts2.isShorthandPropertyAssignment(expression.parent) ? checker.getShorthandAssignmentValueSymbol(expression.parent) : checker.getSymbolAtLocation(expression);
5668
6005
  if (!unresolved)
5669
6006
  return;
5670
6007
  const symbol = resolveAlias(unresolved, checker);
@@ -5672,26 +6009,26 @@ var assetKey = (expression, checker, seen = new Set) => {
5672
6009
  return;
5673
6010
  seen.add(symbol);
5674
6011
  const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
5675
- if (!declaration || !ts.isVariableDeclaration(declaration))
6012
+ if (!declaration || !ts2.isVariableDeclaration(declaration))
5676
6013
  return;
5677
6014
  return assetKey(declaration.initializer, checker, seen);
5678
6015
  }
5679
- if (!ts.isCallExpression(expression))
6016
+ if (!ts2.isCallExpression(expression))
5680
6017
  return;
5681
- if (!ts.isIdentifier(expression.expression) || expression.expression.text !== "asset") {
6018
+ if (!ts2.isIdentifier(expression.expression) || expression.expression.text !== "asset") {
5682
6019
  return;
5683
6020
  }
5684
6021
  const [, key] = expression.arguments;
5685
- return key && ts.isStringLiteralLike(key) ? key.text : undefined;
6022
+ return key && ts2.isStringLiteralLike(key) ? key.text : undefined;
5686
6023
  };
5687
6024
  var staticString = (expression, bindings) => {
5688
- if (ts.isStringLiteralLike(expression))
6025
+ if (ts2.isStringLiteralLike(expression))
5689
6026
  return expression.text;
5690
- if (ts.isIdentifier(expression))
6027
+ if (ts2.isIdentifier(expression))
5691
6028
  return bindings.get(expression.text);
5692
- if (ts.isNoSubstitutionTemplateLiteral(expression))
6029
+ if (ts2.isNoSubstitutionTemplateLiteral(expression))
5693
6030
  return expression.text;
5694
- if (!ts.isTemplateExpression(expression))
6031
+ if (!ts2.isTemplateExpression(expression))
5695
6032
  return;
5696
6033
  let value = expression.head.text;
5697
6034
  for (const span of expression.templateSpans) {
@@ -5705,7 +6042,7 @@ var staticString = (expression, bindings) => {
5705
6042
  var assetKeyWithBindings = (expression, checker, bindings = new Map) => {
5706
6043
  if (!expression)
5707
6044
  return;
5708
- if (ts.isCallExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "asset") {
6045
+ if (ts2.isCallExpression(expression) && ts2.isIdentifier(expression.expression) && expression.expression.text === "asset") {
5709
6046
  const [, key] = expression.arguments;
5710
6047
  return key ? staticString(key, bindings) : undefined;
5711
6048
  }
@@ -5716,16 +6053,16 @@ var callableObject = (call, checker) => {
5716
6053
  const resolved = symbol ? resolveAlias(symbol, checker) : undefined;
5717
6054
  const declaration = resolved?.valueDeclaration ?? resolved?.declarations?.[0];
5718
6055
  let callable;
5719
- if (declaration && ts.isFunctionDeclaration(declaration)) {
6056
+ if (declaration && ts2.isFunctionDeclaration(declaration)) {
5720
6057
  callable = declaration;
5721
- } else if (declaration && ts.isVariableDeclaration(declaration) && declaration.initializer && (ts.isArrowFunction(declaration.initializer) || ts.isFunctionExpression(declaration.initializer))) {
6058
+ } else if (declaration && ts2.isVariableDeclaration(declaration) && declaration.initializer && (ts2.isArrowFunction(declaration.initializer) || ts2.isFunctionExpression(declaration.initializer))) {
5722
6059
  callable = declaration.initializer;
5723
6060
  }
5724
6061
  if (!callable)
5725
6062
  return;
5726
6063
  const bindings = new Map;
5727
6064
  callable.parameters.forEach((parameter, index) => {
5728
- if (!ts.isIdentifier(parameter.name))
6065
+ if (!ts2.isIdentifier(parameter.name))
5729
6066
  return;
5730
6067
  const argument = call.arguments[index];
5731
6068
  if (!argument)
@@ -5737,35 +6074,35 @@ var callableObject = (call, checker) => {
5737
6074
  const { body } = callable;
5738
6075
  if (!body)
5739
6076
  return;
5740
- const expressionBody = ts.isParenthesizedExpression(body) ? body.expression : body;
5741
- if (ts.isObjectLiteralExpression(expressionBody)) {
6077
+ const expressionBody = ts2.isParenthesizedExpression(body) ? body.expression : body;
6078
+ if (ts2.isObjectLiteralExpression(expressionBody)) {
5742
6079
  return { bindings, object: expressionBody };
5743
6080
  }
5744
- if (ts.isBlock(body)) {
5745
- const returned = body.statements.find(ts.isReturnStatement)?.expression;
5746
- if (returned && ts.isObjectLiteralExpression(returned)) {
6081
+ if (ts2.isBlock(body)) {
6082
+ const returned = body.statements.find(ts2.isReturnStatement)?.expression;
6083
+ if (returned && ts2.isObjectLiteralExpression(returned)) {
5747
6084
  return { bindings, object: returned };
5748
6085
  }
5749
6086
  }
5750
6087
  return;
5751
6088
  };
5752
6089
  var spreadObject = (expression, checker, bindings) => {
5753
- if (ts.isObjectLiteralExpression(expression)) {
6090
+ if (ts2.isObjectLiteralExpression(expression)) {
5754
6091
  return { bindings, object: expression };
5755
6092
  }
5756
- if (!ts.isCallExpression(expression))
6093
+ if (!ts2.isCallExpression(expression))
5757
6094
  return;
5758
6095
  return callableObject(expression, checker);
5759
6096
  };
5760
- var objectAssetKey = (object2, name, checker, bindings = new Map) => {
5761
- for (const property of [...object2.properties].reverse()) {
5762
- if (propertyName(property) === name && ts.isShorthandPropertyAssignment(property)) {
6097
+ var objectAssetKey = (object3, name, checker, bindings = new Map) => {
6098
+ for (const property of [...object3.properties].reverse()) {
6099
+ if (propertyName(property) === name && ts2.isShorthandPropertyAssignment(property)) {
5763
6100
  return assetKeyWithBindings(property.name, checker, bindings);
5764
6101
  }
5765
- if (propertyName(property) === name && ts.isPropertyAssignment(property)) {
6102
+ if (propertyName(property) === name && ts2.isPropertyAssignment(property)) {
5766
6103
  return assetKeyWithBindings(property.initializer, checker, bindings);
5767
6104
  }
5768
- if (!ts.isSpreadAssignment(property))
6105
+ if (!ts2.isSpreadAssignment(property))
5769
6106
  continue;
5770
6107
  const nestedObject = spreadObject(property.expression, checker, bindings);
5771
6108
  if (!nestedObject)
@@ -5781,14 +6118,14 @@ var findPageCall = (nodes) => {
5781
6118
  const visit = (candidate) => {
5782
6119
  if (found)
5783
6120
  return;
5784
- if (ts.isCallExpression(candidate) && ts.isIdentifier(candidate.expression) && PAGE_HANDLERS.has(candidate.expression.text)) {
6121
+ if (ts2.isCallExpression(candidate) && ts2.isIdentifier(candidate.expression) && PAGE_HANDLERS.has(candidate.expression.text)) {
5785
6122
  const definition = PAGE_HANDLERS.get(candidate.expression.text);
5786
6123
  if (!definition)
5787
6124
  return;
5788
6125
  found = { definition, node: candidate };
5789
6126
  return;
5790
6127
  }
5791
- ts.forEachChild(candidate, visit);
6128
+ ts2.forEachChild(candidate, visit);
5792
6129
  };
5793
6130
  for (const node of nodes)
5794
6131
  visit(node);
@@ -5797,12 +6134,12 @@ var findPageCall = (nodes) => {
5797
6134
  var isProjectSource = (sourceFile, resolvedFile, projectRoot) => !sourceFile.isDeclarationFile && !resolvedFile.includes("/node_modules/") && resolvedFile.startsWith(`${projectRoot}/`);
5798
6135
  var analyzeRouteCall = (node, sourceFile, checker, projectRoot) => {
5799
6136
  const callee = node.expression;
5800
- if (!ts.isPropertyAccessExpression(callee))
6137
+ if (!ts2.isPropertyAccessExpression(callee))
5801
6138
  return;
5802
6139
  if (!ROUTE_METHODS.has(callee.name.text))
5803
6140
  return;
5804
6141
  const [routePath] = node.arguments;
5805
- if (!routePath || !ts.isStringLiteralLike(routePath))
6142
+ if (!routePath || !ts2.isStringLiteralLike(routePath))
5806
6143
  return;
5807
6144
  const foundPageCall = findPageCall(node.arguments.slice(1));
5808
6145
  const pageCall = foundPageCall?.node;
@@ -5835,7 +6172,7 @@ var analyzeRouteCall = (node, sourceFile, checker, projectRoot) => {
5835
6172
  routeCallSpan: `${node.getStart(sourceFile)}:${node.end}`
5836
6173
  };
5837
6174
  }
5838
- if (!ts.isObjectLiteralExpression(input) || !definition.bundleProperty) {
6175
+ if (!ts2.isObjectLiteralExpression(input) || !definition.bundleProperty) {
5839
6176
  return;
5840
6177
  }
5841
6178
  const page = definition.pageProperty ? objectPropertyExpression(input, definition.pageProperty) : undefined;
@@ -5877,21 +6214,21 @@ var analyzeSourceFile = (sourceFile, checker, projectRoot) => {
5877
6214
  byRouteCall: new Map
5878
6215
  };
5879
6216
  const visit = (node) => {
5880
- const result = ts.isCallExpression(node) ? analyzeRouteCall(node, sourceFile, checker, projectRoot) : undefined;
6217
+ const result = ts2.isCallExpression(node) ? analyzeRouteCall(node, sourceFile, checker, projectRoot) : undefined;
5881
6218
  if (result) {
5882
6219
  analysis.byPageCall.set(result.pageCallStart, result);
5883
6220
  analysis.byRouteCall.set(result.routeCallSpan, result);
5884
6221
  }
5885
- ts.forEachChild(node, visit);
6222
+ ts2.forEachChild(node, visit);
5886
6223
  };
5887
- ts.forEachChild(sourceFile, visit);
6224
+ ts2.forEachChild(sourceFile, visit);
5888
6225
  return analysis;
5889
6226
  };
5890
6227
  var analyzeProgram = (program, projectRoot) => {
5891
6228
  const checker = program.getTypeChecker();
5892
6229
  const analyzed = new Map;
5893
6230
  for (const sourceFile of program.getSourceFiles()) {
5894
- const resolvedFile = resolve13(sourceFile.fileName);
6231
+ const resolvedFile = resolve14(sourceFile.fileName);
5895
6232
  if (!isProjectSource(sourceFile, resolvedFile, projectRoot))
5896
6233
  continue;
5897
6234
  const analysis = analyzeSourceFile(sourceFile, checker, projectRoot);
@@ -5900,21 +6237,21 @@ var analyzeProgram = (program, projectRoot) => {
5900
6237
  }
5901
6238
  return analyzed;
5902
6239
  };
5903
- var metadataExpression = (metadata) => ts.factory.createObjectLiteralExpression(Object.entries(metadata).map(([key, item]) => ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(key), ts.factory.createStringLiteral(item))), false);
6240
+ var metadataExpression = (metadata) => ts2.factory.createObjectLiteralExpression(Object.entries(metadata).map(([key, item]) => ts2.factory.createPropertyAssignment(ts2.factory.createStringLiteral(key), ts2.factory.createStringLiteral(item))), false);
5904
6241
  var routeOptions = (existing, metadata) => {
5905
- const detail = ts.factory.createObjectLiteralExpression([
5906
- ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
6242
+ const detail = ts2.factory.createObjectLiteralExpression([
6243
+ ts2.factory.createPropertyAssignment(ts2.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
5907
6244
  ]);
5908
6245
  if (!existing) {
5909
- return ts.factory.createObjectLiteralExpression([
5910
- ts.factory.createPropertyAssignment("detail", detail)
6246
+ return ts2.factory.createObjectLiteralExpression([
6247
+ ts2.factory.createPropertyAssignment("detail", detail)
5911
6248
  ]);
5912
6249
  }
5913
- return ts.factory.createObjectLiteralExpression([
5914
- ts.factory.createSpreadAssignment(existing),
5915
- ts.factory.createPropertyAssignment("detail", ts.factory.createObjectLiteralExpression([
5916
- ts.factory.createSpreadAssignment(ts.factory.createPropertyAccessExpression(existing, "detail")),
5917
- ts.factory.createPropertyAssignment(ts.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
6250
+ return ts2.factory.createObjectLiteralExpression([
6251
+ ts2.factory.createSpreadAssignment(existing),
6252
+ ts2.factory.createPropertyAssignment("detail", ts2.factory.createObjectLiteralExpression([
6253
+ ts2.factory.createSpreadAssignment(ts2.factory.createPropertyAccessExpression(existing, "detail")),
6254
+ ts2.factory.createPropertyAssignment(ts2.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
5918
6255
  ]))
5919
6256
  ]);
5920
6257
  };
@@ -5925,19 +6262,19 @@ var transformPageCall = (node, page) => {
5925
6262
  const [pagePath, existingOptions, ...rest] = node.arguments;
5926
6263
  if (!pagePath)
5927
6264
  return;
5928
- const options = ts.factory.createObjectLiteralExpression([
5929
- ...existingOptions ? [ts.factory.createSpreadAssignment(existingOptions)] : [],
5930
- ts.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
6265
+ const options = ts2.factory.createObjectLiteralExpression([
6266
+ ...existingOptions ? [ts2.factory.createSpreadAssignment(existingOptions)] : [],
6267
+ ts2.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
5931
6268
  ]);
5932
- return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [pagePath, options, ...rest]);
6269
+ return ts2.factory.updateCallExpression(node, node.expression, node.typeArguments, [pagePath, options, ...rest]);
5933
6270
  }
5934
6271
  const [input] = node.arguments;
5935
- if (!input || !ts.isObjectLiteralExpression(input))
6272
+ if (!input || !ts2.isObjectLiteralExpression(input))
5936
6273
  return;
5937
- return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [
5938
- ts.factory.updateObjectLiteralExpression(input, [
6274
+ return ts2.factory.updateCallExpression(node, node.expression, node.typeArguments, [
6275
+ ts2.factory.updateObjectLiteralExpression(input, [
5939
6276
  ...input.properties,
5940
- ts.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
6277
+ ts2.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
5941
6278
  ]),
5942
6279
  ...node.arguments.slice(1)
5943
6280
  ]);
@@ -5950,16 +6287,16 @@ var transformRouteCall = (node, route) => {
5950
6287
  return;
5951
6288
  const options = maybeHandler ? maybeOptions : undefined;
5952
6289
  const handler = maybeHandler ?? maybeOptions;
5953
- return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [path, routeOptions(options, route.metadata), handler, ...rest]);
6290
+ return ts2.factory.updateCallExpression(node, node.expression, node.typeArguments, [path, routeOptions(options, route.metadata), handler, ...rest]);
5954
6291
  };
5955
6292
  var transformFile = (source, fileName, analysis) => {
5956
- const sourceFile = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, fileName.endsWith("x") ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
6293
+ const sourceFile = ts2.createSourceFile(fileName, source, ts2.ScriptTarget.Latest, true, fileName.endsWith("x") ? ts2.ScriptKind.TSX : ts2.ScriptKind.TS);
5957
6294
  const transformer = (context) => {
5958
6295
  const visit = (node) => {
5959
- if (!ts.isCallExpression(node)) {
5960
- return ts.visitEachChild(node, visit, context);
6296
+ if (!ts2.isCallExpression(node)) {
6297
+ return ts2.visitEachChild(node, visit, context);
5961
6298
  }
5962
- const transformedChildren = ts.visitEachChild(node, visit, context);
6299
+ const transformedChildren = ts2.visitEachChild(node, visit, context);
5963
6300
  const page = analysis.byPageCall.get(node.getStart(sourceFile));
5964
6301
  const transformedPage = transformPageCall(transformedChildren, page);
5965
6302
  if (transformedPage)
@@ -5970,45 +6307,45 @@ var transformFile = (source, fileName, analysis) => {
5970
6307
  return transformedRoute;
5971
6308
  return transformedChildren;
5972
6309
  };
5973
- return (node) => ts.visitNode(node, visit, ts.isSourceFile) ?? node;
6310
+ return (node) => ts2.visitNode(node, visit, ts2.isSourceFile) ?? node;
5974
6311
  };
5975
- const result = ts.transform(sourceFile, [transformer]);
6312
+ const result = ts2.transform(sourceFile, [transformer]);
5976
6313
  try {
5977
6314
  const [transformed] = result.transformed;
5978
6315
  if (!transformed)
5979
6316
  throw new TypeError("Mobile route transform failed.");
5980
- return ts.createPrinter().printFile(transformed);
6317
+ return ts2.createPrinter().printFile(transformed);
5981
6318
  } finally {
5982
6319
  result.dispose();
5983
6320
  }
5984
6321
  };
5985
6322
  var ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL = ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION;
5986
6323
  var createAbsoluteMobileRouteMetadataPlugin = (options) => {
5987
- const projectRoot = resolve13(options.projectRoot ?? process.cwd());
5988
- const entry = resolve13(options.entry);
6324
+ const projectRoot = resolve14(options.projectRoot ?? process.cwd());
6325
+ const entry = resolve14(options.entry);
5989
6326
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
5990
6327
  return {
5991
6328
  name: "absolute-mobile-route-metadata",
5992
6329
  setup(build) {
5993
6330
  build.onLoad({ filter: SOURCE_FILTER }, async ({ path }) => {
5994
- const analysis = analyzed.get(resolve13(path));
6331
+ const analysis = analyzed.get(resolve14(path));
5995
6332
  if (!analysis)
5996
6333
  return;
5997
6334
  const source = await Bun.file(path).text();
5998
6335
  return {
5999
6336
  contents: transformFile(source, path, analysis),
6000
- loader: extname3(path).endsWith("x") ? "tsx" : "ts"
6337
+ loader: extname4(path).endsWith("x") ? "tsx" : "ts"
6001
6338
  };
6002
6339
  });
6003
6340
  }
6004
6341
  };
6005
6342
  };
6006
6343
  var inspectAbsoluteMobileRouteMetadata = (options) => {
6007
- const projectRoot = resolve13(options.projectRoot ?? process.cwd());
6008
- const entry = resolve13(options.entry);
6344
+ const projectRoot = resolve14(options.projectRoot ?? process.cwd());
6345
+ const entry = resolve14(options.entry);
6009
6346
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
6010
6347
  return [...analyzed.entries()].flatMap(([file, analysis]) => [...analysis.byRouteCall.values()].map(({ metadata }) => ({
6011
- file: posixPath(relative10(projectRoot, file)),
6348
+ file: posixPath(relative11(projectRoot, file)),
6012
6349
  metadata
6013
6350
  })));
6014
6351
  };
@@ -6030,6 +6367,7 @@ export {
6030
6367
  resolveAbsoluteMobileDeepLink,
6031
6368
  resolveAbsoluteMobileCompatibilityRelease,
6032
6369
  resolveAbsoluteMobileAuthManifest,
6370
+ resolveAbsoluteDeviceCapabilityPlan,
6033
6371
  repairAbsoluteIosDevSession,
6034
6372
  removeAbsoluteRemoteMacProfile,
6035
6373
  redactAbsoluteIosLog,
@@ -6053,6 +6391,7 @@ export {
6053
6391
  pairAbsoluteRemoteMac,
6054
6392
  normalizeAbsoluteMobileConfig,
6055
6393
  navigateAbsoluteMobilePage,
6394
+ missingAbsoluteDeviceCapabilityPackages,
6056
6395
  materializeAbsoluteRemoteMacAgent,
6057
6396
  materializeAbsoluteMobileCompatibilityBundle,
6058
6397
  materializeAbsoluteMobileAssociationFiles,
@@ -6060,15 +6399,18 @@ export {
6060
6399
  matchesAbsoluteMobileRoutePattern,
6061
6400
  loadAbsoluteNativeReleasePublisher,
6062
6401
  loadAbsoluteMobileMaterializedBundle,
6402
+ loadAbsoluteDeviceCapabilityProviders,
6063
6403
  listAbsoluteRemoteMacProfiles,
6064
6404
  isAbsoluteIosNativeRootInput,
6065
6405
  installAbsoluteRemoteMacAgent,
6406
+ installAbsoluteMobileSyncRemediation,
6066
6407
  installAbsoluteMobileAuthEnvironment,
6067
6408
  inspectAbsoluteRemoteMac,
6068
6409
  inspectAbsoluteMobileRouteMetadata,
6069
6410
  hashAbsoluteMobilePropsSchema,
6070
6411
  getCurrentAbsoluteMobileProducerContext,
6071
6412
  getAbsoluteRemoteMacProfile,
6413
+ getAbsoluteMobileSyncRemediation,
6072
6414
  fingerprintAbsoluteIosNativeProject,
6073
6415
  fingerprintAbsoluteIosDevProject,
6074
6416
  finalizeAbsoluteMobilePage,
@@ -6076,6 +6418,8 @@ export {
6076
6418
  fetchAbsoluteMobilePage,
6077
6419
  disposeAbsoluteMobilePage,
6078
6420
  discoverAbsoluteSyncSchema,
6421
+ discoverAbsoluteDeviceCapabilities,
6422
+ directAbsoluteProjectPackages,
6079
6423
  createAbsoluteRemoteIosDevProject,
6080
6424
  createAbsoluteMobileUpgradeResponse,
6081
6425
  createAbsoluteMobileRouteMetadataPlugin,
@@ -6095,6 +6439,7 @@ export {
6095
6439
  buildAbsoluteMobileCompatibilityRelease,
6096
6440
  buildAbsoluteIosRelease,
6097
6441
  buildAbsoluteAndroidRelease,
6442
+ assertAbsoluteDeviceCapabilityPackages,
6098
6443
  applyAbsoluteNativeDeepLinks,
6099
6444
  activateAbsoluteMobilePage,
6100
6445
  acceptsAbsoluteMobilePage,
@@ -6123,5 +6468,5 @@ export {
6123
6468
  ABSOLUTE_ANDROID_RELEASE_FORMAT
6124
6469
  };
6125
6470
 
6126
- //# debugId=8A696911288E3CC364756E2164756E21
6471
+ //# debugId=09531F7676B08D9D64756E2164756E21
6127
6472
  //# sourceMappingURL=index.js.map