@absolutejs/absolute 0.20.0-beta.17 → 0.20.0-beta.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -5965,16 +5965,49 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
5965
5965
  throw new TypeError("Mobile page bundle escaped the build directory.");
5966
5966
  }
5967
5967
  return asset;
5968
- }, buildShellBootstrap = async (staging, auth, sync) => {
5968
+ }, importEntryTarget = (entry) => {
5969
+ if (typeof entry === "string")
5970
+ return entry;
5971
+ if (typeof entry === "object" && entry !== null)
5972
+ return Reflect.get(entry, "import");
5973
+ return;
5974
+ }, resolveProjectImport = async (projectRoot, specifier) => {
5975
+ const segments = specifier.split("/");
5976
+ const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
5977
+ const subpath = specifier.slice(packageName.length);
5978
+ const packageDirectory = join17(resolve14(projectRoot), "node_modules", packageName);
5979
+ const manifest = JSON.parse(await readFile8(join17(packageDirectory, "package.json"), "utf8"));
5980
+ const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
5981
+ const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
5982
+ const target = importEntryTarget(entry);
5983
+ if (typeof target !== "string" || !target.startsWith("./"))
5984
+ throw new TypeError(`${specifier} does not publish an import entry.`);
5985
+ const resolved = resolve14(packageDirectory, target);
5986
+ if (!resolved.startsWith(`${resolve14(packageDirectory)}/`))
5987
+ throw new TypeError(`${specifier} has an unsafe import entry.`);
5988
+ return resolved;
5989
+ }, buildShellBootstrap = async (staging, auth, sync, storagePrefix, deviceCapabilities, projectRoot) => {
5969
5990
  const modulePath = shellBootstrapModule();
5970
5991
  const authImport = auth ? `import { createAbsoluteMobileShellAuth } from ${JSON.stringify(shellAuthModule())};
5971
5992
  ` : "";
5972
5993
  const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
5973
5994
  const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
5974
5995
  ` : "";
5996
+ const capabilityImports = (await Promise.all(deviceCapabilities.capabilities.map(async (name, index) => {
5997
+ const provider = deviceCapabilities.providers[name];
5998
+ if (!provider)
5999
+ throw new TypeError(`Missing device capability provider ${name}.`);
6000
+ return `import { ${provider.factory} as absoluteDeviceCapability${index} } from ${JSON.stringify(await resolveProjectImport(projectRoot, provider.module))};`;
6001
+ }))).join(`
6002
+ `);
6003
+ const capabilityOptions = deviceCapabilities.capabilities.map((name, index) => `${JSON.stringify(name)}: absoluteDeviceCapability${index}()`).join(", ");
5975
6004
  const entryPath = join17(staging, ".absolute-mobile-entry.ts");
6005
+ const baseAdapterModule = await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor");
5976
6006
  await writeFile7(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
5977
- ${authImport}${syncImport}void startAbsoluteMobileShell(${options});
6007
+ import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};
6008
+ ${authImport}${syncImport}${capabilityImports}
6009
+ installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });
6010
+ void startAbsoluteMobileShell(${options});
5978
6011
  `);
5979
6012
  const build = await Bun.build({
5980
6013
  entrypoints: [entryPath],
@@ -6104,6 +6137,7 @@ ${authImport}${syncImport}void startAbsoluteMobileShell(${options});
6104
6137
  appName: options.config.appName,
6105
6138
  deepLinkHosts: options.config.deepLinkHosts,
6106
6139
  deepLinkScheme: options.config.deepLinkScheme,
6140
+ deviceCapabilities: options.deviceCapabilities.capabilities,
6107
6141
  entry: options.config.entry,
6108
6142
  format: ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT,
6109
6143
  pages,
@@ -6129,7 +6163,7 @@ ${authImport}${syncImport}void startAbsoluteMobileShell(${options});
6129
6163
  writeFile7(join17(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
6130
6164
  `),
6131
6165
  writeFile7(join17(staging, INDEX_FILE), indexHtml(options.config.appName)),
6132
- buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true)
6166
+ buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.deviceCapabilities, options.projectRoot)
6133
6167
  ]);
6134
6168
  await installBundle(staging, destination);
6135
6169
  return manifest;
@@ -6725,9 +6759,203 @@ var init_syncSchema = __esm(() => {
6725
6759
  init_client2();
6726
6760
  });
6727
6761
 
6762
+ // src/mobile/deviceCapabilities.ts
6763
+ import { readFileSync as readFileSync12 } from "fs";
6764
+ import { extname as extname5, join as join20, relative as relative11, resolve as resolve16 } from "path";
6765
+ import ts4 from "typescript";
6766
+ var DEVICES_PACKAGE = "@absolutejs/devices", CAPACITOR_ADAPTER = "@absolutejs/devices-capacitor", SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, CAPACITOR_MODULE_PATTERN, CAPACITOR_PACKAGE_PATTERN, ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
6767
+ const value = JSON.parse(readFileSync12(path, "utf8"));
6768
+ if (!object2(value))
6769
+ throw new TypeError(`${path} must contain an object.`);
6770
+ return value;
6771
+ }, text = (value, field) => {
6772
+ if (typeof value !== "string" || value.length === 0)
6773
+ throw new TypeError(`${field} must be a non-empty string.`);
6774
+ return value;
6775
+ }, androidPermissions = (value, field) => {
6776
+ if (value === undefined)
6777
+ return;
6778
+ if (!object2(value))
6779
+ throw new TypeError(`${field} must be an object.`);
6780
+ const { permissions } = value;
6781
+ if (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string" && ANDROID_PERMISSION_PATTERN.test(permission)))
6782
+ throw new TypeError(`${field}.permissions must contain Android permission names.`);
6783
+ return [...permissions];
6784
+ }, iosUsageDescriptions = (value, field) => {
6785
+ if (value === undefined)
6786
+ return;
6787
+ if (!object2(value))
6788
+ throw new TypeError(`${field} must be an object.`);
6789
+ const { usageDescriptions } = value;
6790
+ if (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose)))
6791
+ throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
6792
+ return [...usageDescriptions];
6793
+ }, parseProvider = (name, value) => {
6794
+ if (!IDENTIFIER_PATTERN.test(name))
6795
+ throw new TypeError("Device capability names must be identifiers.");
6796
+ if (!object2(value))
6797
+ throw new TypeError(`Device capability ${name} must be an object.`);
6798
+ const factory = text(value.factory, `${name}.factory`);
6799
+ const module = text(value.module, `${name}.module`);
6800
+ if (!IDENTIFIER_PATTERN.test(factory))
6801
+ throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
6802
+ if (!CAPACITOR_MODULE_PATTERN.test(module))
6803
+ throw new TypeError(`${name}.module must be an official devices-capacitor subpath.`);
6804
+ if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && CAPACITOR_PACKAGE_PATTERN.test(spec)))
6805
+ throw new TypeError(`${name}.packages must contain exact official Capacitor package versions.`);
6806
+ let native;
6807
+ const { native: nativeMetadata } = value;
6808
+ if (nativeMetadata !== undefined) {
6809
+ if (!object2(nativeMetadata))
6810
+ throw new TypeError(`${name}.native must be an object.`);
6811
+ const { android, ios } = nativeMetadata;
6812
+ const permissions = androidPermissions(android, `${name}.native.android`);
6813
+ const usageDescriptions = iosUsageDescriptions(ios, `${name}.native.ios`);
6814
+ native = {
6815
+ ...permissions === undefined ? {} : { android: { permissions } },
6816
+ ...usageDescriptions === undefined ? {} : { ios: { usageDescriptions } }
6817
+ };
6818
+ }
6819
+ return {
6820
+ factory,
6821
+ module,
6822
+ ...native === undefined ? {} : { native },
6823
+ packages: [...value.packages]
6824
+ };
6825
+ }, absoluteDeviceNativeRequirements = (plan) => ({
6826
+ androidPermissions: [
6827
+ ...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
6828
+ ].sort(),
6829
+ iosUsageDescriptions: [
6830
+ ...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
6831
+ ].sort()
6832
+ }), loadAbsoluteDeviceCapabilityProviders = (projectRoot) => {
6833
+ const path = join20(resolve16(projectRoot), "node_modules", CAPACITOR_ADAPTER, "package.json");
6834
+ const manifest = readJson(path);
6835
+ const { absolutejs } = manifest;
6836
+ const devices = object2(absolutejs) ? absolutejs.devices : undefined;
6837
+ if (!object2(devices) || devices.format !== 1 || devices.provider !== "capacitor" || !object2(devices.capabilities))
6838
+ throw new TypeError(`${CAPACITOR_ADAPTER} does not publish supported capability metadata.`);
6839
+ const entries = Object.entries(devices.capabilities).map(([name, provider]) => ({
6840
+ name,
6841
+ provider: parseProvider(name, provider)
6842
+ }));
6843
+ return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider }) => [name, provider]));
6844
+ }, isIgnored2 = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment)), importedCapabilities = (source, file) => {
6845
+ const names = new Set;
6846
+ const namespaces = new Set;
6847
+ const visit = (node) => {
6848
+ if (ts4.isImportDeclaration(node) && ts4.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
6849
+ const bindings = node.importClause?.namedBindings;
6850
+ if (bindings && ts4.isNamedImports(bindings)) {
6851
+ for (const element of bindings.elements)
6852
+ if (!element.isTypeOnly)
6853
+ names.add((element.propertyName ?? element.name).text);
6854
+ }
6855
+ if (bindings && ts4.isNamespaceImport(bindings))
6856
+ namespaces.add(bindings.name.text);
6857
+ }
6858
+ if (ts4.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && ts4.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && ts4.isNamedExports(node.exportClause)) {
6859
+ for (const element of node.exportClause.elements)
6860
+ if (!element.isTypeOnly)
6861
+ names.add((element.propertyName ?? element.name).text);
6862
+ }
6863
+ if (ts4.isPropertyAccessExpression(node) && ts4.isIdentifier(node.expression) && namespaces.has(node.expression.text))
6864
+ names.add(node.name.text);
6865
+ ts4.forEachChild(node, visit);
6866
+ };
6867
+ const extension = extname5(file).toLowerCase();
6868
+ const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
6869
+ for (const [index, script] of sources.entries())
6870
+ visit(ts4.createSourceFile(`${file}#script-${index}`, script, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TSX));
6871
+ return names;
6872
+ }, assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
6873
+ const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
6874
+ const mismatched = plan.requiredPackages.filter((spec) => {
6875
+ const separator = spec.lastIndexOf("@");
6876
+ const packageName = spec.slice(0, separator);
6877
+ if (missing.includes(spec))
6878
+ return false;
6879
+ try {
6880
+ return readJson(join20(resolve16(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
6881
+ } catch {
6882
+ return true;
6883
+ }
6884
+ });
6885
+ const unmet = [...missing, ...mismatched];
6886
+ if (unmet.length > 0)
6887
+ throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
6888
+ }, directAbsoluteProjectPackages = (projectRoot) => {
6889
+ const manifest = readJson(join20(resolve16(projectRoot), "package.json"));
6890
+ const packages = new Set;
6891
+ for (const field of ["dependencies", "devDependencies"]) {
6892
+ const dependencies = manifest[field];
6893
+ if (object2(dependencies))
6894
+ for (const name of Object.keys(dependencies))
6895
+ packages.add(name);
6896
+ }
6897
+ return packages;
6898
+ }, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
6899
+ const root = resolve16(projectRoot);
6900
+ const known = new Set(Object.keys(providers));
6901
+ const capabilities = new Set;
6902
+ for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
6903
+ const portable = relative11(root, resolve16(root, path)).replaceAll("\\", "/");
6904
+ if (isIgnored2(portable))
6905
+ continue;
6906
+ const source = readFileSync12(resolve16(root, portable), "utf8");
6907
+ for (const name of importedCapabilities(source, portable))
6908
+ if (known.has(name))
6909
+ capabilities.add(name);
6910
+ }
6911
+ return [...capabilities].sort();
6912
+ }, missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
6913
+ const packageName = spec.slice(0, spec.lastIndexOf("@"));
6914
+ return !directPackages.has(packageName);
6915
+ }), resolveAbsoluteDeviceCapabilityPlan = (projectRoot) => {
6916
+ const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot);
6917
+ const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
6918
+ const providers = {};
6919
+ for (const name of capabilities) {
6920
+ const provider = allProviders[name];
6921
+ if (provider)
6922
+ providers[name] = provider;
6923
+ }
6924
+ return {
6925
+ capabilities,
6926
+ providers,
6927
+ requiredPackages: [
6928
+ ...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
6929
+ ].sort()
6930
+ };
6931
+ };
6932
+ var init_deviceCapabilities = __esm(() => {
6933
+ SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
6934
+ IGNORED_DIRECTORIES = new Set([
6935
+ ".absolutejs",
6936
+ ".git",
6937
+ ".test-builds",
6938
+ ".test-shards",
6939
+ "build",
6940
+ "dist",
6941
+ "node_modules",
6942
+ "test",
6943
+ "tests"
6944
+ ]);
6945
+ IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
6946
+ CAPACITOR_MODULE_PATTERN = /^@absolutejs\/devices-capacitor\/[a-z][a-z0-9-]*$/u;
6947
+ CAPACITOR_PACKAGE_PATTERN = /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u;
6948
+ ANDROID_PERMISSION_PATTERN = /^android\.permission\.[A-Z][A-Z0-9_]*$/u;
6949
+ IOS_USAGE_DESCRIPTIONS = new Set([
6950
+ "camera",
6951
+ "photo-library",
6952
+ "photo-library-add"
6953
+ ]);
6954
+ });
6955
+
6728
6956
  // src/mobile/buildPipeline.ts
6729
6957
  import { readFile as readFile10 } from "fs/promises";
6730
- import { join as join20, resolve as resolve16 } from "path";
6958
+ import { join as join21, resolve as resolve17 } from "path";
6731
6959
  import { pathToFileURL } from "url";
6732
6960
  var isElysiaApp = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "compile") === "function" && Array.isArray(Reflect.get(value, "routes")), isStringRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string"), serverExportName = (loaded, app) => {
6733
6961
  if (loaded.server === app)
@@ -6756,11 +6984,11 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
6756
6984
  const exportName = serverExportName(loaded, app);
6757
6985
  return { app, exportName };
6758
6986
  }, finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
6759
- const buildDirectory = resolve16(options.buildDirectory);
6987
+ const buildDirectory = resolve17(options.buildDirectory);
6760
6988
  const mobile = normalizeAbsoluteMobileConfig(options.mobile, options.projectRoot);
6761
- const root = join20(buildDirectory, ".absolutejs", "mobile-compatibility");
6989
+ const root = join21(buildDirectory, ".absolutejs", "mobile-compatibility");
6762
6990
  const [manifestSource, previous] = await Promise.all([
6763
- readFile10(join20(buildDirectory, "manifest.json"), "utf8"),
6991
+ readFile10(join21(buildDirectory, "manifest.json"), "utf8"),
6764
6992
  readAbsoluteMobileMaterializedReleases(root)
6765
6993
  ]);
6766
6994
  const manifest = JSON.parse(manifestSource);
@@ -6773,11 +7001,11 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
6773
7001
  process.env.ABSOLUTE_BUILD_DIR = buildDirectory;
6774
7002
  process.env.ABSOLUTE_COMPILED_RUNTIME = "1";
6775
7003
  if (options.configPath) {
6776
- process.env.ABSOLUTE_CONFIG = resolve16(options.projectRoot, options.configPath);
7004
+ process.env.ABSOLUTE_CONFIG = resolve17(options.projectRoot, options.configPath);
6777
7005
  }
6778
7006
  let loaded;
6779
7007
  try {
6780
- loaded = await loadServerApp(resolve16(options.producerPath));
7008
+ loaded = await loadServerApp(resolve17(options.producerPath));
6781
7009
  } finally {
6782
7010
  restoreEnvironmentVariable("ABSOLUTE_BUILD_DIR", previousBuildDirectory);
6783
7011
  restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
@@ -6790,12 +7018,14 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
6790
7018
  manifest,
6791
7019
  previousArtifacts: previous.map(({ artifact }) => artifact),
6792
7020
  producerExport: loaded.exportName,
6793
- producerPath: resolve16(options.producerPath),
7021
+ producerPath: resolve17(options.producerPath),
6794
7022
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
6795
7023
  });
6796
7024
  const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
6797
7025
  const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
6798
7026
  const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
7027
+ const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
7028
+ assertAbsoluteDeviceCapabilityPackages(options.projectRoot, deviceCapabilities);
6799
7029
  if (auth && !loaded.app.routes.some((route) => route.path === "/.well-known/openid-configuration")) {
6800
7030
  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.");
6801
7031
  }
@@ -6814,6 +7044,8 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
6814
7044
  ...auth ? { auth } : {},
6815
7045
  buildDirectory,
6816
7046
  config: mobile,
7047
+ deviceCapabilities,
7048
+ projectRoot: options.projectRoot,
6817
7049
  ...sync ? { sync: true } : {},
6818
7050
  ...syncSchema ? { syncSchema: { components: syncSchema.components } } : {}
6819
7051
  });
@@ -6828,62 +7060,63 @@ var init_buildPipeline = __esm(() => {
6828
7060
  init_releaseArtifact();
6829
7061
  init_nativeAuth();
6830
7062
  init_syncSchema();
7063
+ init_deviceCapabilities();
6831
7064
  });
6832
7065
 
6833
7066
  // src/mobile/routeMetadataTransform.ts
6834
- import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
6835
- import { dirname as dirname13, extname as extname5, relative as relative11, resolve as resolve17 } from "path";
6836
- import ts4 from "typescript";
6837
- var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts4.findConfigFile(dirname13(entry), existsSync10, "tsconfig.json") ?? ts4.findConfigFile(projectRoot, existsSync10, "tsconfig.json"), createProgram = (entry, projectRoot) => {
7067
+ import { existsSync as existsSync10, readFileSync as readFileSync13 } from "fs";
7068
+ import { dirname as dirname13, extname as extname6, relative as relative12, resolve as resolve18 } from "path";
7069
+ import ts5 from "typescript";
7070
+ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts5.findConfigFile(dirname13(entry), existsSync10, "tsconfig.json") ?? ts5.findConfigFile(projectRoot, existsSync10, "tsconfig.json"), createProgram = (entry, projectRoot) => {
6838
7071
  const configPath2 = findTsconfig(entry, projectRoot);
6839
7072
  if (!configPath2) {
6840
- return ts4.createProgram([entry], {
7073
+ return ts5.createProgram([entry], {
6841
7074
  allowJs: true,
6842
- jsx: ts4.JsxEmit.ReactJSX,
6843
- module: ts4.ModuleKind.ESNext,
6844
- moduleResolution: ts4.ModuleResolutionKind.Bundler,
6845
- target: ts4.ScriptTarget.ESNext
7075
+ jsx: ts5.JsxEmit.ReactJSX,
7076
+ module: ts5.ModuleKind.ESNext,
7077
+ moduleResolution: ts5.ModuleResolutionKind.Bundler,
7078
+ target: ts5.ScriptTarget.ESNext
6846
7079
  });
6847
7080
  }
6848
- const parsed = ts4.parseJsonConfigFileContent(ts4.readConfigFile(configPath2, (path) => readFileSync12(path, "utf8")).config, ts4.sys, dirname13(configPath2));
7081
+ const parsed = ts5.parseJsonConfigFileContent(ts5.readConfigFile(configPath2, (path) => readFileSync13(path, "utf8")).config, ts5.sys, dirname13(configPath2));
6849
7082
  if (!parsed.fileNames.includes(entry))
6850
7083
  parsed.fileNames.push(entry);
6851
- return ts4.createProgram(parsed.fileNames, parsed.options);
7084
+ return ts5.createProgram(parsed.fileNames, parsed.options);
6852
7085
  }, propertyName = (property) => {
6853
7086
  if (!("name" in property) || !property.name)
6854
7087
  return;
6855
- if (ts4.isIdentifier(property.name))
7088
+ if (ts5.isIdentifier(property.name))
6856
7089
  return property.name.text;
6857
- if (ts4.isStringLiteralLike(property.name))
7090
+ if (ts5.isStringLiteralLike(property.name))
6858
7091
  return property.name.text;
6859
7092
  return;
6860
- }, objectPropertyExpression = (object2, name) => {
6861
- const property = object2.properties.find((candidate) => propertyName(candidate) === name);
6862
- if (property && ts4.isPropertyAssignment(property)) {
7093
+ }, objectPropertyExpression = (object3, name) => {
7094
+ const property = object3.properties.find((candidate) => propertyName(candidate) === name);
7095
+ if (property && ts5.isPropertyAssignment(property)) {
6863
7096
  return property.initializer;
6864
7097
  }
6865
- if (property && ts4.isShorthandPropertyAssignment(property)) {
7098
+ if (property && ts5.isShorthandPropertyAssignment(property)) {
6866
7099
  return property.name;
6867
7100
  }
6868
7101
  return;
6869
7102
  }, serializeType = (type, checker, ancestors = new Set) => {
6870
- if (type.flags & ts4.TypeFlags.Any)
7103
+ if (type.flags & ts5.TypeFlags.Any)
6871
7104
  return { type: "any" };
6872
- if (type.flags & ts4.TypeFlags.Unknown)
7105
+ if (type.flags & ts5.TypeFlags.Unknown)
6873
7106
  return { type: "unknown" };
6874
- if (type.flags & ts4.TypeFlags.Never)
7107
+ if (type.flags & ts5.TypeFlags.Never)
6875
7108
  return { type: "never" };
6876
- if (type.flags & ts4.TypeFlags.StringLike)
7109
+ if (type.flags & ts5.TypeFlags.StringLike)
6877
7110
  return { type: "string" };
6878
- if (type.flags & ts4.TypeFlags.NumberLike)
7111
+ if (type.flags & ts5.TypeFlags.NumberLike)
6879
7112
  return { type: "number" };
6880
- if (type.flags & ts4.TypeFlags.BooleanLike)
7113
+ if (type.flags & ts5.TypeFlags.BooleanLike)
6881
7114
  return { type: "boolean" };
6882
- if (type.flags & ts4.TypeFlags.BigIntLike)
7115
+ if (type.flags & ts5.TypeFlags.BigIntLike)
6883
7116
  return { type: "bigint" };
6884
- if (type.flags & ts4.TypeFlags.Null)
7117
+ if (type.flags & ts5.TypeFlags.Null)
6885
7118
  return { type: "null" };
6886
- if (type.flags & ts4.TypeFlags.Undefined)
7119
+ if (type.flags & ts5.TypeFlags.Undefined)
6887
7120
  return { type: "undefined" };
6888
7121
  if (type.isUnion()) {
6889
7122
  return {
@@ -6897,11 +7130,11 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6897
7130
  }
6898
7131
  if (ancestors.has(type)) {
6899
7132
  return {
6900
- ref: checker.typeToString(type, undefined, ts4.TypeFormatFlags.NoTruncation)
7133
+ ref: checker.typeToString(type, undefined, ts5.TypeFormatFlags.NoTruncation)
6901
7134
  };
6902
7135
  }
6903
7136
  ancestors.add(type);
6904
- const arrayElement = checker.getIndexTypeOfType(type, ts4.IndexKind.Number);
7137
+ const arrayElement = checker.getIndexTypeOfType(type, ts5.IndexKind.Number);
6905
7138
  const properties = checker.getPropertiesOfType(type);
6906
7139
  let schema;
6907
7140
  if (arrayElement && properties.some(({ name }) => name === "length")) {
@@ -6916,7 +7149,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6916
7149
  return [
6917
7150
  property.name,
6918
7151
  {
6919
- optional: Boolean(property.flags & ts4.SymbolFlags.Optional),
7152
+ optional: Boolean(property.flags & ts5.SymbolFlags.Optional),
6920
7153
  schema: serializeType(propertyType, checker, ancestors)
6921
7154
  }
6922
7155
  ];
@@ -6924,7 +7157,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6924
7157
  schema = { properties: Object.fromEntries(entries), type: "object" };
6925
7158
  } else {
6926
7159
  schema = {
6927
- type: checker.typeToString(type, undefined, ts4.TypeFormatFlags.NoTruncation)
7160
+ type: checker.typeToString(type, undefined, ts5.TypeFormatFlags.NoTruncation)
6928
7161
  };
6929
7162
  }
6930
7163
  ancestors.delete(type);
@@ -6940,23 +7173,23 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6940
7173
  return propsExpression ? checker.getTypeAtLocation(propsExpression) : checker.getTypeAtLocation(pageExpression);
6941
7174
  }, resolvePageIdentity = (expression, sourceFile, checker, projectRoot) => {
6942
7175
  let symbol = checker.getSymbolAtLocation(expression);
6943
- if (symbol?.flags && symbol.flags & ts4.SymbolFlags.Alias) {
7176
+ if (symbol?.flags && symbol.flags & ts5.SymbolFlags.Alias) {
6944
7177
  symbol = checker.getAliasedSymbol(symbol);
6945
7178
  }
6946
7179
  const declaration = symbol?.declarations?.[0];
6947
7180
  const file = declaration?.getSourceFile().fileName ?? sourceFile.fileName;
6948
7181
  const exportedName = symbol?.name ?? expression.getText(sourceFile);
6949
- const source = posixPath(relative11(projectRoot, file));
7182
+ const source = posixPath(relative12(projectRoot, file));
6950
7183
  return `${source}#${exportedName}`;
6951
7184
  }, resolveAlias = (symbol, checker) => {
6952
- if (!(symbol.flags & ts4.SymbolFlags.Alias))
7185
+ if (!(symbol.flags & ts5.SymbolFlags.Alias))
6953
7186
  return symbol;
6954
7187
  return checker.getAliasedSymbol(symbol);
6955
7188
  }, assetKey = (expression, checker, seen = new Set) => {
6956
7189
  if (!expression)
6957
7190
  return;
6958
- if (ts4.isIdentifier(expression)) {
6959
- const unresolved = ts4.isShorthandPropertyAssignment(expression.parent) ? checker.getShorthandAssignmentValueSymbol(expression.parent) : checker.getSymbolAtLocation(expression);
7191
+ if (ts5.isIdentifier(expression)) {
7192
+ const unresolved = ts5.isShorthandPropertyAssignment(expression.parent) ? checker.getShorthandAssignmentValueSymbol(expression.parent) : checker.getSymbolAtLocation(expression);
6960
7193
  if (!unresolved)
6961
7194
  return;
6962
7195
  const symbol = resolveAlias(unresolved, checker);
@@ -6964,25 +7197,25 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6964
7197
  return;
6965
7198
  seen.add(symbol);
6966
7199
  const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
6967
- if (!declaration || !ts4.isVariableDeclaration(declaration))
7200
+ if (!declaration || !ts5.isVariableDeclaration(declaration))
6968
7201
  return;
6969
7202
  return assetKey(declaration.initializer, checker, seen);
6970
7203
  }
6971
- if (!ts4.isCallExpression(expression))
7204
+ if (!ts5.isCallExpression(expression))
6972
7205
  return;
6973
- if (!ts4.isIdentifier(expression.expression) || expression.expression.text !== "asset") {
7206
+ if (!ts5.isIdentifier(expression.expression) || expression.expression.text !== "asset") {
6974
7207
  return;
6975
7208
  }
6976
7209
  const [, key] = expression.arguments;
6977
- return key && ts4.isStringLiteralLike(key) ? key.text : undefined;
7210
+ return key && ts5.isStringLiteralLike(key) ? key.text : undefined;
6978
7211
  }, staticString = (expression, bindings) => {
6979
- if (ts4.isStringLiteralLike(expression))
7212
+ if (ts5.isStringLiteralLike(expression))
6980
7213
  return expression.text;
6981
- if (ts4.isIdentifier(expression))
7214
+ if (ts5.isIdentifier(expression))
6982
7215
  return bindings.get(expression.text);
6983
- if (ts4.isNoSubstitutionTemplateLiteral(expression))
7216
+ if (ts5.isNoSubstitutionTemplateLiteral(expression))
6984
7217
  return expression.text;
6985
- if (!ts4.isTemplateExpression(expression))
7218
+ if (!ts5.isTemplateExpression(expression))
6986
7219
  return;
6987
7220
  let value = expression.head.text;
6988
7221
  for (const span of expression.templateSpans) {
@@ -6995,7 +7228,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
6995
7228
  }, assetKeyWithBindings = (expression, checker, bindings = new Map) => {
6996
7229
  if (!expression)
6997
7230
  return;
6998
- if (ts4.isCallExpression(expression) && ts4.isIdentifier(expression.expression) && expression.expression.text === "asset") {
7231
+ if (ts5.isCallExpression(expression) && ts5.isIdentifier(expression.expression) && expression.expression.text === "asset") {
6999
7232
  const [, key] = expression.arguments;
7000
7233
  return key ? staticString(key, bindings) : undefined;
7001
7234
  }
@@ -7005,16 +7238,16 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7005
7238
  const resolved = symbol ? resolveAlias(symbol, checker) : undefined;
7006
7239
  const declaration = resolved?.valueDeclaration ?? resolved?.declarations?.[0];
7007
7240
  let callable;
7008
- if (declaration && ts4.isFunctionDeclaration(declaration)) {
7241
+ if (declaration && ts5.isFunctionDeclaration(declaration)) {
7009
7242
  callable = declaration;
7010
- } else if (declaration && ts4.isVariableDeclaration(declaration) && declaration.initializer && (ts4.isArrowFunction(declaration.initializer) || ts4.isFunctionExpression(declaration.initializer))) {
7243
+ } else if (declaration && ts5.isVariableDeclaration(declaration) && declaration.initializer && (ts5.isArrowFunction(declaration.initializer) || ts5.isFunctionExpression(declaration.initializer))) {
7011
7244
  callable = declaration.initializer;
7012
7245
  }
7013
7246
  if (!callable)
7014
7247
  return;
7015
7248
  const bindings = new Map;
7016
7249
  callable.parameters.forEach((parameter, index) => {
7017
- if (!ts4.isIdentifier(parameter.name))
7250
+ if (!ts5.isIdentifier(parameter.name))
7018
7251
  return;
7019
7252
  const argument = call.arguments[index];
7020
7253
  if (!argument)
@@ -7026,33 +7259,33 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7026
7259
  const { body } = callable;
7027
7260
  if (!body)
7028
7261
  return;
7029
- const expressionBody = ts4.isParenthesizedExpression(body) ? body.expression : body;
7030
- if (ts4.isObjectLiteralExpression(expressionBody)) {
7262
+ const expressionBody = ts5.isParenthesizedExpression(body) ? body.expression : body;
7263
+ if (ts5.isObjectLiteralExpression(expressionBody)) {
7031
7264
  return { bindings, object: expressionBody };
7032
7265
  }
7033
- if (ts4.isBlock(body)) {
7034
- const returned = body.statements.find(ts4.isReturnStatement)?.expression;
7035
- if (returned && ts4.isObjectLiteralExpression(returned)) {
7266
+ if (ts5.isBlock(body)) {
7267
+ const returned = body.statements.find(ts5.isReturnStatement)?.expression;
7268
+ if (returned && ts5.isObjectLiteralExpression(returned)) {
7036
7269
  return { bindings, object: returned };
7037
7270
  }
7038
7271
  }
7039
7272
  return;
7040
7273
  }, spreadObject = (expression, checker, bindings) => {
7041
- if (ts4.isObjectLiteralExpression(expression)) {
7274
+ if (ts5.isObjectLiteralExpression(expression)) {
7042
7275
  return { bindings, object: expression };
7043
7276
  }
7044
- if (!ts4.isCallExpression(expression))
7277
+ if (!ts5.isCallExpression(expression))
7045
7278
  return;
7046
7279
  return callableObject(expression, checker);
7047
- }, objectAssetKey = (object2, name, checker, bindings = new Map) => {
7048
- for (const property of [...object2.properties].reverse()) {
7049
- if (propertyName(property) === name && ts4.isShorthandPropertyAssignment(property)) {
7280
+ }, objectAssetKey = (object3, name, checker, bindings = new Map) => {
7281
+ for (const property of [...object3.properties].reverse()) {
7282
+ if (propertyName(property) === name && ts5.isShorthandPropertyAssignment(property)) {
7050
7283
  return assetKeyWithBindings(property.name, checker, bindings);
7051
7284
  }
7052
- if (propertyName(property) === name && ts4.isPropertyAssignment(property)) {
7285
+ if (propertyName(property) === name && ts5.isPropertyAssignment(property)) {
7053
7286
  return assetKeyWithBindings(property.initializer, checker, bindings);
7054
7287
  }
7055
- if (!ts4.isSpreadAssignment(property))
7288
+ if (!ts5.isSpreadAssignment(property))
7056
7289
  continue;
7057
7290
  const nestedObject = spreadObject(property.expression, checker, bindings);
7058
7291
  if (!nestedObject)
@@ -7067,26 +7300,26 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7067
7300
  const visit = (candidate) => {
7068
7301
  if (found)
7069
7302
  return;
7070
- if (ts4.isCallExpression(candidate) && ts4.isIdentifier(candidate.expression) && PAGE_HANDLERS.has(candidate.expression.text)) {
7303
+ if (ts5.isCallExpression(candidate) && ts5.isIdentifier(candidate.expression) && PAGE_HANDLERS.has(candidate.expression.text)) {
7071
7304
  const definition = PAGE_HANDLERS.get(candidate.expression.text);
7072
7305
  if (!definition)
7073
7306
  return;
7074
7307
  found = { definition, node: candidate };
7075
7308
  return;
7076
7309
  }
7077
- ts4.forEachChild(candidate, visit);
7310
+ ts5.forEachChild(candidate, visit);
7078
7311
  };
7079
7312
  for (const node of nodes)
7080
7313
  visit(node);
7081
7314
  return found;
7082
7315
  }, isProjectSource = (sourceFile, resolvedFile, projectRoot) => !sourceFile.isDeclarationFile && !resolvedFile.includes("/node_modules/") && resolvedFile.startsWith(`${projectRoot}/`), analyzeRouteCall = (node, sourceFile, checker, projectRoot) => {
7083
7316
  const callee = node.expression;
7084
- if (!ts4.isPropertyAccessExpression(callee))
7317
+ if (!ts5.isPropertyAccessExpression(callee))
7085
7318
  return;
7086
7319
  if (!ROUTE_METHODS.has(callee.name.text))
7087
7320
  return;
7088
7321
  const [routePath] = node.arguments;
7089
- if (!routePath || !ts4.isStringLiteralLike(routePath))
7322
+ if (!routePath || !ts5.isStringLiteralLike(routePath))
7090
7323
  return;
7091
7324
  const foundPageCall = findPageCall(node.arguments.slice(1));
7092
7325
  const pageCall = foundPageCall?.node;
@@ -7119,7 +7352,7 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7119
7352
  routeCallSpan: `${node.getStart(sourceFile)}:${node.end}`
7120
7353
  };
7121
7354
  }
7122
- if (!ts4.isObjectLiteralExpression(input) || !definition.bundleProperty) {
7355
+ if (!ts5.isObjectLiteralExpression(input) || !definition.bundleProperty) {
7123
7356
  return;
7124
7357
  }
7125
7358
  const page = definition.pageProperty ? objectPropertyExpression(input, definition.pageProperty) : undefined;
@@ -7160,20 +7393,20 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7160
7393
  byRouteCall: new Map
7161
7394
  };
7162
7395
  const visit = (node) => {
7163
- const result = ts4.isCallExpression(node) ? analyzeRouteCall(node, sourceFile, checker, projectRoot) : undefined;
7396
+ const result = ts5.isCallExpression(node) ? analyzeRouteCall(node, sourceFile, checker, projectRoot) : undefined;
7164
7397
  if (result) {
7165
7398
  analysis.byPageCall.set(result.pageCallStart, result);
7166
7399
  analysis.byRouteCall.set(result.routeCallSpan, result);
7167
7400
  }
7168
- ts4.forEachChild(node, visit);
7401
+ ts5.forEachChild(node, visit);
7169
7402
  };
7170
- ts4.forEachChild(sourceFile, visit);
7403
+ ts5.forEachChild(sourceFile, visit);
7171
7404
  return analysis;
7172
7405
  }, analyzeProgram = (program, projectRoot) => {
7173
7406
  const checker = program.getTypeChecker();
7174
7407
  const analyzed = new Map;
7175
7408
  for (const sourceFile of program.getSourceFiles()) {
7176
- const resolvedFile = resolve17(sourceFile.fileName);
7409
+ const resolvedFile = resolve18(sourceFile.fileName);
7177
7410
  if (!isProjectSource(sourceFile, resolvedFile, projectRoot))
7178
7411
  continue;
7179
7412
  const analysis = analyzeSourceFile(sourceFile, checker, projectRoot);
@@ -7181,20 +7414,20 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7181
7414
  analyzed.set(resolvedFile, analysis);
7182
7415
  }
7183
7416
  return analyzed;
7184
- }, metadataExpression = (metadata) => ts4.factory.createObjectLiteralExpression(Object.entries(metadata).map(([key, item]) => ts4.factory.createPropertyAssignment(ts4.factory.createStringLiteral(key), ts4.factory.createStringLiteral(item))), false), routeOptions = (existing, metadata) => {
7185
- const detail = ts4.factory.createObjectLiteralExpression([
7186
- ts4.factory.createPropertyAssignment(ts4.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
7417
+ }, metadataExpression = (metadata) => ts5.factory.createObjectLiteralExpression(Object.entries(metadata).map(([key, item]) => ts5.factory.createPropertyAssignment(ts5.factory.createStringLiteral(key), ts5.factory.createStringLiteral(item))), false), routeOptions = (existing, metadata) => {
7418
+ const detail = ts5.factory.createObjectLiteralExpression([
7419
+ ts5.factory.createPropertyAssignment(ts5.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
7187
7420
  ]);
7188
7421
  if (!existing) {
7189
- return ts4.factory.createObjectLiteralExpression([
7190
- ts4.factory.createPropertyAssignment("detail", detail)
7422
+ return ts5.factory.createObjectLiteralExpression([
7423
+ ts5.factory.createPropertyAssignment("detail", detail)
7191
7424
  ]);
7192
7425
  }
7193
- return ts4.factory.createObjectLiteralExpression([
7194
- ts4.factory.createSpreadAssignment(existing),
7195
- ts4.factory.createPropertyAssignment("detail", ts4.factory.createObjectLiteralExpression([
7196
- ts4.factory.createSpreadAssignment(ts4.factory.createPropertyAccessExpression(existing, "detail")),
7197
- ts4.factory.createPropertyAssignment(ts4.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
7426
+ return ts5.factory.createObjectLiteralExpression([
7427
+ ts5.factory.createSpreadAssignment(existing),
7428
+ ts5.factory.createPropertyAssignment("detail", ts5.factory.createObjectLiteralExpression([
7429
+ ts5.factory.createSpreadAssignment(ts5.factory.createPropertyAccessExpression(existing, "detail")),
7430
+ ts5.factory.createPropertyAssignment(ts5.factory.createStringLiteral(ABSOLUTE_MOBILE_ROUTE_DETAIL), metadataExpression(metadata))
7198
7431
  ]))
7199
7432
  ]);
7200
7433
  }, transformPageCall = (node, page) => {
@@ -7204,19 +7437,19 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7204
7437
  const [pagePath, existingOptions, ...rest] = node.arguments;
7205
7438
  if (!pagePath)
7206
7439
  return;
7207
- const options = ts4.factory.createObjectLiteralExpression([
7208
- ...existingOptions ? [ts4.factory.createSpreadAssignment(existingOptions)] : [],
7209
- ts4.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
7440
+ const options = ts5.factory.createObjectLiteralExpression([
7441
+ ...existingOptions ? [ts5.factory.createSpreadAssignment(existingOptions)] : [],
7442
+ ts5.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
7210
7443
  ]);
7211
- return ts4.factory.updateCallExpression(node, node.expression, node.typeArguments, [pagePath, options, ...rest]);
7444
+ return ts5.factory.updateCallExpression(node, node.expression, node.typeArguments, [pagePath, options, ...rest]);
7212
7445
  }
7213
7446
  const [input] = node.arguments;
7214
- if (!input || !ts4.isObjectLiteralExpression(input))
7447
+ if (!input || !ts5.isObjectLiteralExpression(input))
7215
7448
  return;
7216
- return ts4.factory.updateCallExpression(node, node.expression, node.typeArguments, [
7217
- ts4.factory.updateObjectLiteralExpression(input, [
7449
+ return ts5.factory.updateCallExpression(node, node.expression, node.typeArguments, [
7450
+ ts5.factory.updateObjectLiteralExpression(input, [
7218
7451
  ...input.properties,
7219
- ts4.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
7452
+ ts5.factory.createPropertyAssignment("__absoluteMobile", metadataExpression(page.metadata))
7220
7453
  ]),
7221
7454
  ...node.arguments.slice(1)
7222
7455
  ]);
@@ -7228,15 +7461,15 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7228
7461
  return;
7229
7462
  const options = maybeHandler ? maybeOptions : undefined;
7230
7463
  const handler = maybeHandler ?? maybeOptions;
7231
- return ts4.factory.updateCallExpression(node, node.expression, node.typeArguments, [path, routeOptions(options, route.metadata), handler, ...rest]);
7464
+ return ts5.factory.updateCallExpression(node, node.expression, node.typeArguments, [path, routeOptions(options, route.metadata), handler, ...rest]);
7232
7465
  }, transformFile = (source, fileName, analysis) => {
7233
- const sourceFile = ts4.createSourceFile(fileName, source, ts4.ScriptTarget.Latest, true, fileName.endsWith("x") ? ts4.ScriptKind.TSX : ts4.ScriptKind.TS);
7466
+ const sourceFile = ts5.createSourceFile(fileName, source, ts5.ScriptTarget.Latest, true, fileName.endsWith("x") ? ts5.ScriptKind.TSX : ts5.ScriptKind.TS);
7234
7467
  const transformer = (context) => {
7235
7468
  const visit = (node) => {
7236
- if (!ts4.isCallExpression(node)) {
7237
- return ts4.visitEachChild(node, visit, context);
7469
+ if (!ts5.isCallExpression(node)) {
7470
+ return ts5.visitEachChild(node, visit, context);
7238
7471
  }
7239
- const transformedChildren = ts4.visitEachChild(node, visit, context);
7472
+ const transformedChildren = ts5.visitEachChild(node, visit, context);
7240
7473
  const page = analysis.byPageCall.get(node.getStart(sourceFile));
7241
7474
  const transformedPage = transformPageCall(transformedChildren, page);
7242
7475
  if (transformedPage)
@@ -7247,32 +7480,32 @@ var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.re
7247
7480
  return transformedRoute;
7248
7481
  return transformedChildren;
7249
7482
  };
7250
- return (node) => ts4.visitNode(node, visit, ts4.isSourceFile) ?? node;
7483
+ return (node) => ts5.visitNode(node, visit, ts5.isSourceFile) ?? node;
7251
7484
  };
7252
- const result = ts4.transform(sourceFile, [transformer]);
7485
+ const result = ts5.transform(sourceFile, [transformer]);
7253
7486
  try {
7254
7487
  const [transformed] = result.transformed;
7255
7488
  if (!transformed)
7256
7489
  throw new TypeError("Mobile route transform failed.");
7257
- return ts4.createPrinter().printFile(transformed);
7490
+ return ts5.createPrinter().printFile(transformed);
7258
7491
  } finally {
7259
7492
  result.dispose();
7260
7493
  }
7261
7494
  }, createAbsoluteMobileRouteMetadataPlugin = (options) => {
7262
- const projectRoot = resolve17(options.projectRoot ?? process.cwd());
7263
- const entry = resolve17(options.entry);
7495
+ const projectRoot = resolve18(options.projectRoot ?? process.cwd());
7496
+ const entry = resolve18(options.entry);
7264
7497
  const analyzed = analyzeProgram(createProgram(entry, projectRoot), projectRoot);
7265
7498
  return {
7266
7499
  name: "absolute-mobile-route-metadata",
7267
7500
  setup(build) {
7268
7501
  build.onLoad({ filter: SOURCE_FILTER }, async ({ path }) => {
7269
- const analysis = analyzed.get(resolve17(path));
7502
+ const analysis = analyzed.get(resolve18(path));
7270
7503
  if (!analysis)
7271
7504
  return;
7272
7505
  const source = await Bun.file(path).text();
7273
7506
  return {
7274
7507
  contents: transformFile(source, path, analysis),
7275
- loader: extname5(path).endsWith("x") ? "tsx" : "ts"
7508
+ loader: extname6(path).endsWith("x") ? "tsx" : "ts"
7276
7509
  };
7277
7510
  });
7278
7511
  }
@@ -7333,7 +7566,7 @@ var init_routeMetadataTransform = __esm(() => {
7333
7566
  });
7334
7567
 
7335
7568
  // src/cli/elysiaOpenApiTypeboxPlugin.ts
7336
- import { dirname as dirname14, resolve as resolve18 } from "path";
7569
+ import { dirname as dirname14, resolve as resolve19 } from "path";
7337
7570
  var OPENAPI_TYPEBOX_PREFIX = "../node_modules/typebox/", OPENAPI_DISTRIBUTION_SEGMENT = "/@elysia/openapi/dist/", createElysiaOpenApiTypeboxPlugin = () => ({
7338
7571
  name: "absolute-elysia-openapi-typebox",
7339
7572
  setup(build) {
@@ -7345,7 +7578,7 @@ var OPENAPI_TYPEBOX_PREFIX = "../node_modules/typebox/", OPENAPI_DISTRIBUTION_SE
7345
7578
  const relativePath = args.path.slice(OPENAPI_TYPEBOX_PREFIX.length);
7346
7579
  const typeboxEntry = Bun.resolveSync("typebox", dirname14(args.importer));
7347
7580
  return {
7348
- path: resolve18(dirname14(typeboxEntry), "..", relativePath)
7581
+ path: resolve19(dirname14(typeboxEntry), "..", relativePath)
7349
7582
  };
7350
7583
  });
7351
7584
  }
@@ -7405,15 +7638,15 @@ __export(exports_prerender, {
7405
7638
  prerender: () => prerender,
7406
7639
  PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER
7407
7640
  });
7408
- import { mkdirSync as mkdirSync6, readFileSync as readFileSync13 } from "fs";
7409
- import { join as join21 } from "path";
7641
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync14 } from "fs";
7642
+ import { join as join22 } from "path";
7410
7643
  var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_TIMEOUT_MS = 30000, DEFAULT_FETCH_TIMEOUT_MS = 1e4, PRERENDER_BYPASS_HEADER = "X-Absolute-Prerender-Bypass", routeToFilename = (route) => route === "/" ? "index.html" : `${route.slice(1).replace(/\//g, "-")}.html`, writeTimestamp = async (htmlPath) => {
7411
7644
  const metaPath = htmlPath.replace(/\.html$/, ".meta");
7412
7645
  await Bun.write(metaPath, String(Date.now()));
7413
7646
  }, readTimestamp = (htmlPath) => {
7414
7647
  const metaPath = htmlPath.replace(/\.html$/, ".meta");
7415
7648
  try {
7416
- const content = readFileSync13(metaPath, "utf-8");
7649
+ const content = readFileSync14(metaPath, "utf-8");
7417
7650
  return Number(content) || 0;
7418
7651
  } catch {
7419
7652
  return 0;
@@ -7476,7 +7709,7 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
7476
7709
  if (!isCompleteHtml(html))
7477
7710
  return false;
7478
7711
  const fileName = routeToFilename(route);
7479
- const filePath = join21(prerenderDir, fileName);
7712
+ const filePath = join22(prerenderDir, fileName);
7480
7713
  await Bun.write(filePath, html);
7481
7714
  await writeTimestamp(filePath);
7482
7715
  return true;
@@ -7506,13 +7739,13 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
7506
7739
  return;
7507
7740
  }
7508
7741
  const fileName = routeToFilename(route);
7509
- const filePath = join21(prerenderDir, fileName);
7742
+ const filePath = join22(prerenderDir, fileName);
7510
7743
  await Bun.write(filePath, html);
7511
7744
  await writeTimestamp(filePath);
7512
7745
  result.routes.set(route, filePath);
7513
7746
  log?.(` Pre-rendered ${route} \u2192 ${fileName} (${html.length} bytes)`);
7514
7747
  }, prerender = async (port, outDir, staticConfig, log) => {
7515
- const prerenderDir = join21(outDir, "_prerendered");
7748
+ const prerenderDir = join22(outDir, "_prerendered");
7516
7749
  mkdirSync6(prerenderDir, { recursive: true });
7517
7750
  const baseUrl = `http://localhost:${port}`;
7518
7751
  let routes;
@@ -7579,10 +7812,10 @@ var SERVER_OUTPUT_LIMIT = 4000, STARTUP_POLL_INTERVAL_MS = 100, DEFAULT_STARTUP_
7579
7812
  };
7580
7813
  read();
7581
7814
  }, formatServerOutput = (output) => {
7582
- const text = output.join("").trim();
7583
- if (!text)
7815
+ const text2 = output.join("").trim();
7816
+ if (!text2)
7584
7817
  return "";
7585
- return text.length > SERVER_OUTPUT_LIMIT ? text.slice(-SERVER_OUTPUT_LIMIT) : text;
7818
+ return text2.length > SERVER_OUTPUT_LIMIT ? text2.slice(-SERVER_OUTPUT_LIMIT) : text2;
7586
7819
  }, createServerStartupError = (output) => {
7587
7820
  const serverOutput = formatServerOutput(output);
7588
7821
  const message = serverOutput ? `Server failed to start for pre-rendering.
@@ -7631,9 +7864,9 @@ var SENTINEL, RISKY_STRING_CONTENT, isIdentChar = (c) => /[A-Za-z0-9_$]/.test(c)
7631
7864
  let prevChar = "";
7632
7865
  let prevWord = "";
7633
7866
  let prevWasSpace = false;
7634
- const mask = (text) => {
7867
+ const mask = (text2) => {
7635
7868
  out += SENTINEL + pieces.length + SENTINEL;
7636
- pieces.push(text);
7869
+ pieces.push(text2);
7637
7870
  prevChar = ")";
7638
7871
  prevWord = "";
7639
7872
  prevWasSpace = false;
@@ -7799,11 +8032,11 @@ var SENTINEL, RISKY_STRING_CONTENT, isIdentChar = (c) => /[A-Za-z0-9_$]/.test(c)
7799
8032
  }
7800
8033
  if (c === '"' || c === "'") {
7801
8034
  const end = endOfString(i);
7802
- const text = src.slice(i, end);
7803
- if (RISKY_STRING_CONTENT.test(text)) {
7804
- mask(text);
8035
+ const text2 = src.slice(i, end);
8036
+ if (RISKY_STRING_CONTENT.test(text2)) {
8037
+ mask(text2);
7805
8038
  } else {
7806
- out += text;
8039
+ out += text2;
7807
8040
  prevChar = '"';
7808
8041
  prevWord = "";
7809
8042
  prevWasSpace = false;
@@ -7888,7 +8121,7 @@ var init_maskLiterals = __esm(() => {
7888
8121
  // src/build/nativeRewrite.ts
7889
8122
  import { dlopen, FFIType, ptr } from "bun:ffi";
7890
8123
  import { platform as platform4, arch as arch3 } from "os";
7891
- import { resolve as resolve19 } from "path";
8124
+ import { resolve as resolve20 } from "path";
7892
8125
  var ffiDefinition, nativeLib = null, loadNative = () => {
7893
8126
  if (nativeLib !== null)
7894
8127
  return nativeLib;
@@ -7906,7 +8139,7 @@ var ffiDefinition, nativeLib = null, loadNative = () => {
7906
8139
  if (!libPath)
7907
8140
  return null;
7908
8141
  try {
7909
- const fullPath = resolve19(import.meta.dir, "../../native/packages", libPath);
8142
+ const fullPath = resolve20(import.meta.dir, "../../native/packages", libPath);
7910
8143
  const lib = dlopen(fullPath, ffiDefinition);
7911
8144
  nativeLib = lib.symbols;
7912
8145
  return nativeLib;
@@ -7948,7 +8181,7 @@ var init_nativeRewrite = __esm(() => {
7948
8181
 
7949
8182
  // src/build/rewriteImportsPlugin.ts
7950
8183
  import { readdir as readdir3 } from "fs/promises";
7951
- import { join as join22 } from "path";
8184
+ import { join as join23 } from "path";
7952
8185
  var escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), jsRewriteImports = (content, replacements) => {
7953
8186
  let result = content;
7954
8187
  for (const [specifier, webPath] of replacements) {
@@ -8027,7 +8260,7 @@ ${content}`;
8027
8260
  const entries = await readdir3(dir);
8028
8261
  for (const entry of entries) {
8029
8262
  if (entry.endsWith(".js"))
8030
- allFiles.push(join22(dir, entry));
8263
+ allFiles.push(join23(dir, entry));
8031
8264
  }
8032
8265
  } catch {}
8033
8266
  }
@@ -8102,8 +8335,8 @@ var init_rewriteImports = __esm(() => {
8102
8335
 
8103
8336
  // src/cli/scripts/start.ts
8104
8337
  var {env: env2 } = globalThis.Bun;
8105
- import { existsSync as existsSync11, readFileSync as readFileSync14, rmSync as rmSync4 } from "fs";
8106
- import { basename as basename8, join as join23, resolve as resolve20 } from "path";
8338
+ import { existsSync as existsSync11, readFileSync as readFileSync15, rmSync as rmSync4 } from "fs";
8339
+ import { basename as basename8, join as join24, resolve as resolve21 } from "path";
8107
8340
  var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, resolvePackageVersion = (candidates) => {
8108
8341
  for (const candidate of candidates) {
8109
8342
  const version2 = readPackageVersion2(candidate);
@@ -8114,7 +8347,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8114
8347
  return "";
8115
8348
  }, readPackageVersion2 = (candidate) => {
8116
8349
  try {
8117
- const pkg = JSON.parse(readFileSync14(candidate, "utf-8"));
8350
+ const pkg = JSON.parse(readFileSync15(candidate, "utf-8"));
8118
8351
  if (pkg.name !== "@absolutejs/absolute")
8119
8352
  return null;
8120
8353
  const ver = pkg.version;
@@ -8152,18 +8385,18 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8152
8385
  process.exit(1);
8153
8386
  }, resolveJsxDevRuntimeCompatPath = () => {
8154
8387
  const candidates = [
8155
- resolve20(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
8156
- resolve20(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
8157
- resolve20(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
8158
- resolve20(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
8159
- resolve20(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
8160
- resolve20(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
8388
+ resolve21(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
8389
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
8390
+ resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
8391
+ resolve21(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
8392
+ resolve21(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
8393
+ resolve21(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
8161
8394
  ];
8162
8395
  for (const candidate of candidates) {
8163
8396
  if (existsSync11(candidate))
8164
8397
  return candidate;
8165
8398
  }
8166
- return resolve20(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
8399
+ return resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
8167
8400
  }, jsxDevRuntimeCompatPath, prerenderStaticPages = async (outputPath, prerenderPort, resolvedOutdir, staticConfig, absoluteVersion, configPath2) => {
8168
8401
  const prerenderStart = performance.now();
8169
8402
  process.stdout.write(cliTag2("\x1B[36m", "Pre-rendering static pages"));
@@ -8197,7 +8430,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8197
8430
  serverEntry,
8198
8431
  totalDuration
8199
8432
  }) => {
8200
- const usesDocker = existsSync11(resolve20(COMPOSE_PATH));
8433
+ const usesDocker = existsSync11(resolve21(COMPOSE_PATH));
8201
8434
  const scripts = usesDocker ? await readDbScripts() : null;
8202
8435
  if (scripts)
8203
8436
  await startDatabase(scripts);
@@ -8288,10 +8521,10 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8288
8521
  const port = Number(env2.PORT) || DEFAULT_PORT;
8289
8522
  killStaleProcesses(port);
8290
8523
  const entryName = basename8(serverEntry).replace(/\.[^.]+$/, "");
8291
- const resolvedOutdir = resolve20(outdir ?? "dist");
8524
+ const resolvedOutdir = resolve21(outdir ?? "dist");
8292
8525
  const absoluteVersion = resolvePackageVersion([
8293
- resolve20(import.meta.dir, "..", "..", "..", "package.json"),
8294
- resolve20(import.meta.dir, "..", "..", "package.json")
8526
+ resolve21(import.meta.dir, "..", "..", "..", "package.json"),
8527
+ resolve21(import.meta.dir, "..", "..", "package.json")
8295
8528
  ]);
8296
8529
  const buildConfig = await loadConfig(configPath2);
8297
8530
  buildConfig.buildDirectory = resolvedOutdir;
@@ -8306,7 +8539,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8306
8539
  buildConfig.vueDirectory && "vue",
8307
8540
  buildConfig.angularDirectory && "angular"
8308
8541
  ].filter((val) => Boolean(val));
8309
- const outputPath = resolve20(resolvedOutdir, `${entryName}.js`);
8542
+ const outputPath = resolve21(resolvedOutdir, `${entryName}.js`);
8310
8543
  if (options.prebuilt) {
8311
8544
  if (!existsSync11(outputPath)) {
8312
8545
  throw new Error(`Prepared production server not found: ${outputPath}`);
@@ -8329,13 +8562,13 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8329
8562
  process.stdout.write(cliTag2("\x1B[36m", `Building assets`));
8330
8563
  try {
8331
8564
  const build = await resolveBuildModule([
8332
- resolve20(import.meta.dir, "..", "..", "core", "build"),
8333
- resolve20(import.meta.dir, "..", "build")
8565
+ resolve21(import.meta.dir, "..", "..", "core", "build"),
8566
+ resolve21(import.meta.dir, "..", "build")
8334
8567
  ]);
8335
8568
  if (!build)
8336
8569
  throw new Error("Could not locate build module");
8337
8570
  await build(buildConfig);
8338
- rmSync4(join23(resolvedOutdir, "_prerendered"), {
8571
+ rmSync4(join24(resolvedOutdir, "_prerendered"), {
8339
8572
  force: true,
8340
8573
  recursive: true
8341
8574
  });
@@ -8400,8 +8633,8 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8400
8633
  const normalizedPath = args.path.replace(/\\/g, "/");
8401
8634
  if (normalizedPath.includes("/src/angular/"))
8402
8635
  return;
8403
- const text = await Bun.file(args.path).text();
8404
- if (text.includes("@Component") && stripStringsAndComments(text).includes("@Component")) {
8636
+ const text2 = await Bun.file(args.path).text();
8637
+ if (text2.includes("@Component") && stripStringsAndComments(text2).includes("@Component")) {
8405
8638
  return {
8406
8639
  contents: "export default {}",
8407
8640
  loader: "js"
@@ -8412,17 +8645,17 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8412
8645
  }
8413
8646
  };
8414
8647
  const islandRegistrySpec = buildConfig.islands?.registry;
8415
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve20(islandRegistrySpec))) : undefined;
8648
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve21(islandRegistrySpec))) : undefined;
8416
8649
  const serverBundle = await Bun.build({
8417
8650
  define: { "process.env.NODE_ENV": '"production"' },
8418
- entrypoints: [resolve20(serverEntry)],
8651
+ entrypoints: [resolve21(serverEntry)],
8419
8652
  external: resolveServerBundleExternals(buildConfig),
8420
8653
  outdir: resolvedOutdir,
8421
8654
  plugins: [
8422
8655
  ...islandRegistryPlugin ? [islandRegistryPlugin] : [],
8423
8656
  ...buildConfig.mobile ? [
8424
8657
  createAbsoluteMobileRouteMetadataPlugin({
8425
- entry: resolve20(serverEntry)
8658
+ entry: resolve21(serverEntry)
8426
8659
  })
8427
8660
  ] : [],
8428
8661
  createElysiaOpenApiTypeboxPlugin(),
@@ -8439,9 +8672,9 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8439
8672
  console.error(cliTag2("\x1B[31m", `Expected output not found: ${outputPath}`));
8440
8673
  process.exit(1);
8441
8674
  }
8442
- if (existsSync11(resolve20(resolvedOutdir, "angular", "vendor", "server"))) {
8675
+ if (existsSync11(resolve21(resolvedOutdir, "angular", "vendor", "server"))) {
8443
8676
  const { readdirSync: readdirSync2 } = await import("fs");
8444
- const vendorDir = resolve20(resolvedOutdir, "angular", "vendor", "server");
8677
+ const vendorDir = resolve21(resolvedOutdir, "angular", "vendor", "server");
8445
8678
  const vendorEntries = readdirSync2(vendorDir).filter((fileName) => fileName.endsWith(".js"));
8446
8679
  const angularServerVendorPaths = {};
8447
8680
  const { relative: pathRelative, dirname: pathDirname } = await import("path");
@@ -8451,7 +8684,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
8451
8684
  if (scope !== "angular" || rest.length === 0)
8452
8685
  continue;
8453
8686
  const specifier = `@angular/${rest.join("/")}`;
8454
- const relPath = pathRelative(pathDirname(outputPath), resolve20(vendorDir, file));
8687
+ const relPath = pathRelative(pathDirname(outputPath), resolve21(vendorDir, file));
8455
8688
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
8456
8689
  }
8457
8690
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -8638,17 +8871,17 @@ var exports_build = {};
8638
8871
  __export(exports_build, {
8639
8872
  build: () => build
8640
8873
  });
8641
- import { existsSync as existsSync13, readdirSync as readdirSync3, readFileSync as readFileSync16 } from "fs";
8642
- import { join as join24, resolve as resolve22 } from "path";
8874
+ import { existsSync as existsSync13, readdirSync as readdirSync3, readFileSync as readFileSync17 } from "fs";
8875
+ import { join as join25, resolve as resolve23 } from "path";
8643
8876
  var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, printProfile = (buildDir) => {
8644
- const traceDir = join24(buildDir, ".absolute-trace");
8877
+ const traceDir = join25(buildDir, ".absolute-trace");
8645
8878
  if (!existsSync13(traceDir))
8646
8879
  return;
8647
8880
  const files = readdirSync3(traceDir).filter((file) => file.endsWith(".json")).sort();
8648
8881
  const latest = files[files.length - 1];
8649
8882
  if (latest === undefined)
8650
8883
  return;
8651
- const trace = JSON.parse(readFileSync16(join24(traceDir, latest), "utf-8"));
8884
+ const trace = JSON.parse(readFileSync17(join25(traceDir, latest), "utf-8"));
8652
8885
  const events = Array.isArray(trace.events) ? trace.events : [];
8653
8886
  if (events.length === 0)
8654
8887
  return;
@@ -8685,7 +8918,7 @@ var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message
8685
8918
  }
8686
8919
  return resolveBuildModule2(remaining);
8687
8920
  }, build = async (outdir, configPath2, profile = false) => {
8688
- const resolvedOutdir = resolve22(outdir ?? "build");
8921
+ const resolvedOutdir = resolve23(outdir ?? "build");
8689
8922
  const buildStart = performance.now();
8690
8923
  if (profile)
8691
8924
  process.env.ABSOLUTE_BUILD_TRACE = "1";
@@ -8695,8 +8928,8 @@ var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message
8695
8928
  buildConfig.mode = "production";
8696
8929
  try {
8697
8930
  const buildApp = await resolveBuildModule2([
8698
- resolve22(import.meta.dir, "..", "..", "core", "build"),
8699
- resolve22(import.meta.dir, "..", "build")
8931
+ resolve23(import.meta.dir, "..", "..", "core", "build"),
8932
+ resolve23(import.meta.dir, "..", "build")
8700
8933
  ]);
8701
8934
  if (!buildApp)
8702
8935
  throw new Error("Could not locate build module");
@@ -8745,14 +8978,14 @@ import {
8745
8978
  lstatSync,
8746
8979
  mkdirSync as mkdirSync8,
8747
8980
  mkdtempSync,
8748
- readFileSync as readFileSync17,
8981
+ readFileSync as readFileSync18,
8749
8982
  realpathSync,
8750
8983
  renameSync as renameSync2,
8751
8984
  rmSync as rmSync5,
8752
8985
  writeFileSync as writeFileSync7
8753
8986
  } from "fs";
8754
8987
  import { tmpdir as tmpdir3 } from "os";
8755
- import { delimiter, dirname as dirname15, relative as relative12, resolve as resolve23 } from "path";
8988
+ import { delimiter, dirname as dirname15, relative as relative13, resolve as resolve24 } from "path";
8756
8989
  var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSION = 2, FLAG_NOT_FOUND = -1, CHUNKED_FLAG = "--chunked", TSCONFIG_PATTERN, ABSOLUTE_BINARY, runGit = (args, options) => {
8757
8990
  const proc = Bun.spawnSync(["git", ...args], {
8758
8991
  cwd: options.cwd,
@@ -8765,8 +8998,8 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8765
8998
  throw new Error(detail || `git ${args.join(" ")} failed`);
8766
8999
  }
8767
9000
  return proc.stdout.toString().trim();
8768
- }, gitRoot = (cwd) => resolve23(runGit(["rev-parse", "--show-toplevel"], { cwd })), isInside3 = (parent, candidate) => {
8769
- const path = relative12(parent, candidate);
9001
+ }, gitRoot = (cwd) => resolve24(runGit(["rev-parse", "--show-toplevel"], { cwd })), isInside3 = (parent, candidate) => {
9002
+ const path = relative13(parent, candidate);
8770
9003
  return path === "" || !path.startsWith("../") && path !== "..";
8771
9004
  }, attestationPayload = (proof) => Buffer.from([
8772
9005
  "absolute-lint-proof-attestation:1",
@@ -8778,17 +9011,17 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8778
9011
  sourceTree: proof.sourceTree
8779
9012
  })
8780
9013
  ].join("\x00")), publicKeyId = (key) => createHash11("sha256").update(key.export({ format: "der", type: "spki" })).digest("hex"), readEd25519PrivateKey = (cwd, location) => {
8781
- const path = resolve23(cwd, location);
9014
+ const path = resolve24(cwd, location);
8782
9015
  if (isInside3(realpathSync(gitRoot(cwd)), realpathSync(path))) {
8783
9016
  throw new Error("lint proof signing key must live outside the Git working tree");
8784
9017
  }
8785
- const key = createPrivateKey(readFileSync17(path));
9018
+ const key = createPrivateKey(readFileSync18(path));
8786
9019
  if (key.asymmetricKeyType !== "ed25519") {
8787
9020
  throw new Error("lint proof signing key must be an Ed25519 private key");
8788
9021
  }
8789
9022
  return key;
8790
9023
  }, readEd25519PublicKey = (cwd, location) => {
8791
- const key = createPublicKey(readFileSync17(resolve23(cwd, location)));
9024
+ const key = createPublicKey(readFileSync18(resolve24(cwd, location)));
8792
9025
  if (key.asymmetricKeyType !== "ed25519") {
8793
9026
  throw new Error("trusted lint proof key must be an Ed25519 public key");
8794
9027
  }
@@ -8816,7 +9049,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8816
9049
  return null;
8817
9050
  const auxiliary = gitVisibleFiles(root).filter((file) => TSCONFIG_PATTERN.test(file));
8818
9051
  const configPath2 = findEslintConfigPath(root);
8819
- const configRelative = configPath2 === null ? null : relative12(root, configPath2).replaceAll("\\", "/");
9052
+ const configRelative = configPath2 === null ? null : relative13(root, configPath2).replaceAll("\\", "/");
8820
9053
  return [
8821
9054
  ...new Set([
8822
9055
  ...resolveLintTargets(args, root),
@@ -8826,17 +9059,17 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8826
9059
  ].sort();
8827
9060
  }, createLintSourceTree = (cwd = process.cwd(), proofLocation = DEFAULT_PROOF_LOCATION, command = []) => {
8828
9061
  const root = gitRoot(cwd);
8829
- const proofPath = resolve23(cwd, proofLocation);
8830
- const proofRelative = relative12(root, proofPath).replaceAll("\\", "/");
9062
+ const proofPath = resolve24(cwd, proofLocation);
9063
+ const proofRelative = relative13(root, proofPath).replaceAll("\\", "/");
8831
9064
  if (proofRelative === ".." || proofRelative.startsWith("../") || proofRelative === "") {
8832
9065
  throw new Error("lint proof must live inside the Git working tree");
8833
9066
  }
8834
- const temporaryDirectory = mkdtempSync(resolve23(tmpdir3(), "absolute-lint-proof-"));
8835
- const temporaryIndex = resolve23(temporaryDirectory, "index");
8836
- const temporaryObjects = resolve23(temporaryDirectory, "objects");
9067
+ const temporaryDirectory = mkdtempSync(resolve24(tmpdir3(), "absolute-lint-proof-"));
9068
+ const temporaryIndex = resolve24(temporaryDirectory, "index");
9069
+ const temporaryObjects = resolve24(temporaryDirectory, "objects");
8837
9070
  mkdirSync8(temporaryObjects, { recursive: true });
8838
9071
  const repositoryObjectsPath = runGit(["rev-parse", "--git-path", "objects"], { cwd: root });
8839
- const repositoryObjects = resolve23(root, repositoryObjectsPath);
9072
+ const repositoryObjects = resolve24(root, repositoryObjectsPath);
8840
9073
  const existingAlternates = process.env.GIT_ALTERNATE_OBJECT_DIRECTORIES?.trim();
8841
9074
  const env3 = {
8842
9075
  GIT_ALTERNATE_OBJECT_DIRECTORIES: [
@@ -8860,7 +9093,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8860
9093
  if (!path || path === proofRelative)
8861
9094
  return false;
8862
9095
  try {
8863
- lstatSync(resolve23(root, path));
9096
+ lstatSync(resolve24(root, path));
8864
9097
  return true;
8865
9098
  } catch {
8866
9099
  return false;
@@ -8884,7 +9117,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8884
9117
  }, writeLintProof = (command, options = {}) => {
8885
9118
  const cwd = options.cwd ?? process.cwd();
8886
9119
  const proofLocation = options.proofLocation ?? DEFAULT_PROOF_LOCATION;
8887
- const path = resolve23(cwd, proofLocation);
9120
+ const path = resolve24(cwd, proofLocation);
8888
9121
  const temporary = `${path}.${process.pid}.tmp`;
8889
9122
  const proof = createLintProof(command, { cwd, proofLocation });
8890
9123
  if (options.signingKeyLocation) {
@@ -8940,12 +9173,12 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
8940
9173
  }, verifyLintProof = (command, options = {}) => {
8941
9174
  const cwd = options.cwd ?? process.cwd();
8942
9175
  const proofLocation = options.proofLocation ?? DEFAULT_PROOF_LOCATION;
8943
- const path = resolve23(cwd, proofLocation);
9176
+ const path = resolve24(cwd, proofLocation);
8944
9177
  if (!existsSync14(path))
8945
9178
  return { reason: `missing lint proof: ${proofLocation}`, valid: false };
8946
9179
  let proof;
8947
9180
  try {
8948
- proof = JSON.parse(readFileSync17(path, "utf-8"));
9181
+ proof = JSON.parse(readFileSync18(path, "utf-8"));
8949
9182
  } catch {
8950
9183
  return { reason: `invalid lint proof: ${proofLocation}`, valid: false };
8951
9184
  }
@@ -9110,8 +9343,8 @@ var exports_ls = {};
9110
9343
  __export(exports_ls, {
9111
9344
  runLs: () => runLs
9112
9345
  });
9113
- import { existsSync as existsSync16, readFileSync as readFileSync18, statSync } from "fs";
9114
- import { basename as basename10, extname as extname6, join as join25, relative as relative13 } from "path";
9346
+ import { existsSync as existsSync16, readFileSync as readFileSync19, statSync } from "fs";
9347
+ import { basename as basename10, extname as extname7, join as join26, relative as relative14 } from "path";
9115
9348
  var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELDS, readStringField = (source, key) => {
9116
9349
  const value = Reflect.get(source, key);
9117
9350
  return typeof value === "string" ? value : undefined;
@@ -9126,24 +9359,24 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
9126
9359
  } catch {
9127
9360
  return null;
9128
9361
  }
9129
- }, relativeOrSelf = (target) => relative13(process.cwd(), target) || target, configCandidates = (raw) => isWorkspaceConfig(raw) ? Object.values(raw).map((service) => ({
9362
+ }, relativeOrSelf = (target) => relative14(process.cwd(), target) || target, configCandidates = (raw) => isWorkspaceConfig(raw) ? Object.values(raw).map((service) => ({
9130
9363
  baseDir: readStringField(service, "cwd") ?? ".",
9131
9364
  source: service
9132
9365
  })) : [{ baseDir: ".", source: raw }], specsFor = (source, baseDir) => FRAMEWORK_FIELDS.flatMap((framework) => {
9133
9366
  const dir = readStringField(source, framework.field);
9134
9367
  return dir === undefined ? [] : [
9135
9368
  {
9136
- dir: join25(baseDir, dir),
9369
+ dir: join26(baseDir, dir),
9137
9370
  label: framework.label,
9138
9371
  pattern: framework.pattern
9139
9372
  }
9140
9373
  ];
9141
9374
  }), scanFramework = async (spec) => {
9142
- const { pageFiles } = await scanConventions(join25(spec.dir, "pages"), spec.pattern);
9375
+ const { pageFiles } = await scanConventions(join26(spec.dir, "pages"), spec.pattern);
9143
9376
  if (pageFiles.length === 0)
9144
9377
  return null;
9145
9378
  const pages = pageFiles.map((file) => ({
9146
- name: basename10(file, extname6(file)),
9379
+ name: basename10(file, extname7(file)),
9147
9380
  sizeBytes: null,
9148
9381
  sourcePath: relativeOrSelf(file)
9149
9382
  }));
@@ -9163,10 +9396,10 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
9163
9396
  }, resolveDiskPath = (buildDir, value) => {
9164
9397
  if (existsSync16(value))
9165
9398
  return value;
9166
- const underBuild = join25(buildDir, value);
9399
+ const underBuild = join26(buildDir, value);
9167
9400
  if (existsSync16(underBuild))
9168
9401
  return underBuild;
9169
- return join25(process.cwd(), value);
9402
+ return join26(process.cwd(), value);
9170
9403
  }, fileSize = (diskPath) => {
9171
9404
  try {
9172
9405
  return statSync(diskPath).size;
@@ -9174,7 +9407,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
9174
9407
  return 0;
9175
9408
  }
9176
9409
  }, readManifestSizes = (manifestDir) => {
9177
- const manifest = JSON.parse(readFileSync18(join25(manifestDir, "manifest.json"), "utf-8"));
9410
+ const manifest = JSON.parse(readFileSync19(join26(manifestDir, "manifest.json"), "utf-8"));
9178
9411
  const sizes = new Map;
9179
9412
  Object.entries(manifest).forEach(([key, value]) => {
9180
9413
  sizes.set(key, fileSize(resolveDiskPath(manifestDir, value)));
@@ -9193,7 +9426,7 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
9193
9426
  }))
9194
9427
  })), manifestAge = (manifestPath) => getDurationString(Date.now() - statSync(manifestPath).mtimeMs), firstBuildDir = (candidates) => candidates.map((candidate) => {
9195
9428
  const dir = readStringField(candidate.source, "buildDirectory");
9196
- return dir === undefined ? undefined : join25(candidate.baseDir, dir);
9429
+ return dir === undefined ? undefined : join26(candidate.baseDir, dir);
9197
9430
  }).find((dir) => dir !== undefined), resolveSizesDir = (args, candidates) => parseFlagValue(args, "--outdir") ?? firstBuildDir(candidates) ?? DEFAULT_BUILD_DIR, formatSize = (bytes) => {
9198
9431
  if (bytes === null || bytes === 0)
9199
9432
  return "-";
@@ -9291,7 +9524,7 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
9291
9524
  return;
9292
9525
  }
9293
9526
  const sizesDir = resolveSizesDir(args, candidates);
9294
- const manifestPath = join25(sizesDir, "manifest.json");
9527
+ const manifestPath = join26(sizesDir, "manifest.json");
9295
9528
  if (!existsSync16(manifestPath)) {
9296
9529
  printDim(`No build at ${relativeOrSelf(manifestPath)}. Run \`absolute build\` first, or pass \`--outdir <dir>\`.`);
9297
9530
  return;
@@ -9416,21 +9649,21 @@ var init_discoverInstances = __esm(() => {
9416
9649
  import { createConnection as createConnection2 } from "net";
9417
9650
  var {$: $4 } = globalThis.Bun;
9418
9651
  var displayHost = (host2) => host2 === "0.0.0.0" || host2 === "::" ? "localhost" : host2, probePort = (host2, port) => {
9419
- const { promise, resolve: resolve24 } = Promise.withResolvers();
9652
+ const { promise, resolve: resolve25 } = Promise.withResolvers();
9420
9653
  const socket = createConnection2({ host: displayHost(host2), port });
9421
9654
  const timeout = setTimeout(() => {
9422
9655
  socket.destroy();
9423
- resolve24(false);
9656
+ resolve25(false);
9424
9657
  }, INSTANCE_PROBE_TIMEOUT_MS);
9425
9658
  socket.once("connect", () => {
9426
9659
  clearTimeout(timeout);
9427
9660
  socket.end();
9428
- resolve24(true);
9661
+ resolve25(true);
9429
9662
  });
9430
9663
  socket.once("error", () => {
9431
9664
  clearTimeout(timeout);
9432
9665
  socket.destroy();
9433
- resolve24(false);
9666
+ resolve25(false);
9434
9667
  });
9435
9668
  return promise;
9436
9669
  }, probeStatus = async (record) => {
@@ -9562,8 +9795,8 @@ var TUI_HEADERS, STATUS_INDEX = 8, URL_INDEX = 9, MEM_HISTORY_MAX = 12, SPARK_CH
9562
9795
  render();
9563
9796
  }, LIST_TUI_RENDER_DEBOUNCE_MS);
9564
9797
  };
9565
- const setStatus = (text, level) => {
9566
- statusMessage = { level, text };
9798
+ const setStatus = (text2, level) => {
9799
+ statusMessage = { level, text: text2 };
9567
9800
  if (statusTimer)
9568
9801
  clearTimeout(statusTimer);
9569
9802
  statusTimer = setTimeout(() => {
@@ -10142,9 +10375,9 @@ var exports_heapDiff = {};
10142
10375
  __export(exports_heapDiff, {
10143
10376
  runHeapDiff: () => runHeapDiff
10144
10377
  });
10145
- import { existsSync as existsSync17, readFileSync as readFileSync19 } from "fs";
10378
+ import { existsSync as existsSync17, readFileSync as readFileSync20 } from "fs";
10146
10379
  var TOP = 15, STRING_TYPES, aggregate = (path) => {
10147
- const data = JSON.parse(readFileSync19(path, "utf-8"));
10380
+ const data = JSON.parse(readFileSync20(path, "utf-8"));
10148
10381
  const { nodes, strings } = data;
10149
10382
  const { node_fields: fields, node_types: nodeTypes } = data.snapshot.meta;
10150
10383
  const [typeNames] = nodeTypes;
@@ -10292,31 +10525,31 @@ var init_mem = __esm(() => {
10292
10525
  var isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
10293
10526
 
10294
10527
  // src/cli/config/schema/fromType.ts
10295
- import ts5 from "typescript";
10528
+ import ts6 from "typescript";
10296
10529
  import {
10297
10530
  existsSync as existsSync18,
10298
10531
  mkdirSync as mkdirSync9,
10299
- readFileSync as readFileSync20,
10532
+ readFileSync as readFileSync21,
10300
10533
  statSync as statSync2,
10301
10534
  writeFileSync as writeFileSync8
10302
10535
  } from "fs";
10303
- import { resolve as resolve24 } from "path";
10536
+ import { resolve as resolve25 } from "path";
10304
10537
  var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFrameworkRepo = (cwd) => {
10305
10538
  try {
10306
- const pkg = JSON.parse(readFileSync20(resolve24(cwd, "package.json"), "utf-8"));
10539
+ const pkg = JSON.parse(readFileSync21(resolve25(cwd, "package.json"), "utf-8"));
10307
10540
  return pkg?.name === "@absolutejs/absolute";
10308
10541
  } catch {
10309
10542
  return false;
10310
10543
  }
10311
10544
  }, compilerOptionsFor = (cwd) => {
10312
- const tsconfigPath = ts5.findConfigFile(cwd, ts5.sys.fileExists, "tsconfig.json");
10545
+ const tsconfigPath = ts6.findConfigFile(cwd, ts6.sys.fileExists, "tsconfig.json");
10313
10546
  const parseConfigHost = {
10314
- ...ts5.sys,
10547
+ ...ts6.sys,
10315
10548
  onUnRecoverableConfigFileDiagnostic: () => {}
10316
10549
  };
10317
- const base = tsconfigPath && ts5.getParsedCommandLineOfConfigFile(tsconfigPath, {}, parseConfigHost)?.options;
10550
+ const base = tsconfigPath && ts6.getParsedCommandLineOfConfigFile(tsconfigPath, {}, parseConfigHost)?.options;
10318
10551
  return {
10319
- ...base ?? ts5.getDefaultCompilerOptions(),
10552
+ ...base ?? ts6.getDefaultCompilerOptions(),
10320
10553
  noEmit: true,
10321
10554
  skipDefaultLibCheck: true,
10322
10555
  skipLibCheck: true,
@@ -10324,14 +10557,14 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10324
10557
  };
10325
10558
  }, SCHEMA_VERSION = 1, packageVersion = (cwd, specifier) => {
10326
10559
  const candidates = specifier === "@absolutejs/absolute" ? [
10327
- resolve24(cwd, "node_modules", "@absolutejs", "absolute", "package.json"),
10328
- resolve24(cwd, "package.json")
10560
+ resolve25(cwd, "node_modules", "@absolutejs", "absolute", "package.json"),
10561
+ resolve25(cwd, "package.json")
10329
10562
  ] : [
10330
- resolve24(cwd, "node_modules", ...specifier.split("/"), "package.json")
10563
+ resolve25(cwd, "node_modules", ...specifier.split("/"), "package.json")
10331
10564
  ];
10332
10565
  for (const candidate of candidates) {
10333
10566
  try {
10334
- const { version: version2 } = JSON.parse(readFileSync20(candidate, "utf-8"));
10567
+ const { version: version2 } = JSON.parse(readFileSync21(candidate, "utf-8"));
10335
10568
  if (typeof version2 === "string")
10336
10569
  return version2;
10337
10570
  } catch {}
@@ -10342,16 +10575,16 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10342
10575
  if (local) {
10343
10576
  const file = typeName === "PackageJson" ? "packageJson.ts" : "build.ts";
10344
10577
  try {
10345
- signature += `:${statSync2(resolve24(cwd, "types", file)).mtimeMs}`;
10578
+ signature += `:${statSync2(resolve25(cwd, "types", file)).mtimeMs}`;
10346
10579
  } catch {}
10347
10580
  }
10348
10581
  return signature;
10349
10582
  }, cacheSlug = (specifier) => specifier.replace("@", "").split("/").join("-"), cacheFile = (cwd, typeName, specifier) => {
10350
10583
  const name = specifier === "@absolutejs/absolute" ? typeName : `${typeName}.${cacheSlug(specifier)}`;
10351
- return resolve24(cwd, ".absolutejs", "config-schema", `${name}.json`);
10584
+ return resolve25(cwd, ".absolutejs", "config-schema", `${name}.json`);
10352
10585
  }, readDiskCache = (cwd, typeName, signature, specifier) => {
10353
10586
  try {
10354
- const cached = JSON.parse(readFileSync20(cacheFile(cwd, typeName, specifier), "utf-8"));
10587
+ const cached = JSON.parse(readFileSync21(cacheFile(cwd, typeName, specifier), "utf-8"));
10355
10588
  if (isRecord9(cached) && cached.signature === signature && Array.isArray(cached.fields)) {
10356
10589
  return cached.fields;
10357
10590
  }
@@ -10359,12 +10592,12 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10359
10592
  return null;
10360
10593
  }, writeDiskCache = (cwd, typeName, signature, fields, specifier) => {
10361
10594
  try {
10362
- mkdirSync9(resolve24(cwd, ".absolutejs", "config-schema"), {
10595
+ mkdirSync9(resolve25(cwd, ".absolutejs", "config-schema"), {
10363
10596
  recursive: true
10364
10597
  });
10365
10598
  writeFileSync8(cacheFile(cwd, typeName, specifier), JSON.stringify({ fields, signature }));
10366
10599
  } catch {}
10367
- }, docOf = (symbol, checker) => ts5.displayPartsToString(symbol.getDocumentationComment(checker)).trim(), typeOfSymbol = (symbol, checker) => {
10600
+ }, docOf = (symbol, checker) => ts6.displayPartsToString(symbol.getDocumentationComment(checker)).trim(), typeOfSymbol = (symbol, checker) => {
10368
10601
  const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
10369
10602
  return declaration ? checker.getTypeOfSymbolAtLocation(symbol, declaration) : checker.getDeclaredTypeOfSymbol(symbol);
10370
10603
  }, hasFlag = (type, flag) => (type.flags & flag) !== 0, unionParts = (type) => type.isUnion() ? type.types : [type], literalChoice = (type) => {
@@ -10380,10 +10613,10 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10380
10613
  });
10381
10614
  if (depth > MAX_DEPTH)
10382
10615
  return opaque();
10383
- const parts = unionParts(type).filter((part) => !hasFlag(part, ts5.TypeFlags.Undefined) && !hasFlag(part, ts5.TypeFlags.Null));
10616
+ const parts = unionParts(type).filter((part) => !hasFlag(part, ts6.TypeFlags.Undefined) && !hasFlag(part, ts6.TypeFlags.Null));
10384
10617
  if (parts.length === 0)
10385
10618
  return opaque();
10386
- if (parts.every((part) => hasFlag(part, ts5.TypeFlags.BooleanLike))) {
10619
+ if (parts.every((part) => hasFlag(part, ts6.TypeFlags.BooleanLike))) {
10387
10620
  return { kind: "boolean" };
10388
10621
  }
10389
10622
  const choices = parts.map(literalChoice);
@@ -10403,13 +10636,13 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10403
10636
  kind: "opaque",
10404
10637
  typeText: checker.typeToString(type)
10405
10638
  });
10406
- if (hasFlag(type, ts5.TypeFlags.BooleanLike))
10639
+ if (hasFlag(type, ts6.TypeFlags.BooleanLike))
10407
10640
  return { kind: "boolean" };
10408
- if (hasFlag(type, ts5.TypeFlags.NumberLike))
10641
+ if (hasFlag(type, ts6.TypeFlags.NumberLike))
10409
10642
  return { kind: "number" };
10410
- if (hasFlag(type, ts5.TypeFlags.StringLike))
10643
+ if (hasFlag(type, ts6.TypeFlags.StringLike))
10411
10644
  return { kind: "string" };
10412
- if (!hasFlag(type, ts5.TypeFlags.Object))
10645
+ if (!hasFlag(type, ts6.TypeFlags.Object))
10413
10646
  return opaque();
10414
10647
  if (type.getCallSignatures().length > 0)
10415
10648
  return opaque();
@@ -10430,7 +10663,7 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10430
10663
  const fields = props.map((symbol) => ({
10431
10664
  description: docOf(symbol, checker),
10432
10665
  name: symbol.getName(),
10433
- optional: (symbol.flags & ts5.SymbolFlags.Optional) !== 0,
10666
+ optional: (symbol.flags & ts6.SymbolFlags.Optional) !== 0,
10434
10667
  schema: toSchema(typeOfSymbol(symbol, checker), checker, depth + 1, seen)
10435
10668
  }));
10436
10669
  return { fields, kind: "object" };
@@ -10446,26 +10679,26 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
10446
10679
  }
10447
10680
  return opaque();
10448
10681
  }, introspectFrom = (cwd, specifier, typeName, options, exclude) => {
10449
- const virtualPath = resolve24(cwd, VIRTUAL_NAME);
10682
+ const virtualPath = resolve25(cwd, VIRTUAL_NAME);
10450
10683
  const source = `import type { ${typeName} } from '${specifier}';
10451
10684
  declare const value: ${typeName};
10452
10685
  export { value };
10453
10686
  `;
10454
- const host2 = ts5.createCompilerHost(options, true);
10687
+ const host2 = ts6.createCompilerHost(options, true);
10455
10688
  const getSourceFile = host2.getSourceFile.bind(host2);
10456
- host2.getSourceFile = (fileName, languageVersion, onError, shouldCreate) => fileName === virtualPath ? ts5.createSourceFile(fileName, source, languageVersion, true) : getSourceFile(fileName, languageVersion, onError, shouldCreate);
10689
+ host2.getSourceFile = (fileName, languageVersion, onError, shouldCreate) => fileName === virtualPath ? ts6.createSourceFile(fileName, source, languageVersion, true) : getSourceFile(fileName, languageVersion, onError, shouldCreate);
10457
10690
  const fileExists = host2.fileExists.bind(host2);
10458
10691
  host2.fileExists = (fileName) => fileName === virtualPath ? true : fileExists(fileName);
10459
10692
  const readFile11 = host2.readFile.bind(host2);
10460
10693
  host2.readFile = (fileName) => fileName === virtualPath ? source : readFile11(fileName);
10461
- const program = ts5.createProgram([virtualPath], options, host2);
10694
+ const program = ts6.createProgram([virtualPath], options, host2);
10462
10695
  const checker = program.getTypeChecker();
10463
10696
  const sourceFile = program.getSourceFile(virtualPath);
10464
10697
  if (!sourceFile)
10465
10698
  return [];
10466
10699
  const nodes = [];
10467
10700
  sourceFile.forEachChild((node) => {
10468
- if (!ts5.isVariableStatement(node))
10701
+ if (!ts6.isVariableStatement(node))
10469
10702
  return;
10470
10703
  const [declaration] = node.declarationList.declarations;
10471
10704
  if (!declaration)
@@ -10478,7 +10711,7 @@ export { value };
10478
10711
  nodes.push({
10479
10712
  description: docOf(symbol, checker),
10480
10713
  name,
10481
- optional: (symbol.flags & ts5.SymbolFlags.Optional) !== 0,
10714
+ optional: (symbol.flags & ts6.SymbolFlags.Optional) !== 0,
10482
10715
  schema: toSchema(typeOfSymbol(symbol, checker), checker, 1, new Set)
10483
10716
  });
10484
10717
  }
@@ -10489,7 +10722,7 @@ export { value };
10489
10722
  const cached = cache.get(cacheKey);
10490
10723
  if (cached)
10491
10724
  return cached;
10492
- const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) && existsSync18(resolve24(cwd, "types/index.ts"));
10725
+ const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) && existsSync18(resolve25(cwd, "types/index.ts"));
10493
10726
  const signature = cacheSignature(cwd, typeName, local, specifier);
10494
10727
  const fromDisk = readDiskCache(cwd, typeName, signature, specifier);
10495
10728
  if (fromDisk) {
@@ -10516,59 +10749,59 @@ var init_fromType = __esm(() => {
10516
10749
  });
10517
10750
 
10518
10751
  // src/cli/config/absolute/resolveAbsoluteConfig.ts
10519
- import ts6 from "typescript";
10520
- import { existsSync as existsSync19, readFileSync as readFileSync21 } from "fs";
10521
- import { resolve as resolve25 } from "path";
10752
+ import ts7 from "typescript";
10753
+ import { existsSync as existsSync19, readFileSync as readFileSync22 } from "fs";
10754
+ import { resolve as resolve26 } from "path";
10522
10755
  var CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath = (cwd, override) => {
10523
10756
  if (override) {
10524
- const resolved = resolve25(cwd, override);
10757
+ const resolved = resolve26(cwd, override);
10525
10758
  return existsSync19(resolved) ? resolved : null;
10526
10759
  }
10527
10760
  for (const name of CONFIG_CANDIDATES2) {
10528
- const candidate = resolve25(cwd, name);
10761
+ const candidate = resolve26(cwd, name);
10529
10762
  if (existsSync19(candidate))
10530
10763
  return candidate;
10531
10764
  }
10532
10765
  return null;
10533
- }, parseSource = (configPath2, text) => ts6.createSourceFile(configPath2, text, ts6.ScriptTarget.Latest, true), findConfigObject = (sourceFile) => {
10766
+ }, parseSource = (configPath2, text2) => ts7.createSourceFile(configPath2, text2, ts7.ScriptTarget.Latest, true), findConfigObject = (sourceFile) => {
10534
10767
  const pending = [sourceFile];
10535
10768
  while (pending.length > 0) {
10536
10769
  const node = pending.pop();
10537
10770
  if (!node)
10538
10771
  continue;
10539
- const [firstArgument] = ts6.isCallExpression(node) ? node.arguments : [];
10540
- if (ts6.isCallExpression(node) && ts6.isIdentifier(node.expression) && node.expression.text === "defineConfig" && firstArgument && ts6.isObjectLiteralExpression(firstArgument)) {
10772
+ const [firstArgument] = ts7.isCallExpression(node) ? node.arguments : [];
10773
+ if (ts7.isCallExpression(node) && ts7.isIdentifier(node.expression) && node.expression.text === "defineConfig" && firstArgument && ts7.isObjectLiteralExpression(firstArgument)) {
10541
10774
  return firstArgument;
10542
10775
  }
10543
- if (ts6.isExportAssignment(node) && ts6.isObjectLiteralExpression(node.expression)) {
10776
+ if (ts7.isExportAssignment(node) && ts7.isObjectLiteralExpression(node.expression)) {
10544
10777
  return node.expression;
10545
10778
  }
10546
10779
  node.forEachChild((child) => pending.push(child));
10547
10780
  }
10548
10781
  return null;
10549
10782
  }, parseConfigObject = (configPath2) => {
10550
- const text = readFileSync21(configPath2, "utf-8");
10551
- return { object: findConfigObject(parseSource(configPath2, text)), text };
10783
+ const text2 = readFileSync22(configPath2, "utf-8");
10784
+ return { object: findConfigObject(parseSource(configPath2, text2)), text: text2 };
10552
10785
  }, evalLiteral = (node) => {
10553
- if (ts6.isStringLiteralLike(node)) {
10786
+ if (ts7.isStringLiteralLike(node)) {
10554
10787
  return { opaque: false, value: node.text };
10555
10788
  }
10556
- if (node.kind === ts6.SyntaxKind.TrueKeyword) {
10789
+ if (node.kind === ts7.SyntaxKind.TrueKeyword) {
10557
10790
  return { opaque: false, value: true };
10558
10791
  }
10559
- if (node.kind === ts6.SyntaxKind.FalseKeyword) {
10792
+ if (node.kind === ts7.SyntaxKind.FalseKeyword) {
10560
10793
  return { opaque: false, value: false };
10561
10794
  }
10562
- if (node.kind === ts6.SyntaxKind.NullKeyword) {
10795
+ if (node.kind === ts7.SyntaxKind.NullKeyword) {
10563
10796
  return { opaque: false, value: null };
10564
10797
  }
10565
- if (ts6.isNumericLiteral(node)) {
10798
+ if (ts7.isNumericLiteral(node)) {
10566
10799
  return { opaque: false, value: Number(node.text) };
10567
10800
  }
10568
- if (ts6.isPrefixUnaryExpression(node) && node.operator === ts6.SyntaxKind.MinusToken && ts6.isNumericLiteral(node.operand)) {
10801
+ if (ts7.isPrefixUnaryExpression(node) && node.operator === ts7.SyntaxKind.MinusToken && ts7.isNumericLiteral(node.operand)) {
10569
10802
  return { opaque: false, value: -Number(node.operand.text) };
10570
10803
  }
10571
- if (ts6.isArrayLiteralExpression(node)) {
10804
+ if (ts7.isArrayLiteralExpression(node)) {
10572
10805
  const items = [];
10573
10806
  for (const element of node.elements) {
10574
10807
  const result = evalLiteral(element);
@@ -10578,28 +10811,28 @@ var CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath = (cwd, override) => {
10578
10811
  }
10579
10812
  return { opaque: false, value: items };
10580
10813
  }
10581
- if (ts6.isObjectLiteralExpression(node)) {
10582
- const object2 = {};
10814
+ if (ts7.isObjectLiteralExpression(node)) {
10815
+ const object3 = {};
10583
10816
  for (const property of node.properties) {
10584
- if (!ts6.isPropertyAssignment(property) || !(ts6.isIdentifier(property.name) || ts6.isStringLiteral(property.name))) {
10817
+ if (!ts7.isPropertyAssignment(property) || !(ts7.isIdentifier(property.name) || ts7.isStringLiteral(property.name))) {
10585
10818
  return { opaque: true, value: undefined };
10586
10819
  }
10587
10820
  const result = evalLiteral(property.initializer);
10588
10821
  if (result.opaque)
10589
10822
  return { opaque: true, value: undefined };
10590
- object2[property.name.text] = result.value;
10823
+ object3[property.name.text] = result.value;
10591
10824
  }
10592
- return { opaque: false, value: object2 };
10825
+ return { opaque: false, value: object3 };
10593
10826
  }
10594
10827
  return { opaque: true, value: undefined };
10595
10828
  }, readCurrent = (configPath2) => {
10596
10829
  const current = {};
10597
10830
  const opaqueKeys = [];
10598
- const { object: object2 } = parseConfigObject(configPath2);
10599
- if (!object2)
10831
+ const { object: object3 } = parseConfigObject(configPath2);
10832
+ if (!object3)
10600
10833
  return { current, opaqueKeys };
10601
- for (const property of object2.properties) {
10602
- if (!ts6.isPropertyAssignment(property) || !(ts6.isIdentifier(property.name) || ts6.isStringLiteral(property.name))) {
10834
+ for (const property of object3.properties) {
10835
+ if (!ts7.isPropertyAssignment(property) || !(ts7.isIdentifier(property.name) || ts7.isStringLiteral(property.name))) {
10603
10836
  continue;
10604
10837
  }
10605
10838
  const name = property.name.text;
@@ -10758,8 +10991,8 @@ var init_frameworks = __esm(() => {
10758
10991
  });
10759
10992
 
10760
10993
  // src/cli/generate/context.ts
10761
- import { dirname as dirname16, isAbsolute as isAbsolute5, join as join26, relative as relative14, resolve as resolve26 } from "path";
10762
- var asString = (value) => typeof value === "string" ? value : undefined, isRecord10 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute5(value) ? value : resolve26(cwd, value), resolveStylesDir = (cwd, config) => {
10994
+ import { dirname as dirname16, isAbsolute as isAbsolute5, join as join27, relative as relative15, resolve as resolve27 } from "path";
10995
+ var asString = (value) => typeof value === "string" ? value : undefined, isRecord10 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute5(value) ? value : resolve27(cwd, value), resolveStylesDir = (cwd, config) => {
10763
10996
  const styles = config.stylesConfig;
10764
10997
  if (typeof styles === "string")
10765
10998
  return resolveDir(cwd, styles);
@@ -10768,10 +11001,10 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
10768
11001
  if (indexes)
10769
11002
  return resolveDir(cwd, indexes);
10770
11003
  }
10771
- return resolve26(cwd, "src/frontend/styles/indexes");
11004
+ return resolve27(cwd, "src/frontend/styles/indexes");
10772
11005
  }, configuredFrameworks = (project) => FRAMEWORK_KEYS2.filter((key) => project.frameworkDirs[key] !== undefined), frontendRootFor = (project, framework) => {
10773
11006
  const dir = project.frameworkDirs[framework];
10774
- return dir ? dirname16(dir) : resolve26(project.cwd, "src/frontend");
11007
+ return dir ? dirname16(dir) : resolve27(project.cwd, "src/frontend");
10775
11008
  }, resolveProject = async (cwd, configOverride) => {
10776
11009
  const loaded = await loadConfig(configOverride);
10777
11010
  const config = isRecord10(loaded) ? loaded : {};
@@ -10821,8 +11054,8 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
10821
11054
  message: `Multiple frameworks configured (${configured.join(", ")}). Pass --framework <name>.`,
10822
11055
  ok: false
10823
11056
  };
10824
- }, sharedDirFor = (project, framework) => join26(frontendRootFor(project, framework), "shared"), toModuleSpecifier = (fromDir, toFileNoExt) => {
10825
- const rel = relative14(fromDir, toFileNoExt).split("\\").join("/");
11057
+ }, sharedDirFor = (project, framework) => join27(frontendRootFor(project, framework), "shared"), toModuleSpecifier = (fromDir, toFileNoExt) => {
11058
+ const rel = relative15(fromDir, toFileNoExt).split("\\").join("/");
10826
11059
  return rel.startsWith(".") ? rel : `./${rel}`;
10827
11060
  };
10828
11061
  var init_context = __esm(() => {
@@ -10849,78 +11082,78 @@ var emptyOutcome = () => ({
10849
11082
  });
10850
11083
 
10851
11084
  // src/cli/generate/routeWiring.ts
10852
- import ts7 from "typescript";
10853
- import { existsSync as existsSync20, readFileSync as readFileSync22, readdirSync as readdirSync4, writeFileSync as writeFileSync9 } from "fs";
10854
- import { dirname as dirname17, join as join27 } from "path";
11085
+ import ts8 from "typescript";
11086
+ import { existsSync as existsSync20, readFileSync as readFileSync23, readdirSync as readdirSync4, writeFileSync as writeFileSync9 } from "fs";
11087
+ import { dirname as dirname17, join as join28 } from "path";
10855
11088
  var DEFAULT_SEPARATOR = `
10856
- `, BOUNDARY_USE, applyEdits = (text, edits) => {
11089
+ `, BOUNDARY_USE, applyEdits = (text2, edits) => {
10857
11090
  const ordered = [...edits].sort((first, second) => second.start - first.start);
10858
- let output = text;
11091
+ let output = text2;
10859
11092
  for (const edit of ordered) {
10860
11093
  output = output.slice(0, edit.start) + edit.text + output.slice(edit.end);
10861
11094
  }
10862
11095
  return output;
10863
- }, stripExtension = (path) => path.replace(/\.[^./\\]+$/, ""), parse2 = (path, text) => ts7.createSourceFile(path, text, ts7.ScriptTarget.Latest, true), findElysiaNew = (sourceFile) => {
11096
+ }, stripExtension = (path) => path.replace(/\.[^./\\]+$/, ""), parse2 = (path, text2) => ts8.createSourceFile(path, text2, ts8.ScriptTarget.Latest, true), findElysiaNew = (sourceFile) => {
10864
11097
  let found = null;
10865
11098
  const visit = (node) => {
10866
11099
  if (found)
10867
11100
  return;
10868
- if (ts7.isNewExpression(node) && ts7.isIdentifier(node.expression) && node.expression.text === "Elysia") {
11101
+ if (ts8.isNewExpression(node) && ts8.isIdentifier(node.expression) && node.expression.text === "Elysia") {
10869
11102
  found = node;
10870
11103
  return;
10871
11104
  }
10872
- ts7.forEachChild(node, visit);
11105
+ ts8.forEachChild(node, visit);
10873
11106
  };
10874
11107
  visit(sourceFile);
10875
11108
  return found;
10876
11109
  }, climbChain = (start2) => {
10877
11110
  let top = start2;
10878
- while (ts7.isPropertyAccessExpression(top.parent) && top.parent.expression === top && ts7.isCallExpression(top.parent.parent) && top.parent.parent.expression === top.parent) {
11111
+ while (ts8.isPropertyAccessExpression(top.parent) && top.parent.expression === top && ts8.isCallExpression(top.parent.parent) && top.parent.parent.expression === top.parent) {
10879
11112
  top = top.parent.parent;
10880
11113
  }
10881
11114
  return top;
10882
11115
  }, collectCalls = (top) => {
10883
11116
  const calls = [];
10884
11117
  let node = top;
10885
- while (ts7.isCallExpression(node) && ts7.isPropertyAccessExpression(node.expression)) {
11118
+ while (ts8.isCallExpression(node) && ts8.isPropertyAccessExpression(node.expression)) {
10886
11119
  calls.push(node);
10887
11120
  node = node.expression.expression;
10888
11121
  }
10889
11122
  return calls.reverse();
10890
- }, methodName = (call) => ts7.isPropertyAccessExpression(call.expression) ? call.expression.name.text : null, isBoundary = (call) => {
11123
+ }, methodName = (call) => ts8.isPropertyAccessExpression(call.expression) ? call.expression.name.text : null, isBoundary = (call) => {
10891
11124
  const name = methodName(call);
10892
11125
  const [arg] = call.arguments;
10893
- if (name === "use" && arg && ts7.isIdentifier(arg)) {
11126
+ if (name === "use" && arg && ts8.isIdentifier(arg)) {
10894
11127
  return BOUNDARY_USE.has(arg.text);
10895
11128
  }
10896
- return name === "on" && arg !== undefined && ts7.isStringLiteralLike(arg);
10897
- }, receiverEnd = (call) => ts7.isPropertyAccessExpression(call.expression) ? call.expression.expression.getEnd() : call.getEnd(), separatorBefore = (text, offset) => {
10898
- const match = text.slice(offset).match(/^(\s*\n[ \t]*)\./);
11129
+ return name === "on" && arg !== undefined && ts8.isStringLiteralLike(arg);
11130
+ }, receiverEnd = (call) => ts8.isPropertyAccessExpression(call.expression) ? call.expression.expression.getEnd() : call.getEnd(), separatorBefore = (text2, offset) => {
11131
+ const match = text2.slice(offset).match(/^(\s*\n[ \t]*)\./);
10899
11132
  return match ? match[1] : DEFAULT_SEPARATOR;
10900
- }, findRouteInsertion = (text, top) => {
11133
+ }, findRouteInsertion = (text2, top) => {
10901
11134
  const calls = collectCalls(top);
10902
11135
  const boundary = calls.find(isBoundary);
10903
11136
  if (boundary) {
10904
11137
  const offset2 = receiverEnd(boundary);
10905
- return { offset: offset2, separator: separatorBefore(text, offset2) };
11138
+ return { offset: offset2, separator: separatorBefore(text2, offset2) };
10906
11139
  }
10907
11140
  const last = calls[calls.length - 1];
10908
11141
  const offset = last ? last.getEnd() : top.getEnd();
10909
11142
  const sepProbe = last ? receiverEnd(last) : top.getEnd();
10910
- return { offset, separator: separatorBefore(text, sepProbe) };
10911
- }, namedImportDecl = (sourceFile, module) => sourceFile.statements.find((statement) => ts7.isImportDeclaration(statement) && ts7.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.importClause !== undefined && !statement.importClause.isTypeOnly && statement.importClause.namedBindings !== undefined && ts7.isNamedImports(statement.importClause.namedBindings)), importedNames = (decl) => {
11143
+ return { offset, separator: separatorBefore(text2, sepProbe) };
11144
+ }, namedImportDecl = (sourceFile, module) => sourceFile.statements.find((statement) => ts8.isImportDeclaration(statement) && ts8.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.importClause !== undefined && !statement.importClause.isTypeOnly && statement.importClause.namedBindings !== undefined && ts8.isNamedImports(statement.importClause.namedBindings)), importedNames = (decl) => {
10912
11145
  const bindings = decl.importClause?.namedBindings;
10913
- if (!bindings || !ts7.isNamedImports(bindings))
11146
+ if (!bindings || !ts8.isNamedImports(bindings))
10914
11147
  return new Set;
10915
11148
  return new Set(bindings.elements.map((element) => (element.propertyName ?? element.name).text));
10916
11149
  }, lastImportEnd = (sourceFile) => {
10917
11150
  let end = 0;
10918
11151
  for (const statement of sourceFile.statements) {
10919
- if (ts7.isImportDeclaration(statement))
11152
+ if (ts8.isImportDeclaration(statement))
10920
11153
  end = statement.getEnd();
10921
11154
  }
10922
11155
  return end;
10923
- }, hasTypeImport = (sourceFile, module, local) => sourceFile.statements.some((statement) => ts7.isImportDeclaration(statement) && ts7.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.getText().includes(local)), renderTypeImport = (spec) => {
11156
+ }, hasTypeImport = (sourceFile, module, local) => sourceFile.statements.some((statement) => ts8.isImportDeclaration(statement) && ts8.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === module && statement.getText().includes(local)), renderTypeImport = (spec) => {
10924
11157
  if (spec.kind === "typeDefault") {
10925
11158
  return `import type ${spec.local} from '${spec.module}';`;
10926
11159
  }
@@ -10940,7 +11173,7 @@ var DEFAULT_SEPARATOR = `
10940
11173
  return byModule;
10941
11174
  }, mergeNamedEdit = (decl, sourceFile, missing) => {
10942
11175
  const bindings = decl.importClause?.namedBindings;
10943
- if (!bindings || !ts7.isNamedImports(bindings))
11176
+ if (!bindings || !ts8.isNamedImports(bindings))
10944
11177
  return null;
10945
11178
  const { elements } = bindings;
10946
11179
  const additions = missing.join(", ");
@@ -11001,7 +11234,7 @@ ${newLines.join(`
11001
11234
  }, hasChain = (path) => {
11002
11235
  if (!existsSync20(path))
11003
11236
  return false;
11004
- const sourceFile = parse2(path, readFileSync22(path, "utf-8"));
11237
+ const sourceFile = parse2(path, readFileSync23(path, "utf-8"));
11005
11238
  const found = findElysiaNew(sourceFile);
11006
11239
  return found !== null;
11007
11240
  }, firstChainFile = (pluginsDir) => {
@@ -11010,14 +11243,14 @@ ${newLines.join(`
11010
11243
  for (const name of readdirSync4(pluginsDir)) {
11011
11244
  if (!name.endsWith(".ts"))
11012
11245
  continue;
11013
- const candidate = join27(pluginsDir, name);
11246
+ const candidate = join28(pluginsDir, name);
11014
11247
  if (hasChain(candidate))
11015
11248
  return candidate;
11016
11249
  }
11017
11250
  return null;
11018
11251
  }, findRoutingFile = (serverEntry) => {
11019
- const pluginsDir = join27(dirname17(serverEntry), "plugins");
11020
- const preferred = join27(pluginsDir, "pagesPlugin.ts");
11252
+ const pluginsDir = join28(dirname17(serverEntry), "plugins");
11253
+ const preferred = join28(pluginsDir, "pagesPlugin.ts");
11021
11254
  if (hasChain(preferred))
11022
11255
  return preferred;
11023
11256
  const scanned = firstChainFile(pluginsDir);
@@ -11050,20 +11283,20 @@ ${newLines.join(`
11050
11283
  };
11051
11284
  if (!hasChain(serverEntry))
11052
11285
  return fallback;
11053
- const text = readFileSync22(serverEntry, "utf-8");
11054
- const sourceFile = parse2(serverEntry, text);
11286
+ const text2 = readFileSync23(serverEntry, "utf-8");
11287
+ const sourceFile = parse2(serverEntry, text2);
11055
11288
  const newExpr = findElysiaNew(sourceFile);
11056
11289
  if (!newExpr)
11057
11290
  return fallback;
11058
11291
  const top = climbChain(newExpr);
11059
- const { offset, separator } = findRouteInsertion(text, top);
11292
+ const { offset, separator } = findRouteInsertion(text2, top);
11060
11293
  const edits = buildImportEdits(sourceFile, specs);
11061
11294
  edits.push({
11062
11295
  end: offset,
11063
11296
  start: offset,
11064
11297
  text: `${separator}.use(${pluginName})`
11065
11298
  });
11066
- writeFileSync9(serverEntry, applyEdits(text, edits), "utf-8");
11299
+ writeFileSync9(serverEntry, applyEdits(text2, edits), "utf-8");
11067
11300
  return { kind: "edited", routingFile: serverEntry };
11068
11301
  }, wireRoute = (input) => {
11069
11302
  const routingFile = findRoutingFile(input.serverEntry);
@@ -11079,8 +11312,8 @@ ${newLines.join(`
11079
11312
  ${routeExpr}`
11080
11313
  };
11081
11314
  }
11082
- const text = readFileSync22(routingFile, "utf-8");
11083
- const sourceFile = parse2(routingFile, text);
11315
+ const text2 = readFileSync23(routingFile, "utf-8");
11316
+ const sourceFile = parse2(routingFile, text2);
11084
11317
  const newExpr = findElysiaNew(sourceFile);
11085
11318
  if (!newExpr) {
11086
11319
  return {
@@ -11092,14 +11325,14 @@ ${routeExpr}`
11092
11325
  };
11093
11326
  }
11094
11327
  const top = climbChain(newExpr);
11095
- const { offset, separator } = findRouteInsertion(text, top);
11328
+ const { offset, separator } = findRouteInsertion(text2, top);
11096
11329
  const edits = buildImportEdits(sourceFile, specs);
11097
11330
  edits.push({
11098
11331
  end: offset,
11099
11332
  start: offset,
11100
11333
  text: `${separator}${routeExpr}`
11101
11334
  });
11102
- writeFileSync9(routingFile, applyEdits(text, edits), "utf-8");
11335
+ writeFileSync9(routingFile, applyEdits(text2, edits), "utf-8");
11103
11336
  return { kind: "edited", routingFile };
11104
11337
  };
11105
11338
  var init_routeWiring = __esm(() => {
@@ -11109,7 +11342,7 @@ var init_routeWiring = __esm(() => {
11109
11342
 
11110
11343
  // src/cli/generate/generateApi.ts
11111
11344
  import { existsSync as existsSync21, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
11112
- import { dirname as dirname18, join as join28 } from "path";
11345
+ import { dirname as dirname18, join as join29 } from "path";
11113
11346
  var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
11114
11347
 
11115
11348
  export const ${pluginName} = new Elysia()
@@ -11121,8 +11354,8 @@ export const ${pluginName} = new Elysia()
11121
11354
  const pluginName = `${camel}Plugin`;
11122
11355
  const base = `/api/${kebab}`;
11123
11356
  const outcome = { ...emptyOutcome(), route: base };
11124
- const pluginsDir = join28(dirname18(project.serverEntry), "plugins");
11125
- const fileAbs = join28(pluginsDir, `${pluginName}.ts`);
11357
+ const pluginsDir = join29(dirname18(project.serverEntry), "plugins");
11358
+ const fileAbs = join29(pluginsDir, `${pluginName}.ts`);
11126
11359
  if (existsSync21(fileAbs)) {
11127
11360
  outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
11128
11361
  return outcome;
@@ -11197,7 +11430,7 @@ var init_componentTemplates = __esm(() => {
11197
11430
 
11198
11431
  // src/cli/generate/generateComponent.ts
11199
11432
  import { existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
11200
- import { dirname as dirname19, join as join29 } from "path";
11433
+ import { dirname as dirname19, join as join30 } from "path";
11201
11434
  var generateComponent = (project, framework, rawName) => {
11202
11435
  const def = frameworks6[framework];
11203
11436
  const pascal = toPascalCase(rawName);
@@ -11208,7 +11441,7 @@ var generateComponent = (project, framework, rawName) => {
11208
11441
  outcome.manual = { reason: "framework directory missing", snippet: "" };
11209
11442
  return outcome;
11210
11443
  }
11211
- const fileAbs = join29(frameworkDir, "components", def.componentFile({ kebab, pascal }));
11444
+ const fileAbs = join30(frameworkDir, "components", def.componentFile({ kebab, pascal }));
11212
11445
  if (existsSync22(fileAbs)) {
11213
11446
  outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
11214
11447
  return outcome;
@@ -11228,36 +11461,36 @@ var init_generateComponent = __esm(() => {
11228
11461
  });
11229
11462
 
11230
11463
  // src/cli/generate/cssStrategy.ts
11231
- import ts8 from "typescript";
11464
+ import ts9 from "typescript";
11232
11465
  import { existsSync as existsSync23 } from "fs";
11233
- import { join as join30 } from "path";
11466
+ import { join as join31 } from "path";
11234
11467
  var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
11235
11468
  margin: 0 auto;
11236
11469
  max-width: 64rem;
11237
11470
  padding: 2rem;
11238
11471
  }
11239
11472
  `, cssAssetArg = (node) => {
11240
- if (!ts8.isCallExpression(node) || !ts8.isIdentifier(node.expression) || node.expression.text !== "asset") {
11473
+ if (!ts9.isCallExpression(node) || !ts9.isIdentifier(node.expression) || node.expression.text !== "asset") {
11241
11474
  return null;
11242
11475
  }
11243
11476
  const [, arg] = node.arguments;
11244
- if (arg && ts8.isStringLiteralLike(arg) && arg.text.endsWith(CSS_SUFFIX)) {
11477
+ if (arg && ts9.isStringLiteralLike(arg) && arg.text.endsWith(CSS_SUFFIX)) {
11245
11478
  return arg.text;
11246
11479
  }
11247
11480
  return null;
11248
11481
  }, detectSharedKey = (routingText) => {
11249
- const sourceFile = ts8.createSourceFile("routing.ts", routingText, ts8.ScriptTarget.Latest, true);
11482
+ const sourceFile = ts9.createSourceFile("routing.ts", routingText, ts9.ScriptTarget.Latest, true);
11250
11483
  let hoisted = null;
11251
11484
  const inlineCounts = new Map;
11252
11485
  const visit = (node) => {
11253
11486
  const key = cssAssetArg(node);
11254
11487
  if (key) {
11255
- if (ts8.isVariableDeclaration(node.parent))
11488
+ if (ts9.isVariableDeclaration(node.parent))
11256
11489
  hoisted ??= key;
11257
11490
  else
11258
11491
  inlineCounts.set(key, (inlineCounts.get(key) ?? 0) + 1);
11259
11492
  }
11260
- ts8.forEachChild(node, visit);
11493
+ ts9.forEachChild(node, visit);
11261
11494
  };
11262
11495
  visit(sourceFile);
11263
11496
  if (hoisted)
@@ -11269,7 +11502,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
11269
11502
  return null;
11270
11503
  }, fileForKey = (stylesDir, assetKey2) => {
11271
11504
  const base = assetKey2.endsWith(CSS_SUFFIX) ? assetKey2.slice(0, -CSS_SUFFIX.length) : assetKey2;
11272
- return join30(stylesDir, `${toKebabCase(base)}.css`);
11505
+ return join31(stylesDir, `${toKebabCase(base)}.css`);
11273
11506
  }, planCss = (routingText, stylesDir, pascal, kebab) => {
11274
11507
  const sharedKey = detectSharedKey(routingText);
11275
11508
  if (sharedKey) {
@@ -11282,7 +11515,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
11282
11515
  shared: true
11283
11516
  };
11284
11517
  }
11285
- const cssFileAbs = join30(stylesDir, `${kebab}.css`);
11518
+ const cssFileAbs = join31(stylesDir, `${kebab}.css`);
11286
11519
  return {
11287
11520
  assetKey: `${pascal}${CSS_SUFFIX}`,
11288
11521
  contents: DEFAULT_CSS,
@@ -11294,8 +11527,8 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
11294
11527
  var init_cssStrategy = () => {};
11295
11528
 
11296
11529
  // src/cli/generate/navData.ts
11297
- import ts9 from "typescript";
11298
- import { existsSync as existsSync24, mkdirSync as mkdirSync12, readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "fs";
11530
+ import ts10 from "typescript";
11531
+ import { existsSync as existsSync24, mkdirSync as mkdirSync12, readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "fs";
11299
11532
  import { dirname as dirname20 } from "path";
11300
11533
  var NAV_DATA_TEMPLATE = `type NavItem = {
11301
11534
  href: string;
@@ -11308,24 +11541,24 @@ export const navData: NavItem[] = [];
11308
11541
  const visit = (node) => {
11309
11542
  if (found)
11310
11543
  return;
11311
- if (ts9.isVariableDeclaration(node) && ts9.isIdentifier(node.name) && node.name.text === "navData" && node.initializer && ts9.isArrayLiteralExpression(node.initializer)) {
11544
+ if (ts10.isVariableDeclaration(node) && ts10.isIdentifier(node.name) && node.name.text === "navData" && node.initializer && ts10.isArrayLiteralExpression(node.initializer)) {
11312
11545
  found = node.initializer;
11313
11546
  return;
11314
11547
  }
11315
- ts9.forEachChild(node, visit);
11548
+ ts10.forEachChild(node, visit);
11316
11549
  };
11317
11550
  visit(sourceFile);
11318
11551
  return found;
11319
- }, readStringProperty = (object2, name) => {
11320
- const property = object2.properties.find((candidate) => ts9.isPropertyAssignment(candidate) && ts9.isIdentifier(candidate.name) && candidate.name.text === name);
11321
- if (!property || !ts9.isStringLiteralLike(property.initializer)) {
11552
+ }, readStringProperty = (object3, name) => {
11553
+ const property = object3.properties.find((candidate) => ts10.isPropertyAssignment(candidate) && ts10.isIdentifier(candidate.name) && candidate.name.text === name);
11554
+ if (!property || !ts10.isStringLiteralLike(property.initializer)) {
11322
11555
  return null;
11323
11556
  }
11324
11557
  return property.initializer.text;
11325
11558
  }, parseNavItems = (array) => {
11326
11559
  const items = [];
11327
11560
  for (const element of array.elements) {
11328
- if (!ts9.isObjectLiteralExpression(element))
11561
+ if (!ts10.isObjectLiteralExpression(element))
11329
11562
  continue;
11330
11563
  const href = readStringProperty(element, "href");
11331
11564
  const label = readStringProperty(element, "label");
@@ -11336,40 +11569,40 @@ export const navData: NavItem[] = [];
11336
11569
  }, readNavItems = (navDataPath) => {
11337
11570
  if (!existsSync24(navDataPath))
11338
11571
  return [];
11339
- const text = readFileSync23(navDataPath, "utf-8");
11340
- const sourceFile = ts9.createSourceFile(navDataPath, text, ts9.ScriptTarget.Latest, true);
11572
+ const text2 = readFileSync24(navDataPath, "utf-8");
11573
+ const sourceFile = ts10.createSourceFile(navDataPath, text2, ts10.ScriptTarget.Latest, true);
11341
11574
  const array = findNavArray(sourceFile);
11342
11575
  return array ? parseNavItems(array) : [];
11343
- }, indentOf = (text, position) => {
11576
+ }, indentOf = (text2, position) => {
11344
11577
  let index = position;
11345
- while (index > 0 && text[index - 1] !== `
11578
+ while (index > 0 && text2[index - 1] !== `
11346
11579
  `)
11347
11580
  index -= 1;
11348
11581
  let end = index;
11349
- while (text[end] === " " || text[end] === "\t")
11582
+ while (text2[end] === " " || text2[end] === "\t")
11350
11583
  end += 1;
11351
- return text.slice(index, end);
11352
- }, insertElement = (text, array, sourceFile, entry) => {
11584
+ return text2.slice(index, end);
11585
+ }, insertElement = (text2, array, sourceFile, entry) => {
11353
11586
  const { elements } = array;
11354
11587
  if (elements.length === 0) {
11355
11588
  const insertAt2 = array.getStart(sourceFile) + 1;
11356
- const indent2 = `${indentOf(text, array.getStart(sourceFile))} `;
11589
+ const indent2 = `${indentOf(text2, array.getStart(sourceFile))} `;
11357
11590
  const insertion2 = `
11358
11591
  ${indent2}${entry}
11359
- ${indentOf(text, array.getStart(sourceFile))}`;
11360
- return text.slice(0, insertAt2) + insertion2 + text.slice(insertAt2);
11592
+ ${indentOf(text2, array.getStart(sourceFile))}`;
11593
+ return text2.slice(0, insertAt2) + insertion2 + text2.slice(insertAt2);
11361
11594
  }
11362
11595
  const last = elements[elements.length - 1];
11363
11596
  if (!last)
11364
- return text;
11365
- const indent = indentOf(text, last.getStart(sourceFile));
11597
+ return text2;
11598
+ const indent = indentOf(text2, last.getStart(sourceFile));
11366
11599
  let insertAt = last.getEnd();
11367
- const hasComma = text[insertAt] === ",";
11600
+ const hasComma = text2[insertAt] === ",";
11368
11601
  if (hasComma)
11369
11602
  insertAt += 1;
11370
11603
  const insertion = `${hasComma ? "" : ","}
11371
11604
  ${indent}${entry}`;
11372
- return text.slice(0, insertAt) + insertion + text.slice(insertAt);
11605
+ return text2.slice(0, insertAt) + insertion + text2.slice(insertAt);
11373
11606
  }, upsertNavItem = (navDataPath, item) => {
11374
11607
  const created = !existsSync24(navDataPath);
11375
11608
  if (created) {
@@ -11380,24 +11613,24 @@ ${indent}${entry}`;
11380
11613
  if (existing.some((candidate) => candidate.href === item.href)) {
11381
11614
  return { changed: created, created, items: existing };
11382
11615
  }
11383
- const text = readFileSync23(navDataPath, "utf-8");
11384
- const sourceFile = ts9.createSourceFile(navDataPath, text, ts9.ScriptTarget.Latest, true);
11616
+ const text2 = readFileSync24(navDataPath, "utf-8");
11617
+ const sourceFile = ts10.createSourceFile(navDataPath, text2, ts10.ScriptTarget.Latest, true);
11385
11618
  const array = findNavArray(sourceFile);
11386
11619
  if (!array)
11387
11620
  return { changed: created, created, items: existing };
11388
11621
  const entry = `{ href: '${item.href}', label: '${item.label}' }`;
11389
- writeFileSync12(navDataPath, insertElement(text, array, sourceFile, entry), "utf-8");
11622
+ writeFileSync12(navDataPath, insertElement(text2, array, sourceFile, entry), "utf-8");
11390
11623
  return { changed: true, created, items: [...existing, item] };
11391
11624
  };
11392
11625
  var init_navData = () => {};
11393
11626
 
11394
11627
  // src/cli/generate/staticNav.ts
11395
- var NAV_MARKER_END = "<!-- /absolute:nav -->", NAV_MARKER_START = "<!-- absolute:nav -->", escapeHtml2 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), indentBefore = (text, position) => {
11628
+ var NAV_MARKER_END = "<!-- /absolute:nav -->", NAV_MARKER_START = "<!-- absolute:nav -->", escapeHtml2 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), indentBefore = (text2, position) => {
11396
11629
  let index = position;
11397
- while (index > 0 && text[index - 1] !== `
11630
+ while (index > 0 && text2[index - 1] !== `
11398
11631
  `)
11399
11632
  index -= 1;
11400
- return text.slice(index, position);
11633
+ return text2.slice(index, position);
11401
11634
  }, renderNavBlock = (items, indent) => {
11402
11635
  const links = items.map((item) => `${indent} <a href="${escapeHtml2(item.href)}">${escapeHtml2(item.label)}</a>`).join(`
11403
11636
  `);
@@ -11539,19 +11772,19 @@ var init_pageTemplates = __esm(() => {
11539
11772
  import {
11540
11773
  existsSync as existsSync25,
11541
11774
  mkdirSync as mkdirSync13,
11542
- readFileSync as readFileSync24,
11775
+ readFileSync as readFileSync25,
11543
11776
  readdirSync as readdirSync5,
11544
11777
  writeFileSync as writeFileSync13
11545
11778
  } from "fs";
11546
- import { dirname as dirname21, join as join31, relative as relative15 } from "path";
11779
+ import { dirname as dirname21, join as join32, relative as relative16 } from "path";
11547
11780
  var writeNew = (path, contents) => {
11548
11781
  mkdirSync13(dirname21(path), { recursive: true });
11549
11782
  writeFileSync13(path, contents, "utf-8");
11550
11783
  }, toHref = (fromDir, toFile) => {
11551
- const rel = relative15(fromDir, toFile).split("\\").join("/");
11784
+ const rel = relative16(fromDir, toFile).split("\\").join("/");
11552
11785
  return rel.startsWith(".") ? rel : `./${rel}`;
11553
- }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join31(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync25(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join31(pagesDir, name))), resyncPage = (file, items) => {
11554
- const html = readFileSync24(file, "utf-8");
11786
+ }, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join32(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync25(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join32(pagesDir, name))), resyncPage = (file, items) => {
11787
+ const html = readFileSync25(file, "utf-8");
11555
11788
  const synced = syncStaticNav(html, items);
11556
11789
  if (synced === null || synced === html)
11557
11790
  return false;
@@ -11578,15 +11811,15 @@ var writeNew = (path, contents) => {
11578
11811
  outcome.manual = { reason: "framework directory missing", snippet: "" };
11579
11812
  return outcome;
11580
11813
  }
11581
- const pageFileAbs = join31(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
11814
+ const pageFileAbs = join32(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
11582
11815
  if (existsSync25(pageFileAbs)) {
11583
11816
  outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
11584
11817
  return outcome;
11585
11818
  }
11586
11819
  const routingFile = findRoutingFile(project.serverEntry);
11587
- const routingText = routingFile ? readFileSync24(routingFile, "utf-8") : "";
11820
+ const routingText = routingFile ? readFileSync25(routingFile, "utf-8") : "";
11588
11821
  const css = planCss(routingText, project.stylesDir, pascal, kebab);
11589
- const navDataPath = join31(sharedDirFor(project, framework), "navData.ts");
11822
+ const navDataPath = join32(sharedDirFor(project, framework), "navData.ts");
11590
11823
  const nav = upsertNavItem(navDataPath, { href: route, label: title });
11591
11824
  const navImportPath = toModuleSpecifier(dirname21(pageFileAbs), navDataPath.replace(/\.ts$/, ""));
11592
11825
  writeNew(pageFileAbs, pageTemplates[framework]({
@@ -11640,8 +11873,8 @@ var exports_generate = {};
11640
11873
  __export(exports_generate, {
11641
11874
  runGenerate: () => runGenerate
11642
11875
  });
11643
- import { relative as relative16 } from "path";
11644
- var SUBCOMMANDS, write = (text) => process.stdout.write(`${text}
11876
+ import { relative as relative17 } from "path";
11877
+ var SUBCOMMANDS, write = (text2) => process.stdout.write(`${text2}
11645
11878
  `), fail = (message) => {
11646
11879
  process.stdout.write(`${colors.red}${message}${colors.reset}
11647
11880
  `);
@@ -11672,7 +11905,7 @@ var SUBCOMMANDS, write = (text) => process.stdout.write(`${text}
11672
11905
  return;
11673
11906
  write(` ${colors.dim}${label}${colors.reset}`);
11674
11907
  for (const path of paths)
11675
- write(` ${relative16(cwd, path)}`);
11908
+ write(` ${relative17(cwd, path)}`);
11676
11909
  }, printSummary = (title, outcome, cwd) => {
11677
11910
  for (const note of outcome.notes) {
11678
11911
  write(`${colors.yellow}!${colors.reset} ${note}`);
@@ -11772,47 +12005,47 @@ ${indent.repeat(level)}}`;
11772
12005
  var init_serialize = () => {};
11773
12006
 
11774
12007
  // src/cli/config/absolute/editAbsoluteConfig.ts
11775
- import ts10 from "typescript";
11776
- import { readFileSync as readFileSync25, writeFileSync as writeFileSync14 } from "fs";
11777
- var lineStartOffset = (text, position) => {
12008
+ import ts11 from "typescript";
12009
+ import { readFileSync as readFileSync26, writeFileSync as writeFileSync14 } from "fs";
12010
+ var lineStartOffset = (text2, position) => {
11778
12011
  let index = position;
11779
- while (index > 0 && text[index - 1] !== `
12012
+ while (index > 0 && text2[index - 1] !== `
11780
12013
  `)
11781
12014
  index -= 1;
11782
12015
  return index;
11783
- }, indentBefore2 = (text, position) => text.slice(lineStartOffset(text, position), position), findProperty = (object2, name) => object2.properties.find((property) => ts10.isPropertyAssignment(property) && (ts10.isIdentifier(property.name) || ts10.isStringLiteral(property.name)) && property.name.text === name), applyAbsoluteConfigEdit = (configPath2, request) => {
12016
+ }, indentBefore2 = (text2, position) => text2.slice(lineStartOffset(text2, position), position), findProperty = (object3, name) => object3.properties.find((property) => ts11.isPropertyAssignment(property) && (ts11.isIdentifier(property.name) || ts11.isStringLiteral(property.name)) && property.name.text === name), applyAbsoluteConfigEdit = (configPath2, request) => {
11784
12017
  try {
11785
- const text = readFileSync25(configPath2, "utf-8");
11786
- const sourceFile = ts10.createSourceFile(configPath2, text, ts10.ScriptTarget.Latest, true);
11787
- const object2 = findConfigObject(sourceFile);
11788
- if (!object2) {
12018
+ const text2 = readFileSync26(configPath2, "utf-8");
12019
+ const sourceFile = ts11.createSourceFile(configPath2, text2, ts11.ScriptTarget.Latest, true);
12020
+ const object3 = findConfigObject(sourceFile);
12021
+ if (!object3) {
11789
12022
  return {
11790
12023
  message: "Could not find defineConfig({ ... }) in the config file.",
11791
12024
  ok: false
11792
12025
  };
11793
12026
  }
11794
- const existing = findProperty(object2, request.name);
12027
+ const existing = findProperty(object3, request.name);
11795
12028
  if (request.remove) {
11796
12029
  if (!existing)
11797
12030
  return { message: `${request.name} is not set`, ok: true };
11798
- const start2 = lineStartOffset(text, existing.getStart(sourceFile));
12031
+ const start2 = lineStartOffset(text2, existing.getStart(sourceFile));
11799
12032
  let end = existing.getEnd();
11800
- if (text[end] === ",")
12033
+ if (text2[end] === ",")
11801
12034
  end += 1;
11802
- if (text[end] === `
12035
+ if (text2[end] === `
11803
12036
  `)
11804
12037
  end += 1;
11805
- writeFileSync14(configPath2, text.slice(0, start2) + text.slice(end), "utf-8");
12038
+ writeFileSync14(configPath2, text2.slice(0, start2) + text2.slice(end), "utf-8");
11806
12039
  return { message: `Removed ${request.name}`, ok: true };
11807
12040
  }
11808
12041
  const valueText = serializeValue(request.value);
11809
12042
  if (existing) {
11810
12043
  const start2 = existing.initializer.getStart(sourceFile);
11811
12044
  const end = existing.initializer.getEnd();
11812
- writeFileSync14(configPath2, text.slice(0, start2) + valueText + text.slice(end), "utf-8");
12045
+ writeFileSync14(configPath2, text2.slice(0, start2) + valueText + text2.slice(end), "utf-8");
11813
12046
  return { message: `Updated ${request.name}`, ok: true };
11814
12047
  }
11815
- const { properties } = object2;
12048
+ const { properties } = object3;
11816
12049
  const entry = `${request.name}: ${valueText}`;
11817
12050
  if (properties.length > 0) {
11818
12051
  const last = properties[properties.length - 1];
@@ -11822,21 +12055,21 @@ var lineStartOffset = (text, position) => {
11822
12055
  ok: false
11823
12056
  };
11824
12057
  }
11825
- const indent = indentBefore2(text, last.getStart(sourceFile));
12058
+ const indent = indentBefore2(text2, last.getStart(sourceFile));
11826
12059
  let insertionIndex = last.getEnd();
11827
- const hasComma = text[insertionIndex] === ",";
12060
+ const hasComma = text2[insertionIndex] === ",";
11828
12061
  if (hasComma)
11829
12062
  insertionIndex += 1;
11830
12063
  const insertion = `${hasComma ? "" : ","}
11831
12064
  ${indent}${entry}`;
11832
- writeFileSync14(configPath2, text.slice(0, insertionIndex) + insertion + text.slice(insertionIndex), "utf-8");
12065
+ writeFileSync14(configPath2, text2.slice(0, insertionIndex) + insertion + text2.slice(insertionIndex), "utf-8");
11833
12066
  } else {
11834
- const insertionIndex = object2.getStart(sourceFile) + 1;
11835
- const indent = `${indentBefore2(text, object2.getStart(sourceFile))} `;
12067
+ const insertionIndex = object3.getStart(sourceFile) + 1;
12068
+ const indent = `${indentBefore2(text2, object3.getStart(sourceFile))} `;
11836
12069
  const insertion = `
11837
12070
  ${indent}${entry}
11838
- ${indentBefore2(text, object2.getStart(sourceFile))}`;
11839
- writeFileSync14(configPath2, text.slice(0, insertionIndex) + insertion + text.slice(insertionIndex), "utf-8");
12071
+ ${indentBefore2(text2, object3.getStart(sourceFile))}`;
12072
+ writeFileSync14(configPath2, text2.slice(0, insertionIndex) + insertion + text2.slice(insertionIndex), "utf-8");
11840
12073
  }
11841
12074
  return { message: `Updated ${request.name}`, ok: true };
11842
12075
  } catch (error) {
@@ -11965,14 +12198,14 @@ var init_catalog = __esm(() => {
11965
12198
  });
11966
12199
 
11967
12200
  // src/cli/integrations/addPlugin.ts
11968
- import { existsSync as existsSync26, readFileSync as readFileSync26 } from "fs";
11969
- import { join as join32 } from "path";
12201
+ import { existsSync as existsSync26, readFileSync as readFileSync27 } from "fs";
12202
+ import { join as join33 } from "path";
11970
12203
  var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
11971
- const path = join32(cwd, "package.json");
12204
+ const path = join33(cwd, "package.json");
11972
12205
  if (!existsSync26(path))
11973
12206
  return null;
11974
12207
  try {
11975
- const parsed = JSON.parse(readFileSync26(path, "utf-8"));
12208
+ const parsed = JSON.parse(readFileSync27(path, "utf-8"));
11976
12209
  return isRecord11(parsed) ? parsed : null;
11977
12210
  } catch {
11978
12211
  return null;
@@ -12463,61 +12696,61 @@ var init_authCatalog = __esm(() => {
12463
12696
  });
12464
12697
 
12465
12698
  // src/cli/config/auth/resolveAuthSettings.ts
12466
- import ts11 from "typescript";
12467
- import { existsSync as existsSync27, readFileSync as readFileSync27 } from "fs";
12468
- import { resolve as resolve27 } from "path";
12699
+ import ts12 from "typescript";
12700
+ import { existsSync as existsSync27, readFileSync as readFileSync28 } from "fs";
12701
+ import { resolve as resolve28 } from "path";
12469
12702
  var AUTH_PACKAGE = "@absolutejs/auth", CONFIG_CANDIDATES3, findAuthSettingsPath = (cwd, override) => {
12470
12703
  if (override) {
12471
- const resolved = resolve27(cwd, override);
12704
+ const resolved = resolve28(cwd, override);
12472
12705
  return existsSync27(resolved) ? resolved : null;
12473
12706
  }
12474
12707
  for (const name of CONFIG_CANDIDATES3) {
12475
- const candidate = resolve27(cwd, name);
12708
+ const candidate = resolve28(cwd, name);
12476
12709
  if (existsSync27(candidate))
12477
12710
  return candidate;
12478
12711
  }
12479
12712
  return null;
12480
- }, parseSource2 = (configPath2, text) => ts11.createSourceFile(configPath2, text, ts11.ScriptTarget.Latest, true), findAuthSettingsObject = (sourceFile) => {
12713
+ }, parseSource2 = (configPath2, text2) => ts12.createSourceFile(configPath2, text2, ts12.ScriptTarget.Latest, true), findAuthSettingsObject = (sourceFile) => {
12481
12714
  const pending = [sourceFile];
12482
12715
  while (pending.length > 0) {
12483
12716
  const node = pending.pop();
12484
12717
  if (!node)
12485
12718
  continue;
12486
- const [firstArgument] = ts11.isCallExpression(node) ? node.arguments : [];
12487
- if (ts11.isCallExpression(node) && ts11.isIdentifier(node.expression) && node.expression.text === "defineAuthSettings" && firstArgument && ts11.isObjectLiteralExpression(firstArgument)) {
12719
+ const [firstArgument] = ts12.isCallExpression(node) ? node.arguments : [];
12720
+ if (ts12.isCallExpression(node) && ts12.isIdentifier(node.expression) && node.expression.text === "defineAuthSettings" && firstArgument && ts12.isObjectLiteralExpression(firstArgument)) {
12488
12721
  return firstArgument;
12489
12722
  }
12490
- if (ts11.isExportAssignment(node) && ts11.isObjectLiteralExpression(node.expression)) {
12723
+ if (ts12.isExportAssignment(node) && ts12.isObjectLiteralExpression(node.expression)) {
12491
12724
  return node.expression;
12492
12725
  }
12493
12726
  node.forEachChild((child) => pending.push(child));
12494
12727
  }
12495
12728
  return null;
12496
12729
  }, parseAuthSettingsObject = (configPath2) => {
12497
- const text = readFileSync27(configPath2, "utf-8");
12730
+ const text2 = readFileSync28(configPath2, "utf-8");
12498
12731
  return {
12499
- object: findAuthSettingsObject(parseSource2(configPath2, text)),
12500
- text
12732
+ object: findAuthSettingsObject(parseSource2(configPath2, text2)),
12733
+ text: text2
12501
12734
  };
12502
12735
  }, evalLiteral2 = (node) => {
12503
- if (ts11.isStringLiteralLike(node))
12736
+ if (ts12.isStringLiteralLike(node))
12504
12737
  return { opaque: false, value: node.text };
12505
- if (node.kind === ts11.SyntaxKind.TrueKeyword) {
12738
+ if (node.kind === ts12.SyntaxKind.TrueKeyword) {
12506
12739
  return { opaque: false, value: true };
12507
12740
  }
12508
- if (node.kind === ts11.SyntaxKind.FalseKeyword) {
12741
+ if (node.kind === ts12.SyntaxKind.FalseKeyword) {
12509
12742
  return { opaque: false, value: false };
12510
12743
  }
12511
- if (node.kind === ts11.SyntaxKind.NullKeyword) {
12744
+ if (node.kind === ts12.SyntaxKind.NullKeyword) {
12512
12745
  return { opaque: false, value: null };
12513
12746
  }
12514
- if (ts11.isNumericLiteral(node)) {
12747
+ if (ts12.isNumericLiteral(node)) {
12515
12748
  return { opaque: false, value: Number(node.text) };
12516
12749
  }
12517
- if (ts11.isPrefixUnaryExpression(node) && node.operator === ts11.SyntaxKind.MinusToken && ts11.isNumericLiteral(node.operand)) {
12750
+ if (ts12.isPrefixUnaryExpression(node) && node.operator === ts12.SyntaxKind.MinusToken && ts12.isNumericLiteral(node.operand)) {
12518
12751
  return { opaque: false, value: -Number(node.operand.text) };
12519
12752
  }
12520
- if (ts11.isArrayLiteralExpression(node)) {
12753
+ if (ts12.isArrayLiteralExpression(node)) {
12521
12754
  const items = [];
12522
12755
  for (const element of node.elements) {
12523
12756
  const result = evalLiteral2(element);
@@ -12531,11 +12764,11 @@ var AUTH_PACKAGE = "@absolutejs/auth", CONFIG_CANDIDATES3, findAuthSettingsPath
12531
12764
  }, readCurrent2 = (configPath2) => {
12532
12765
  const current = {};
12533
12766
  const opaqueKeys = [];
12534
- const { object: object2 } = parseAuthSettingsObject(configPath2);
12535
- if (!object2)
12767
+ const { object: object3 } = parseAuthSettingsObject(configPath2);
12768
+ if (!object3)
12536
12769
  return { current, opaqueKeys };
12537
- for (const property of object2.properties) {
12538
- if (!ts11.isPropertyAssignment(property) || !(ts11.isIdentifier(property.name) || ts11.isStringLiteral(property.name))) {
12770
+ for (const property of object3.properties) {
12771
+ if (!ts12.isPropertyAssignment(property) || !(ts12.isIdentifier(property.name) || ts12.isStringLiteral(property.name))) {
12539
12772
  continue;
12540
12773
  }
12541
12774
  const name = property.name.text;
@@ -12568,14 +12801,14 @@ var init_resolveAuthSettings = __esm(() => {
12568
12801
  });
12569
12802
 
12570
12803
  // src/cli/config/auth/resolveAuthState.ts
12571
- import ts12 from "typescript";
12572
- import { existsSync as existsSync28, readdirSync as readdirSync6, readFileSync as readFileSync28 } from "fs";
12573
- import { join as join33, relative as relative17, resolve as resolve28 } from "path";
12574
- var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
12804
+ import ts13 from "typescript";
12805
+ import { existsSync as existsSync28, readdirSync as readdirSync6, readFileSync as readFileSync29 } from "fs";
12806
+ import { join as join34, relative as relative18, resolve as resolve29 } from "path";
12807
+ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson2 = (path) => {
12575
12808
  if (!existsSync28(path))
12576
12809
  return null;
12577
12810
  try {
12578
- const parsed = JSON.parse(readFileSync28(path, "utf-8"));
12811
+ const parsed = JSON.parse(readFileSync29(path, "utf-8"));
12579
12812
  return isRecord12(parsed) ? parsed : null;
12580
12813
  } catch {
12581
12814
  return null;
@@ -12584,7 +12817,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12584
12817
  const value = record?.[key];
12585
12818
  return typeof value === "string" ? value : null;
12586
12819
  }, declaredVersionFor = (cwd) => {
12587
- const pkg = readJson(join33(cwd, "package.json"));
12820
+ const pkg = readJson2(join34(cwd, "package.json"));
12588
12821
  if (!pkg)
12589
12822
  return null;
12590
12823
  for (const field of ["dependencies", "devDependencies"]) {
@@ -12596,14 +12829,14 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12596
12829
  return version2;
12597
12830
  }
12598
12831
  return null;
12599
- }, installedVersionFor = (cwd) => stringField(readJson(join33(cwd, "node_modules", AUTH_PACKAGE2, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
12832
+ }, installedVersionFor = (cwd) => stringField(readJson2(join34(cwd, "node_modules", AUTH_PACKAGE2, "package.json")), "version"), SOURCE_FILE, safeReaddir = (dir) => {
12600
12833
  try {
12601
12834
  return readdirSync6(dir, { withFileTypes: true });
12602
12835
  } catch {
12603
12836
  return [];
12604
12837
  }
12605
12838
  }, sortEntry = (dir, entry, found, dirs) => {
12606
- const full = join33(dir, entry.name);
12839
+ const full = join34(dir, entry.name);
12607
12840
  if (entry.isDirectory()) {
12608
12841
  if (SKIP_DIRS.has(entry.name) || entry.name.startsWith("."))
12609
12842
  return;
@@ -12625,9 +12858,9 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12625
12858
  collectFrom(dir, found, stack);
12626
12859
  }
12627
12860
  return found;
12628
- }, isAuthPackageImport = (statement) => ts12.isImportDeclaration(statement) && ts12.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === AUTH_PACKAGE2, addAuthNames = (statement, names) => {
12861
+ }, isAuthPackageImport = (statement) => ts13.isImportDeclaration(statement) && ts13.isStringLiteral(statement.moduleSpecifier) && statement.moduleSpecifier.text === AUTH_PACKAGE2, addAuthNames = (statement, names) => {
12629
12862
  const bindings = statement.importClause?.namedBindings;
12630
- if (!bindings || !ts12.isNamedImports(bindings))
12863
+ if (!bindings || !ts13.isNamedImports(bindings))
12631
12864
  return;
12632
12865
  for (const element of bindings.elements) {
12633
12866
  const imported = element.propertyName?.text ?? element.name.text;
@@ -12642,18 +12875,18 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12642
12875
  addAuthNames(statement, names);
12643
12876
  }
12644
12877
  return names;
12645
- }, isAuthCall = (node, bindings) => ts12.isIdentifier(node.expression) && bindings.has(node.expression.text), providerCountOf = (property) => {
12646
- if (!ts12.isPropertyAssignment(property) || !ts12.isObjectLiteralExpression(property.initializer)) {
12878
+ }, isAuthCall = (node, bindings) => ts13.isIdentifier(node.expression) && bindings.has(node.expression.text), providerCountOf = (property) => {
12879
+ if (!ts13.isPropertyAssignment(property) || !ts13.isObjectLiteralExpression(property.initializer)) {
12647
12880
  return null;
12648
12881
  }
12649
12882
  return property.initializer.properties.length;
12650
- }, readConfigKeys = (object2) => {
12883
+ }, readConfigKeys = (object3) => {
12651
12884
  const keys = new Set;
12652
12885
  let providerCount = null;
12653
- const usesSpread = object2.properties.some((property) => ts12.isSpreadAssignment(property));
12654
- for (const property of object2.properties) {
12886
+ const usesSpread = object3.properties.some((property) => ts13.isSpreadAssignment(property));
12887
+ for (const property of object3.properties) {
12655
12888
  const { name } = property;
12656
- if (name === undefined || !ts12.isIdentifier(name))
12889
+ if (name === undefined || !ts13.isIdentifier(name))
12657
12890
  continue;
12658
12891
  keys.add(name.text);
12659
12892
  if (name.text !== "providersConfiguration")
@@ -12663,20 +12896,20 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12663
12896
  return { keys, providerCount, usesSpread };
12664
12897
  }, matchFromCall = (node) => {
12665
12898
  const [arg] = node.arguments;
12666
- if (arg && ts12.isObjectLiteralExpression(arg))
12899
+ if (arg && ts13.isObjectLiteralExpression(arg))
12667
12900
  return readConfigKeys(arg);
12668
12901
  return { keys: new Set, providerCount: null, usesSpread: true };
12669
12902
  }, readFileOrNull = (path) => {
12670
12903
  try {
12671
- return readFileSync28(path, "utf-8");
12904
+ return readFileSync29(path, "utf-8");
12672
12905
  } catch {
12673
12906
  return null;
12674
12907
  }
12675
12908
  }, findSetupInFile = (path) => {
12676
- const text = readFileOrNull(path);
12677
- if (text === null || !text.includes(AUTH_PACKAGE2))
12909
+ const text2 = readFileOrNull(path);
12910
+ if (text2 === null || !text2.includes(AUTH_PACKAGE2))
12678
12911
  return null;
12679
- const sourceFile = ts12.createSourceFile(path, text, ts12.ScriptTarget.Latest, true);
12912
+ const sourceFile = ts13.createSourceFile(path, text2, ts13.ScriptTarget.Latest, true);
12680
12913
  const bindings = authBindings(sourceFile);
12681
12914
  if (bindings.size === 0)
12682
12915
  return null;
@@ -12685,7 +12918,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12685
12918
  const node = pending.pop();
12686
12919
  if (!node)
12687
12920
  continue;
12688
- if (ts12.isCallExpression(node) && isAuthCall(node, bindings)) {
12921
+ if (ts13.isCallExpression(node) && isAuthCall(node, bindings)) {
12689
12922
  return matchFromCall(node);
12690
12923
  }
12691
12924
  node.forEachChild((child) => pending.push(child));
@@ -12701,7 +12934,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12701
12934
  scaffoldable: isScaffoldableFeature(feature.id)
12702
12935
  })), resolveAuthState = (cwd) => {
12703
12936
  const installedVersion = installedVersionFor(cwd);
12704
- const root = existsSync28(join33(cwd, "src")) ? join33(cwd, "src") : cwd;
12937
+ const root = existsSync28(join34(cwd, "src")) ? join34(cwd, "src") : cwd;
12705
12938
  let match = null;
12706
12939
  let setupPath = null;
12707
12940
  for (const file of candidateFiles(root)) {
@@ -12709,7 +12942,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
12709
12942
  if (found === null)
12710
12943
  continue;
12711
12944
  match = found;
12712
- setupPath = relative17(cwd, resolve28(file));
12945
+ setupPath = relative18(cwd, resolve29(file));
12713
12946
  break;
12714
12947
  }
12715
12948
  const keys = match?.keys ?? new Set;
@@ -12747,7 +12980,7 @@ var init_resolveAuthState = __esm(() => {
12747
12980
 
12748
12981
  // src/cli/config/auth/scaffoldAuthFeature.ts
12749
12982
  import { existsSync as existsSync29, writeFileSync as writeFileSync15 } from "fs";
12750
- import { dirname as dirname22, join as join34, relative as relative18, resolve as resolve29 } from "path";
12983
+ import { dirname as dirname22, join as join35, relative as relative19, resolve as resolve30 } from "path";
12751
12984
  var renderScaffold = (scaffold) => {
12752
12985
  const importNames = [...scaffold.imports, `type ${scaffold.typeName}`];
12753
12986
  const importLine = `import { ${importNames.join(", ")} } from '@absolutejs/auth';`;
@@ -12772,8 +13005,8 @@ ${body}
12772
13005
  }, targetDir = (cwd) => {
12773
13006
  const { setupPath } = resolveAuthState(cwd);
12774
13007
  if (setupPath)
12775
- return dirname22(resolve29(cwd, setupPath));
12776
- const src = join34(cwd, "src");
13008
+ return dirname22(resolve30(cwd, setupPath));
13009
+ const src = join35(cwd, "src");
12777
13010
  return existsSync29(src) ? src : cwd;
12778
13011
  }, spreadFor = (scaffold) => `import { ${scaffold.exportName} } from './${scaffold.exportName}';
12779
13012
  // add to your auth() call:
@@ -12787,8 +13020,8 @@ ${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
12787
13020
  const scaffold = AUTH_SCAFFOLDS[id];
12788
13021
  if (!scaffold)
12789
13022
  return failure2(`Unknown auth feature "${id}".`);
12790
- const filePath = join34(targetDir(cwd), `${scaffold.exportName}.ts`);
12791
- const relPath = relative18(cwd, filePath);
13023
+ const filePath = join35(targetDir(cwd), `${scaffold.exportName}.ts`);
13024
+ const relPath = relative19(cwd, filePath);
12792
13025
  if (existsSync29(filePath)) {
12793
13026
  return {
12794
13027
  created: null,
@@ -12816,12 +13049,12 @@ var init_scaffoldAuthFeature = __esm(() => {
12816
13049
  });
12817
13050
 
12818
13051
  // src/cli/htmx/install.ts
12819
- import { existsSync as existsSync30, mkdirSync as mkdirSync14, readFileSync as readFileSync29, writeFileSync as writeFileSync16 } from "fs";
12820
- import { join as join35 } from "path";
13052
+ import { existsSync as existsSync30, mkdirSync as mkdirSync14, readFileSync as readFileSync30, writeFileSync as writeFileSync16 } from "fs";
13053
+ import { join as join36 } from "path";
12821
13054
  var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
12822
- join35(import.meta.dir, "htmx.min.js"),
12823
- join35(import.meta.dir, "htmx", "htmx.min.js"),
12824
- join35(import.meta.dir, "..", "htmx", "htmx.min.js")
13055
+ join36(import.meta.dir, "htmx.min.js"),
13056
+ join36(import.meta.dir, "htmx", "htmx.min.js"),
13057
+ join36(import.meta.dir, "..", "htmx", "htmx.min.js")
12825
13058
  ].find((path) => existsSync30(path)) ?? null, detectHtmxVersion = (content) => {
12826
13059
  const match = content.match(/version:"([0-9.]+)"/);
12827
13060
  return match ? match[1] : null;
@@ -12833,16 +13066,16 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
12833
13066
  }
12834
13067
  return response.text();
12835
13068
  }, installedHtmxVersion = (htmxDir) => {
12836
- const file = join35(htmxDir, "htmx.min.js");
13069
+ const file = join36(htmxDir, "htmx.min.js");
12837
13070
  if (!existsSync30(file))
12838
13071
  return null;
12839
- return detectHtmxVersion(readFileSync29(file, "utf-8"));
13072
+ return detectHtmxVersion(readFileSync30(file, "utf-8"));
12840
13073
  }, readVendoredHtmx = () => {
12841
13074
  const file = vendoredHtmxFile();
12842
- return file ? readFileSync29(file, "utf-8") : null;
13075
+ return file ? readFileSync30(file, "utf-8") : null;
12843
13076
  }, writeHtmx = (htmxDir, content) => {
12844
13077
  mkdirSync14(htmxDir, { recursive: true });
12845
- const file = join35(htmxDir, "htmx.min.js");
13078
+ const file = join36(htmxDir, "htmx.min.js");
12846
13079
  writeFileSync16(file, content, "utf-8");
12847
13080
  return file;
12848
13081
  };
@@ -12853,8 +13086,8 @@ var exports_add = {};
12853
13086
  __export(exports_add, {
12854
13087
  runAdd: () => runAdd
12855
13088
  });
12856
- import { dirname as dirname23, join as join36, relative as relative19 } from "path";
12857
- var write2 = (text) => process.stdout.write(`${text}
13089
+ import { dirname as dirname23, join as join37, relative as relative20 } from "path";
13090
+ var write2 = (text2) => process.stdout.write(`${text2}
12858
13091
  `), fail2 = (message) => {
12859
13092
  process.stdout.write(`${colors.red}${message}${colors.reset}
12860
13093
  `);
@@ -12864,11 +13097,11 @@ var write2 = (text) => process.stdout.write(`${text}
12864
13097
  return;
12865
13098
  write2(` ${colors.dim}${label}${colors.reset}`);
12866
13099
  for (const path of paths)
12867
- write2(` ${relative19(cwd, path)}`);
13100
+ write2(` ${relative20(cwd, path)}`);
12868
13101
  }, frontendRoot = (project, cwd) => {
12869
13102
  const [firstKey] = configuredFrameworks(project);
12870
13103
  const firstDir = firstKey ? project.frameworkDirs[firstKey] : undefined;
12871
- return firstDir ? dirname23(firstDir) : join36(cwd, "src", "frontend");
13104
+ return firstDir ? dirname23(firstDir) : join37(cwd, "src", "frontend");
12872
13105
  }, addIntegrationCli = (id, install) => {
12873
13106
  const result = addIntegration(process.cwd(), id, { install });
12874
13107
  if (!result.ok) {
@@ -12932,8 +13165,8 @@ var write2 = (text) => process.stdout.write(`${text}
12932
13165
  write2(`${colors.yellow}!${colors.reset} ${frameworks6[framework].label} is already configured \u2014 nothing to do.`);
12933
13166
  return;
12934
13167
  }
12935
- const dirAbs = join36(frontendRoot(project, cwd), framework);
12936
- const dirRel = `./${relative19(cwd, dirAbs).split("\\").join("/")}`;
13168
+ const dirAbs = join37(frontendRoot(project, cwd), framework);
13169
+ const dirRel = `./${relative20(cwd, dirAbs).split("\\").join("/")}`;
12937
13170
  let depNote = "Skipped dependency install (--no-install).";
12938
13171
  if (!noInstall) {
12939
13172
  write2(`${colors.dim}Installing ${frameworks6[framework].label} dependencies\u2026${colors.reset}`);
@@ -13002,8 +13235,8 @@ var exports_analyze = {};
13002
13235
  __export(exports_analyze, {
13003
13236
  runAnalyze: () => runAnalyze
13004
13237
  });
13005
- import { existsSync as existsSync31, readFileSync as readFileSync30, statSync as statSync3, writeFileSync as writeFileSync17 } from "fs";
13006
- import { join as join37, resolve as resolve30 } from "path";
13238
+ import { existsSync as existsSync31, readFileSync as readFileSync31, statSync as statSync3, writeFileSync as writeFileSync17 } from "fs";
13239
+ import { join as join38, resolve as resolve31 } from "path";
13007
13240
  var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_WIDTH = 16, SIZE_WIDTH = 12, CHANGE_WIDTH = 10, CATEGORY_ORDER, categoryOf = (key) => {
13008
13241
  if (key.startsWith("Island"))
13009
13242
  return "Islands";
@@ -13023,21 +13256,21 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
13023
13256
  return 0;
13024
13257
  }
13025
13258
  }, readSizes = (manifestDir) => {
13026
- const manifestPath = join37(manifestDir, "manifest.json");
13259
+ const manifestPath = join38(manifestDir, "manifest.json");
13027
13260
  if (!existsSync31(manifestPath))
13028
13261
  return null;
13029
- const manifest = JSON.parse(readFileSync30(manifestPath, "utf-8"));
13262
+ const manifest = JSON.parse(readFileSync31(manifestPath, "utf-8"));
13030
13263
  const sizes = {};
13031
13264
  for (const [key, value] of Object.entries(manifest)) {
13032
- sizes[key] = fileSize2(join37(manifestDir, value.replace(/^\//, "")));
13265
+ sizes[key] = fileSize2(join38(manifestDir, value.replace(/^\//, "")));
13033
13266
  }
13034
13267
  return sizes;
13035
13268
  }, readBaseline = (cwd) => {
13036
- const path = join37(cwd, BASELINE_FILE);
13269
+ const path = join38(cwd, BASELINE_FILE);
13037
13270
  if (!existsSync31(path))
13038
13271
  return null;
13039
13272
  try {
13040
- const parsed = JSON.parse(readFileSync30(path, "utf-8"));
13273
+ const parsed = JSON.parse(readFileSync31(path, "utf-8"));
13041
13274
  return parsed;
13042
13275
  } catch {
13043
13276
  return null;
@@ -13115,14 +13348,14 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
13115
13348
  const config = await loadConfig(configIndex >= 0 ? args[configIndex + 1] : undefined);
13116
13349
  const outdirIndex = args.indexOf("--outdir");
13117
13350
  const outdir = outdirIndex >= 0 ? args[outdirIndex + 1] : config.buildDirectory;
13118
- const sizes = readSizes(resolve30(cwd, outdir ?? "build"));
13351
+ const sizes = readSizes(resolve31(cwd, outdir ?? "build"));
13119
13352
  if (sizes === null) {
13120
13353
  process.stdout.write(`${colors.dim}No build found. Run \`absolute build\` first.${colors.reset}
13121
13354
  `);
13122
13355
  return;
13123
13356
  }
13124
13357
  if (args.includes("--save")) {
13125
- writeFileSync17(join37(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
13358
+ writeFileSync17(join38(cwd, BASELINE_FILE), `${JSON.stringify(sizes, null, 2)}
13126
13359
  `);
13127
13360
  process.stdout.write(`${colors.green}\u2713${colors.reset} Saved size baseline (${Object.keys(sizes).length} entries) to ${BASELINE_FILE}
13128
13361
  `);
@@ -13167,7 +13400,7 @@ var SLOW_MS = 100, VERY_SLOW_MS = 500, HTTP_SERVER_ERROR = 500, HTTP_CLIENT_ERRO
13167
13400
  }, isDim = (kind) => kind !== "api" && kind !== "page", pickServer = (instances) => {
13168
13401
  const withUrl = instances.filter((instance) => instance.url !== null);
13169
13402
  return withUrl.find((instance) => instance.source === "dev") ?? withUrl.find((instance) => instance.source !== "untracked") ?? withUrl[0] ?? null;
13170
- }, clock = (epochMs) => new Date(epochMs).toLocaleTimeString([], { hour12: false }), tint = (text, color, dim) => `${dim ? colors.dim : color}${text}${colors.reset}`, aggregates = (records) => {
13403
+ }, clock = (epochMs) => new Date(epochMs).toLocaleTimeString([], { hour12: false }), tint = (text2, color, dim) => `${dim ? colors.dim : color}${text2}${colors.reset}`, aggregates = (records) => {
13171
13404
  const durations = records.filter((record) => !isDim(record.kind)).map((record) => record.durationMs).sort((left, right) => left - right);
13172
13405
  const total = durations.reduce((sum, value) => sum + value, 0);
13173
13406
  const avgMs = durations.length ? Math.round(total / durations.length) : 0;
@@ -13368,9 +13601,9 @@ var exports_remove = {};
13368
13601
  __export(exports_remove, {
13369
13602
  runRemove: () => runRemove
13370
13603
  });
13371
- import { existsSync as existsSync32, readFileSync as readFileSync31 } from "fs";
13372
- import { relative as relative20 } from "path";
13373
- var write3 = (text) => process.stdout.write(`${text}
13604
+ import { existsSync as existsSync32, readFileSync as readFileSync32 } from "fs";
13605
+ import { relative as relative21 } from "path";
13606
+ var write3 = (text2) => process.stdout.write(`${text2}
13374
13607
  `), fail3 = (message) => {
13375
13608
  process.stdout.write(`${colors.red}${message}${colors.reset}
13376
13609
  `);
@@ -13382,7 +13615,7 @@ var write3 = (text) => process.stdout.write(`${text}
13382
13615
  if (file === null || seen.has(file) || !existsSync32(file))
13383
13616
  return false;
13384
13617
  seen.add(file);
13385
- return readFileSync31(file, "utf-8").includes(handler);
13618
+ return readFileSync32(file, "utf-8").includes(handler);
13386
13619
  });
13387
13620
  }, runRemove = async (args) => {
13388
13621
  const [framework] = args.filter((arg) => !arg.startsWith("--"));
@@ -13418,10 +13651,10 @@ var write3 = (text) => process.stdout.write(`${text}
13418
13651
  }
13419
13652
  write3(`${colors.green}\u2713${colors.reset} Removed ${framework}Directory from absolute.config.ts
13420
13653
  `);
13421
- write3(` ${colors.dim}Kept${colors.reset} ${relative20(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
13654
+ write3(` ${colors.dim}Kept${colors.reset} ${relative21(cwd, frameworkDir)} \u2014 delete its source manually if no longer needed.`);
13422
13655
  const refs = referencingFiles(project.serverEntry, HANDLER_NAME[framework]);
13423
13656
  for (const file of refs) {
13424
- write3(` ${colors.yellow}Still references${colors.reset} ${relative20(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
13657
+ write3(` ${colors.yellow}Still references${colors.reset} ${relative21(cwd, file)} (calls ${HANDLER_NAME[framework]})`);
13425
13658
  }
13426
13659
  const deps = frameworkDependencyNames(framework);
13427
13660
  if (prune && deps.length > 0) {
@@ -13459,7 +13692,7 @@ var exports_htmx = {};
13459
13692
  __export(exports_htmx, {
13460
13693
  runHtmx: () => runHtmx
13461
13694
  });
13462
- var write4 = (text) => process.stdout.write(`${text}
13695
+ var write4 = (text2) => process.stdout.write(`${text2}
13463
13696
  `), fail4 = (message) => {
13464
13697
  process.stdout.write(`${colors.red}${message}${colors.reset}
13465
13698
  `);
@@ -13509,15 +13742,15 @@ __export(exports_env, {
13509
13742
  runEnv: () => runEnv,
13510
13743
  collectEnvVars: () => collectEnvVars
13511
13744
  });
13512
- import { existsSync as existsSync33, readFileSync as readFileSync32 } from "fs";
13513
- import { join as join38 } from "path";
13745
+ import { existsSync as existsSync33, readFileSync as readFileSync33 } from "fs";
13746
+ import { join as join39 } from "path";
13514
13747
  var {env: env3, Glob: Glob3 } = globalThis.Bun;
13515
- var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text) => [...text.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync33(join38(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
13748
+ var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text2) => [...text2.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync33(join39(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
13516
13749
  const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
13517
13750
  const files = (await Promise.all(scans)).flat();
13518
13751
  const usage = new Map;
13519
13752
  files.forEach((file) => {
13520
- keysInFile(readFileSync32(file, "utf-8")).forEach((key) => {
13753
+ keysInFile(readFileSync33(file, "utf-8")).forEach((key) => {
13521
13754
  usage.set(key, [...usage.get(key) ?? [], file]);
13522
13755
  });
13523
13756
  });
@@ -13578,10 +13811,10 @@ __export(exports_db, {
13578
13811
  conflictClause: () => conflictClause,
13579
13812
  chunkRows: () => chunkRows
13580
13813
  });
13581
- import { existsSync as existsSync34, mkdirSync as mkdirSync15, readFileSync as readFileSync33, writeFileSync as writeFileSync18 } from "fs";
13582
- import { join as join39 } from "path";
13814
+ import { existsSync as existsSync34, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync18 } from "fs";
13815
+ import { join as join40 } from "path";
13583
13816
  var {env: env4, spawn: spawn2, SQL } = globalThis.Bun;
13584
- var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA_TYPES, SEED_CANDIDATES, VALUE_FLAGS, paint = (text, color) => `${color}${text}${colors.reset}`, chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size)), quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`, resolveUrl = (explicit) => {
13817
+ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA_TYPES, SEED_CANDIDATES, VALUE_FLAGS, paint = (text2, color) => `${color}${text2}${colors.reset}`, chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size)), quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`, resolveUrl = (explicit) => {
13585
13818
  const found = explicit ?? URL_ENV_KEYS.map((key) => env4[key]).find((value) => typeof value === "string" && value !== "");
13586
13819
  if (found === undefined || found === "")
13587
13820
  throw new Error(`No database URL found. Set ${URL_ENV_KEYS.join(" or ")}, or pass --url <url>.`);
@@ -13689,19 +13922,19 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
13689
13922
  tables,
13690
13923
  v: BACKUP_FORMAT_VERSION
13691
13924
  };
13692
- const dir = options.out ?? join39(process.cwd(), "backups");
13925
+ const dir = options.out ?? join40(process.cwd(), "backups");
13693
13926
  mkdirSync15(dir, { recursive: true });
13694
13927
  const json = JSON.stringify(payload, (_, value) => typeof value === "bigint" ? value.toString() : value);
13695
- const file = join39(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
13928
+ const file = join40(dir, `backup-${payload.at.replace(/[:.]/g, "-")}.json`);
13696
13929
  writeFileSync18(file, json);
13697
- writeFileSync18(join39(dir, "latest.json"), json);
13930
+ writeFileSync18(join40(dir, "latest.json"), json);
13698
13931
  const total = chosen.reduce((sum, name) => sum + (tables[name]?.length ?? 0), 0);
13699
13932
  console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
13700
13933
  console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
13701
13934
  }, runRestore = async (file, options) => {
13702
13935
  if (!existsSync34(file))
13703
13936
  throw new Error(`Backup not found: ${file}`);
13704
- const payload = JSON.parse(readFileSync33(file, "utf-8"));
13937
+ const payload = JSON.parse(readFileSync34(file, "utf-8"));
13705
13938
  const names = Object.keys(payload.tables).filter((name) => keepTable(name, options));
13706
13939
  const sql = new SQL(options.url);
13707
13940
  const order = dependencyOrder(names, await foreignLinks(sql));
@@ -13723,7 +13956,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
13723
13956
  const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
13724
13957
  console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
13725
13958
  }, runSeed = async (entry) => {
13726
- const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync34(join39(process.cwd(), candidate)));
13959
+ const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync34(join40(process.cwd(), candidate)));
13727
13960
  if (target === undefined)
13728
13961
  throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
13729
13962
  console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
@@ -13758,7 +13991,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
13758
13991
  return;
13759
13992
  }
13760
13993
  if (sub === "restore") {
13761
- const file = positionalArgs(rest)[0] ?? join39(process.cwd(), "backups", "latest.json");
13994
+ const file = positionalArgs(rest)[0] ?? join40(process.cwd(), "backups", "latest.json");
13762
13995
  await runRestore(file, parseOptions(rest));
13763
13996
  return;
13764
13997
  }
@@ -13872,16 +14105,16 @@ var init_logs = __esm(() => {
13872
14105
  // src/cli/typeGraphCoherence.ts
13873
14106
  import {
13874
14107
  existsSync as existsSync36,
13875
- readFileSync as readFileSync34,
14108
+ readFileSync as readFileSync35,
13876
14109
  realpathSync as realpathSync2,
13877
14110
  rmSync as rmSync6,
13878
14111
  writeFileSync as writeFileSync19
13879
14112
  } from "fs";
13880
14113
  import { createRequire } from "module";
13881
- import { dirname as dirname24, join as join40, resolve as resolve31, sep as sep5 } from "path";
14114
+ import { dirname as dirname24, join as join41, resolve as resolve32, sep as sep5 } from "path";
13882
14115
  var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
13883
14116
  try {
13884
- const parsed = JSON.parse(readFileSync34(path, "utf-8"));
14117
+ const parsed = JSON.parse(readFileSync35(path, "utf-8"));
13885
14118
  return isRecord9(parsed) ? parsed : null;
13886
14119
  } catch {
13887
14120
  return null;
@@ -13900,7 +14133,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
13900
14133
  }, packageJsonFromEntry = (entry, expectedName) => {
13901
14134
  let directory = dirname24(entry);
13902
14135
  for (;; ) {
13903
- const candidate = join40(directory, "package.json");
14136
+ const candidate = join41(directory, "package.json");
13904
14137
  const manifest = readManifest(candidate);
13905
14138
  if (manifest && manifestName(manifest, "") === expectedName)
13906
14139
  return candidate;
@@ -13920,27 +14153,27 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
13920
14153
  }
13921
14154
  }
13922
14155
  }, findInstallRoot = (cwd) => {
13923
- let directory = resolve31(cwd);
14156
+ let directory = resolve32(cwd);
13924
14157
  for (;; ) {
13925
- if (existsSync36(join40(directory, "bun.lock")) || existsSync36(join40(directory, "bun.lockb"))) {
14158
+ if (existsSync36(join41(directory, "bun.lock")) || existsSync36(join41(directory, "bun.lockb"))) {
13926
14159
  return directory;
13927
14160
  }
13928
14161
  const parent = dirname24(directory);
13929
14162
  if (parent === directory)
13930
- return resolve31(cwd);
14163
+ return resolve32(cwd);
13931
14164
  directory = parent;
13932
14165
  }
13933
14166
  }, findProjectManifest = (cwd, installRoot) => {
13934
- let directory = resolve31(cwd);
14167
+ let directory = resolve32(cwd);
13935
14168
  for (;; ) {
13936
- const candidate = join40(directory, "package.json");
14169
+ const candidate = join41(directory, "package.json");
13937
14170
  if (existsSync36(candidate))
13938
14171
  return candidate;
13939
14172
  if (directory === installRoot)
13940
- return join40(installRoot, "package.json");
14173
+ return join41(installRoot, "package.json");
13941
14174
  const parent = dirname24(directory);
13942
14175
  if (parent === directory)
13943
- return join40(installRoot, "package.json");
14176
+ return join41(installRoot, "package.json");
13944
14177
  directory = parent;
13945
14178
  }
13946
14179
  }, appendConsumer = (consumers, consumerPaths, path, manifest) => {
@@ -13978,7 +14211,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
13978
14211
  appendConsumer(consumers, consumerPaths, inspection.consumer.path, inspection.consumer.manifest);
13979
14212
  }, inspectTypeGraph = (cwd) => {
13980
14213
  const installRoot = findInstallRoot(cwd);
13981
- const rootManifestPath = join40(installRoot, "package.json");
14214
+ const rootManifestPath = join41(installRoot, "package.json");
13982
14215
  const rootManifest = readManifest(rootManifestPath) ?? {};
13983
14216
  const consumers = [
13984
14217
  { manifest: rootManifest, path: rootManifestPath }
@@ -14014,7 +14247,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
14014
14247
  const duplicates = duplicateTypeGraphPackages(report);
14015
14248
  if (duplicates.length === 0)
14016
14249
  return [];
14017
- const manifestPath = join40(report.installRoot, "package.json");
14250
+ const manifestPath = join41(report.installRoot, "package.json");
14018
14251
  const manifest = readManifest(manifestPath);
14019
14252
  if (!manifest)
14020
14253
  return [];
@@ -14036,7 +14269,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
14036
14269
  }
14037
14270
  return changes;
14038
14271
  }, removeDuplicateTypeGraphPackages = (report) => {
14039
- const manifest = readManifest(join40(report.installRoot, "package.json")) ?? {};
14272
+ const manifest = readManifest(join41(report.installRoot, "package.json")) ?? {};
14040
14273
  const rootName = manifestName(manifest, "<workspace>");
14041
14274
  const installPrefix = `${realpathSync2(report.installRoot)}${sep5}`;
14042
14275
  const nodeModulesSegment = `${sep5}node_modules${sep5}`;
@@ -14075,10 +14308,10 @@ var exports_doctor = {};
14075
14308
  __export(exports_doctor, {
14076
14309
  runDoctor: () => runDoctor
14077
14310
  });
14078
- import { existsSync as existsSync37, mkdirSync as mkdirSync16, readFileSync as readFileSync35, writeFileSync as writeFileSync20 } from "fs";
14311
+ import { existsSync as existsSync37, mkdirSync as mkdirSync16, readFileSync as readFileSync36, writeFileSync as writeFileSync20 } from "fs";
14079
14312
  import { createRequire as createRequire2 } from "module";
14080
14313
  import { arch as arch4, platform as platform5 } from "os";
14081
- import { join as join41 } from "path";
14314
+ import { join as join42 } from "path";
14082
14315
  var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
14083
14316
  detail,
14084
14317
  label,
@@ -14113,7 +14346,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
14113
14346
  return [];
14114
14347
  const label = `${field.replace("Directory", "")} pages`;
14115
14348
  return [
14116
- existsSync37(join41(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
14349
+ existsSync37(join42(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
14117
14350
  ];
14118
14351
  }), envCheck = async () => {
14119
14352
  const vars = await collectEnvVars();
@@ -14175,9 +14408,9 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
14175
14408
  const fixes = [];
14176
14409
  for (const field of FRAMEWORK_FIELDS2) {
14177
14410
  const dir = readString2(config, field);
14178
- if (dir === undefined || existsSync37(join41(cwd, dir)))
14411
+ if (dir === undefined || existsSync37(join42(cwd, dir)))
14179
14412
  continue;
14180
- mkdirSync16(join41(cwd, dir, "pages"), { recursive: true });
14413
+ mkdirSync16(join42(cwd, dir, "pages"), { recursive: true });
14181
14414
  fixes.push(`created ${dir}/pages`);
14182
14415
  }
14183
14416
  return fixes;
@@ -14185,8 +14418,8 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
14185
14418
  const missing = (await collectEnvVars()).filter((entry) => !entry.set);
14186
14419
  if (missing.length === 0)
14187
14420
  return null;
14188
- const envExample = join41(cwd, ".env.example");
14189
- const existing = existsSync37(envExample) ? readFileSync35(envExample, "utf-8") : "";
14421
+ const envExample = join42(cwd, ".env.example");
14422
+ const existing = existsSync37(envExample) ? readFileSync36(envExample, "utf-8") : "";
14190
14423
  const existingKeys = new Set(existing.split(`
14191
14424
  `).map((line) => line.split("=")[0]?.trim()));
14192
14425
  const toAdd = missing.filter((entry) => !existingKeys.has(entry.key));
@@ -14256,7 +14489,7 @@ var init_doctor = __esm(() => {
14256
14489
  "htmlDirectory",
14257
14490
  "htmxDirectory"
14258
14491
  ];
14259
- projectRequire = createRequire2(join41(process.cwd(), "package.json"));
14492
+ projectRequire = createRequire2(join42(process.cwd(), "package.json"));
14260
14493
  STATUS_MARK = {
14261
14494
  fail: `${colors.red}\u2717${colors.reset}`,
14262
14495
  ok: `${colors.green}\u2713${colors.reset}`,
@@ -14645,8 +14878,8 @@ var init_sourceMetadata = __esm(() => {
14645
14878
  });
14646
14879
 
14647
14880
  // src/islands/pageMetadata.ts
14648
- import { readFileSync as readFileSync36 } from "fs";
14649
- import { dirname as dirname25, resolve as resolve32 } from "path";
14881
+ import { readFileSync as readFileSync37 } from "fs";
14882
+ import { dirname as dirname25, resolve as resolve33 } from "path";
14650
14883
  var pagePatterns, getPageDirs = (config) => [
14651
14884
  { dir: config.angularDirectory, framework: "angular" },
14652
14885
  { dir: config.emberDirectory, framework: "ember" },
@@ -14666,8 +14899,8 @@ var pagePatterns, getPageDirs = (config) => [
14666
14899
  const source = definition.buildReference?.source;
14667
14900
  if (!source)
14668
14901
  continue;
14669
- const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve32(dirname25(buildInfo.resolvedRegistryPath), source);
14670
- lookup.set(`${definition.framework}:${definition.component}`, resolve32(resolvedSource));
14902
+ const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve33(dirname25(buildInfo.resolvedRegistryPath), source);
14903
+ lookup.set(`${definition.framework}:${definition.component}`, resolve33(resolvedSource));
14671
14904
  }
14672
14905
  return lookup;
14673
14906
  }, resolveIslandUsages = (islands, islandSourceLookup) => islands.map((usage2) => {
@@ -14680,13 +14913,13 @@ var pagePatterns, getPageDirs = (config) => [
14680
14913
  const pattern = pagePatterns[entry.framework];
14681
14914
  if (!pattern)
14682
14915
  return;
14683
- const files = await scanEntryPoints(resolve32(entry.dir), pattern);
14916
+ const files = await scanEntryPoints(resolve33(entry.dir), pattern);
14684
14917
  for (const filePath of files) {
14685
- const source = readFileSync36(filePath, "utf-8");
14918
+ const source = readFileSync37(filePath, "utf-8");
14686
14919
  const islands = extractIslandUsagesFromSource(source);
14687
- pageMetadata.set(resolve32(filePath), {
14920
+ pageMetadata.set(resolve33(filePath), {
14688
14921
  islands: resolveIslandUsages(islands, islandSourceLookup),
14689
- pagePath: resolve32(filePath)
14922
+ pagePath: resolve33(filePath)
14690
14923
  });
14691
14924
  }
14692
14925
  }, loadPageIslandMetadata = async (config) => {
@@ -14715,14 +14948,14 @@ var exports_islands = {};
14715
14948
  __export(exports_islands, {
14716
14949
  runIslands: () => runIslands
14717
14950
  });
14718
- import { existsSync as existsSync39, readFileSync as readFileSync37, statSync as statSync5 } from "fs";
14719
- import { join as join42, relative as relative21, resolve as resolve33 } from "path";
14951
+ import { existsSync as existsSync39, readFileSync as readFileSync38, statSync as statSync5 } from "fs";
14952
+ import { join as join43, relative as relative22, resolve as resolve34 } from "path";
14720
14953
  var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
14721
14954
  `), hostFrameworkOf = (pagePath, cwd, config) => {
14722
- const resolved = resolve33(cwd, pagePath);
14955
+ const resolved = resolve34(cwd, pagePath);
14723
14956
  for (const [framework, key] of Object.entries(FRAMEWORK_DIR_KEY)) {
14724
14957
  const dir = config[key];
14725
- if (typeof dir === "string" && resolved.startsWith(resolve33(cwd, dir))) {
14958
+ if (typeof dir === "string" && resolved.startsWith(resolve34(cwd, dir))) {
14726
14959
  return framework;
14727
14960
  }
14728
14961
  }
@@ -14734,20 +14967,20 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
14734
14967
  return 0;
14735
14968
  }
14736
14969
  }, readManifestSizes2 = (manifestDir) => {
14737
- const manifestPath = join42(manifestDir, "manifest.json");
14970
+ const manifestPath = join43(manifestDir, "manifest.json");
14738
14971
  if (!existsSync39(manifestPath))
14739
14972
  return null;
14740
- const manifest = JSON.parse(readFileSync37(manifestPath, "utf-8"));
14973
+ const manifest = JSON.parse(readFileSync38(manifestPath, "utf-8"));
14741
14974
  const sizes = new Map;
14742
14975
  for (const [key, value] of Object.entries(manifest)) {
14743
- sizes.set(key, fileSize3(join42(manifestDir, value.replace(/^\//, ""))));
14976
+ sizes.set(key, fileSize3(join43(manifestDir, value.replace(/^\//, ""))));
14744
14977
  }
14745
14978
  return sizes;
14746
14979
  }, collectIslands = async (cwd, config, sizes) => {
14747
14980
  const registryPath = config.islands?.registry;
14748
14981
  if (typeof registryPath !== "string")
14749
14982
  return null;
14750
- const buildInfo = await loadIslandRegistryBuildInfo(resolve33(cwd, registryPath));
14983
+ const buildInfo = await loadIslandRegistryBuildInfo(resolve34(cwd, registryPath));
14751
14984
  const pageMetadata = await loadPageIslandMetadata(config);
14752
14985
  const usages = [...pageMetadata.values()].flatMap((meta) => meta.islands.map((island) => ({ ...island, page: meta.pagePath })));
14753
14986
  return buildInfo.definitions.map((definition) => {
@@ -14757,7 +14990,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
14757
14990
  crossFramework: hostFramework !== null && hostFramework !== definition.framework,
14758
14991
  hostFramework,
14759
14992
  hydrate: usage2.hydrate ?? "load",
14760
- page: relative21(cwd, resolve33(cwd, usage2.page))
14993
+ page: relative22(cwd, resolve34(cwd, usage2.page))
14761
14994
  };
14762
14995
  });
14763
14996
  const key = getIslandManifestKey(definition.framework, definition.component);
@@ -14796,7 +15029,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
14796
15029
  ` ${color}\u2B21${colors.reset} ${colors.bold}${island.component}${colors.reset} ${meta}${sizeText}`
14797
15030
  ];
14798
15031
  if (island.source) {
14799
- lines.push(` ${colors.dim}${relative21(cwd, island.source)}${colors.reset}`);
15032
+ lines.push(` ${colors.dim}${relative22(cwd, island.source)}${colors.reset}`);
14800
15033
  }
14801
15034
  if (pages.length === 0) {
14802
15035
  lines.push(` ${colors.dim}(registered but not mounted on any page)${colors.reset}`);
@@ -14826,7 +15059,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
14826
15059
  }
14827
15060
  const outdirIndex = args.indexOf("--outdir");
14828
15061
  const outdir = outdirIndex >= 0 ? args[outdirIndex + 1] : config.buildDirectory;
14829
- const sizes = args.includes("--sizes") ? readManifestSizes2(resolve33(cwd, outdir ?? "build")) : null;
15062
+ const sizes = args.includes("--sizes") ? readManifestSizes2(resolve34(cwd, outdir ?? "build")) : null;
14830
15063
  const islands = await collectIslands(cwd, config, sizes);
14831
15064
  if (islands === null) {
14832
15065
  printDim6('No island registry configured. Set `islands: { registry: "..." }` in absolute.config.ts.');
@@ -14876,12 +15109,12 @@ var init_islands2 = __esm(() => {
14876
15109
 
14877
15110
  // src/build/externalAssetPlugin.ts
14878
15111
  import { copyFileSync as copyFileSync2, existsSync as existsSync40, mkdirSync as mkdirSync17, statSync as statSync6 } from "fs";
14879
- import { basename as basename11, dirname as dirname26, join as join43, resolve as resolve34 } from "path";
15112
+ import { basename as basename11, dirname as dirname26, join as join44, resolve as resolve35 } from "path";
14880
15113
  var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
14881
15114
  name: "absolute-external-asset",
14882
15115
  setup(bld) {
14883
15116
  const urlPattern = /new\s+URL\(\s*["'](\.\.?\/[^"']+)["']\s*,\s*import\.meta\.url\s*\)/g;
14884
- const skipRoots = userSourceRoots.map((root) => resolve34(root));
15117
+ const skipRoots = userSourceRoots.map((root) => resolve35(root));
14885
15118
  const isUserSource = (path) => skipRoots.some((root) => path.startsWith(`${root}/`));
14886
15119
  bld.onLoad({ filter: /\.[mc]?[jt]sx?$/ }, async (args) => {
14887
15120
  if (isUserSource(args.path))
@@ -14896,12 +15129,12 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
14896
15129
  const relPath = match[1];
14897
15130
  if (!relPath)
14898
15131
  continue;
14899
- const assetPath = resolve34(sourceDir, relPath);
15132
+ const assetPath = resolve35(sourceDir, relPath);
14900
15133
  if (!existsSync40(assetPath))
14901
15134
  continue;
14902
15135
  if (!statSync6(assetPath).isFile())
14903
15136
  continue;
14904
- const targetPath = join43(outDir, basename11(assetPath));
15137
+ const targetPath = join44(outDir, basename11(assetPath));
14905
15138
  if (existsSync40(targetPath))
14906
15139
  continue;
14907
15140
  mkdirSync17(dirname26(targetPath), { recursive: true });
@@ -14925,7 +15158,7 @@ import {
14925
15158
  existsSync as existsSync41,
14926
15159
  mkdirSync as mkdirSync18,
14927
15160
  readdirSync as readdirSync7,
14928
- readFileSync as readFileSync38,
15161
+ readFileSync as readFileSync39,
14929
15162
  rmSync as rmSync7,
14930
15163
  statSync as statSync7,
14931
15164
  unlinkSync as unlinkSync4,
@@ -14936,9 +15169,9 @@ import {
14936
15169
  basename as basename12,
14937
15170
  dirname as dirname27,
14938
15171
  isAbsolute as isAbsolute6,
14939
- join as join44,
14940
- relative as relative22,
14941
- resolve as resolve35
15172
+ join as join45,
15173
+ relative as relative23,
15174
+ resolve as resolve36
14942
15175
  } from "path";
14943
15176
  var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, compileBanner = (version2) => {
14944
15177
  const resolvedVersion = version2 || "unknown";
@@ -14952,7 +15185,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
14952
15185
  const entry = pending.pop();
14953
15186
  if (!entry)
14954
15187
  continue;
14955
- const fullPath = join44(entry.parentPath, entry.name);
15188
+ const fullPath = join45(entry.parentPath, entry.name);
14956
15189
  if (entry.isDirectory())
14957
15190
  pending = pending.concat(readdirSync7(fullPath, { withFileTypes: true }));
14958
15191
  else
@@ -14960,7 +15193,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
14960
15193
  }
14961
15194
  return result;
14962
15195
  }, INLINE_SOURCE_MAP_RE, rebaseInlineSourceMap = (filePath) => {
14963
- const source = readFileSync38(filePath, "utf-8");
15196
+ const source = readFileSync39(filePath, "utf-8");
14964
15197
  const match = source.match(INLINE_SOURCE_MAP_RE);
14965
15198
  const encoded = match?.[1];
14966
15199
  if (!encoded)
@@ -14980,7 +15213,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
14980
15213
  if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(sourceRoot)) {
14981
15214
  return new URL(entry, sourceRoot).href;
14982
15215
  }
14983
- return resolve35(bundleDirectory, sourceRoot, entry);
15216
+ return resolve36(bundleDirectory, sourceRoot, entry);
14984
15217
  });
14985
15218
  delete map.sourceRoot;
14986
15219
  const rebased = Buffer.from(JSON.stringify(map)).toString("base64");
@@ -14998,7 +15231,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
14998
15231
  const entry = pending.pop();
14999
15232
  if (!entry)
15000
15233
  continue;
15001
- const fullPath = join44(entry.parentPath, entry.name);
15234
+ const fullPath = join45(entry.parentPath, entry.name);
15002
15235
  if (entry.isDirectory()) {
15003
15236
  if (SERVER_RUNTIME_SCAN_SKIP_DIRS.has(entry.name))
15004
15237
  continue;
@@ -15010,12 +15243,12 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15010
15243
  return result;
15011
15244
  }, copyServerRuntimeAssetReferences = (outdir) => {
15012
15245
  const copied = new Set;
15013
- const normalizedOutdir = resolve35(outdir);
15246
+ const normalizedOutdir = resolve36(outdir);
15014
15247
  const copyReference = (filePath, relPath) => {
15015
- const assetSource = resolve35(dirname27(filePath), relPath);
15248
+ const assetSource = resolve36(dirname27(filePath), relPath);
15016
15249
  if (!existsSync41(assetSource) || !statSync7(assetSource).isFile())
15017
15250
  return;
15018
- const assetTarget = resolve35(normalizedOutdir, relPath.replace(/^\.\//, ""));
15251
+ const assetTarget = resolve36(normalizedOutdir, relPath.replace(/^\.\//, ""));
15019
15252
  if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
15020
15253
  return;
15021
15254
  if (copied.has(assetTarget))
@@ -15025,7 +15258,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15025
15258
  cpSync(assetSource, assetTarget, { force: true });
15026
15259
  };
15027
15260
  for (const filePath of collectProjectSourceFiles(process.cwd())) {
15028
- const source = readFileSync38(filePath, "utf-8");
15261
+ const source = readFileSync39(filePath, "utf-8");
15029
15262
  SERVER_RUNTIME_ASSET_RE.lastIndex = 0;
15030
15263
  let match;
15031
15264
  while ((match = SERVER_RUNTIME_ASSET_RE.exec(source)) !== null) {
@@ -15054,7 +15287,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15054
15287
  }
15055
15288
  }, readPackageVersion4 = (candidate) => {
15056
15289
  try {
15057
- const pkg = JSON.parse(readFileSync38(candidate, "utf-8"));
15290
+ const pkg = JSON.parse(readFileSync39(candidate, "utf-8"));
15058
15291
  if (pkg.name !== "@absolutejs/absolute")
15059
15292
  return null;
15060
15293
  const ver = pkg.version;
@@ -15089,18 +15322,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15089
15322
  return resolveBuildModule3(remaining);
15090
15323
  }, resolveJsxDevRuntimeCompatPath2 = () => {
15091
15324
  const candidates = [
15092
- resolve35(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
15093
- resolve35(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
15094
- resolve35(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
15095
- resolve35(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
15096
- resolve35(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
15097
- resolve35(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
15325
+ resolve36(import.meta.dir, "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
15326
+ resolve36(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js"),
15327
+ resolve36(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.ts"),
15328
+ resolve36(import.meta.dir, "..", "..", "..", "dist", "react", "jsxDevRuntimeCompat.js"),
15329
+ resolve36(import.meta.dir, "..", "..", "..", "react", "jsxDevRuntimeCompat.js"),
15330
+ resolve36(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
15098
15331
  ];
15099
15332
  for (const candidate of candidates) {
15100
15333
  if (existsSync41(candidate))
15101
15334
  return candidate;
15102
15335
  }
15103
- return resolve35(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
15336
+ return resolve36(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
15104
15337
  }, jsxDevRuntimeCompatPath2, shouldEmbedCompiledAsset = (relativePath, skip = new Set) => {
15105
15338
  if (skip.has(relativePath))
15106
15339
  return false;
@@ -15125,7 +15358,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15125
15358
  return true;
15126
15359
  }), requireForCompile, resolveNativeAssetForRuntime = (specifier) => {
15127
15360
  if (specifier.startsWith("."))
15128
- return resolve35(process.cwd(), specifier);
15361
+ return resolve36(process.cwd(), specifier);
15129
15362
  if (specifier.startsWith("/"))
15130
15363
  return specifier;
15131
15364
  return requireForCompile.resolve(specifier, { paths: [process.cwd()] });
@@ -15137,11 +15370,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15137
15370
  return nativeAssetEnv;
15138
15371
  }, tryReadNodePackageJson = (packageDir) => {
15139
15372
  try {
15140
- return JSON.parse(readFileSync38(join44(packageDir, "package.json"), "utf-8"));
15373
+ return JSON.parse(readFileSync39(join45(packageDir, "package.json"), "utf-8"));
15141
15374
  } catch {
15142
15375
  return null;
15143
15376
  }
15144
- }, resolveProjectPackageDir = (specifier) => resolve35(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
15377
+ }, resolveProjectPackageDir = (specifier) => resolve36(process.cwd(), "node_modules", ...specifier.split("/")), copyPackageToBuild = (specifier, outdir, seen) => {
15145
15378
  if (seen.has(specifier))
15146
15379
  return;
15147
15380
  const srcDir = resolveProjectPackageDir(specifier);
@@ -15149,13 +15382,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15149
15382
  if (!pkg)
15150
15383
  return;
15151
15384
  seen.add(specifier);
15152
- const destDir = join44(outdir, "node_modules", ...specifier.split("/"));
15385
+ const destDir = join45(outdir, "node_modules", ...specifier.split("/"));
15153
15386
  rmSync7(destDir, { force: true, recursive: true });
15154
15387
  cpSync(srcDir, destDir, {
15155
15388
  force: true,
15156
15389
  recursive: true,
15157
15390
  filter(source) {
15158
- const rel = relative22(srcDir, source);
15391
+ const rel = relative23(srcDir, source);
15159
15392
  const [firstSegment] = rel.split(/[\\/]/);
15160
15393
  return firstSegment !== "node_modules" && firstSegment !== ".git";
15161
15394
  }
@@ -15171,7 +15404,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15171
15404
  }, copyAngularRuntimePackages = (buildConfig, outdir) => {
15172
15405
  if (!buildConfig.angularDirectory)
15173
15406
  return;
15174
- const angularScopeDir = resolve35(process.cwd(), "node_modules", "@angular");
15407
+ const angularScopeDir = resolve36(process.cwd(), "node_modules", "@angular");
15175
15408
  const angularPackages = existsSync41(angularScopeDir) ? readdirSync7(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
15176
15409
  const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
15177
15410
  const seen = new Set;
@@ -15190,7 +15423,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15190
15423
  copyAngularRuntimePackages(buildConfig, outdir);
15191
15424
  copyChunkReferencedPackages(outdir, seen);
15192
15425
  }, collectRuntimePackageSpecifiers = (distDir) => {
15193
- const nodeModulesDir = join44(distDir, "node_modules");
15426
+ const nodeModulesDir = join45(distDir, "node_modules");
15194
15427
  if (!existsSync41(nodeModulesDir))
15195
15428
  return [];
15196
15429
  const specifiers = [];
@@ -15198,7 +15431,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15198
15431
  if (!entry.isDirectory())
15199
15432
  continue;
15200
15433
  if (entry.name.startsWith("@")) {
15201
- const scopeDir = join44(nodeModulesDir, entry.name);
15434
+ const scopeDir = join45(nodeModulesDir, entry.name);
15202
15435
  for (const scopedEntry of readdirSync7(scopeDir, {
15203
15436
  withFileTypes: true
15204
15437
  })) {
@@ -15212,7 +15445,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15212
15445
  }
15213
15446
  return specifiers.sort((firstSpecifier, secondSpecifier) => secondSpecifier.length - firstSpecifier.length);
15214
15447
  }, ensureRelativeModuleSpecifier = (fromFile, toFile) => {
15215
- const rel = relative22(dirname27(fromFile), toFile).replace(/\\/g, "/");
15448
+ const rel = relative23(dirname27(fromFile), toFile).replace(/\\/g, "/");
15216
15449
  return rel.startsWith(".") ? rel : `./${rel}`;
15217
15450
  }, pickExportEntry = (value) => {
15218
15451
  if (typeof value === "string")
@@ -15229,18 +15462,18 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15229
15462
  const packageSpecifier = packageSpecifiers.find((root) => specifier === root || specifier.startsWith(`${root}/`));
15230
15463
  if (!packageSpecifier)
15231
15464
  return null;
15232
- const packageDir = join44(distDir, "node_modules", ...packageSpecifier.split("/"));
15465
+ const packageDir = join45(distDir, "node_modules", ...packageSpecifier.split("/"));
15233
15466
  const subpath = specifier.slice(packageSpecifier.length);
15234
- const subPackageDir = subpath ? join44(packageDir, ...subpath.slice(1).split("/")) : null;
15235
- const resolvedPackageDir = subPackageDir && existsSync41(join44(subPackageDir, "package.json")) ? subPackageDir : packageDir;
15236
- const packageJsonPath = join44(resolvedPackageDir, "package.json");
15467
+ const subPackageDir = subpath ? join45(packageDir, ...subpath.slice(1).split("/")) : null;
15468
+ const resolvedPackageDir = subPackageDir && existsSync41(join45(subPackageDir, "package.json")) ? subPackageDir : packageDir;
15469
+ const packageJsonPath = join45(resolvedPackageDir, "package.json");
15237
15470
  if (!existsSync41(packageJsonPath))
15238
15471
  return null;
15239
- const pkg = JSON.parse(readFileSync38(packageJsonPath, "utf-8"));
15472
+ const pkg = JSON.parse(readFileSync39(packageJsonPath, "utf-8"));
15240
15473
  const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
15241
15474
  const rootExport = pkg.exports?.[exportKey];
15242
15475
  const entry = pickExportEntry(rootExport) ?? (resolvedPackageDir === subPackageDir || !subpath ? pkg.module ?? pkg.main ?? "index.js" : `.${subpath}`);
15243
- return join44(resolvedPackageDir, entry);
15476
+ return join45(resolvedPackageDir, entry);
15244
15477
  }, RUNTIME_JS_EXTENSIONS, MODULE_SPECIFIER_RE, isRuntimeJsFile = (filePath) => RUNTIME_JS_EXTENSIONS.some((extension) => filePath.endsWith(extension)), isNodeModulesPath = (filePath) => filePath.split(/[\\/]/).includes("node_modules"), isFile = (filePath) => {
15245
15478
  try {
15246
15479
  return statSync7(filePath).isFile();
@@ -15253,13 +15486,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15253
15486
  const candidates = [
15254
15487
  candidate,
15255
15488
  ...RUNTIME_JS_EXTENSIONS.map((extension) => `${candidate}${extension}`),
15256
- ...RUNTIME_JS_EXTENSIONS.map((extension) => join44(candidate, `index${extension}`))
15489
+ ...RUNTIME_JS_EXTENSIONS.map((extension) => join45(candidate, `index${extension}`))
15257
15490
  ];
15258
15491
  return candidates.find((filePath) => isRuntimeJsFile(filePath) && isFile(filePath)) ?? null;
15259
15492
  }, findContainingRuntimePackageDir = (filePath) => {
15260
15493
  let dir = dirname27(filePath);
15261
15494
  while (dir !== dirname27(dir)) {
15262
- if (isNodeModulesPath(dir) && existsSync41(join44(dir, "package.json"))) {
15495
+ if (isNodeModulesPath(dir) && existsSync41(join45(dir, "package.json"))) {
15263
15496
  return dir;
15264
15497
  }
15265
15498
  dir = dirname27(dir);
@@ -15275,13 +15508,13 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15275
15508
  const entry = pickExportEntry(pkg?.imports?.[specifier]);
15276
15509
  if (!entry)
15277
15510
  return null;
15278
- return join44(packageDir, entry);
15511
+ return join45(packageDir, entry);
15279
15512
  }, collectRuntimeRewriteRoots = (distDir) => collectFiles2(distDir).filter((filePath) => isRuntimeJsFile(filePath) && !isNodeModulesPath(filePath)), toTopLevelPackage = (specifier) => specifier.split("/").slice(0, specifier.startsWith("@") ? 2 : 1).join("/"), FRAMEWORK_PACKAGE_NAME = "@absolutejs/absolute", copyChunkReferencedPackages = (distDir, seen) => {
15280
- const distRoot = resolve35(distDir);
15513
+ const distRoot = resolve36(distDir);
15281
15514
  for (const filePath of collectRuntimeRewriteRoots(distDir)) {
15282
- if (resolve35(dirname27(filePath)) === distRoot)
15515
+ if (resolve36(dirname27(filePath)) === distRoot)
15283
15516
  continue;
15284
- const source = readFileSync38(filePath, "utf-8");
15517
+ const source = readFileSync39(filePath, "utf-8");
15285
15518
  for (const match of source.matchAll(MODULE_SPECIFIER_RE)) {
15286
15519
  const [, , , specifier] = match;
15287
15520
  if (!specifier || specifier.startsWith(".") || specifier.startsWith("/") || specifier.startsWith("#") || specifier.startsWith("node:") || specifier.startsWith("bun:")) {
@@ -15311,11 +15544,11 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15311
15544
  if (!filePath || seen.has(filePath))
15312
15545
  continue;
15313
15546
  seen.add(filePath);
15314
- const source = readFileSync38(filePath, "utf-8");
15547
+ const source = readFileSync39(filePath, "utf-8");
15315
15548
  const { masked, restore } = maskLiterals(source);
15316
15549
  const rewrittenMasked = masked.replace(MODULE_SPECIFIER_RE, (match, prefix, quote, specifier) => {
15317
15550
  if (typeof specifier === "string" && specifier.startsWith(".")) {
15318
- enqueue(resolveRuntimeJsFile(resolve35(dirname27(filePath), specifier)));
15551
+ enqueue(resolveRuntimeJsFile(resolve36(dirname27(filePath), specifier)));
15319
15552
  return match;
15320
15553
  }
15321
15554
  const packageImportTarget = resolveRuntimeJsFile(resolvePackageImportEntryFile(filePath, specifier) ?? "");
@@ -15344,12 +15577,12 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15344
15577
  "_compile_entrypoint.ts"
15345
15578
  ]);
15346
15579
  const embeddedFiles = allFiles.filter((file) => {
15347
- const rel = relative22(distDir, file);
15580
+ const rel = relative23(distDir, file);
15348
15581
  if (embeddedSkip.has(rel))
15349
15582
  return false;
15350
15583
  return true;
15351
15584
  });
15352
- const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative22(distDir, file), assetSkip));
15585
+ const clientFiles = embeddedFiles.filter((file) => shouldEmbedCompiledAsset(relative23(distDir, file), assetSkip));
15353
15586
  const imports = [];
15354
15587
  const nativeImports = [];
15355
15588
  const nativeMappings = [];
@@ -15359,19 +15592,19 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15359
15592
  const nativeAssets = resolveCompileNativeAssets(buildConfig);
15360
15593
  nativeAssets.forEach((asset, idx) => {
15361
15594
  const varName = `__native${idx}`;
15362
- const importSpecifier = asset.import.startsWith(".") ? resolve35(process.cwd(), asset.import) : asset.import;
15595
+ const importSpecifier = asset.import.startsWith(".") ? resolve36(process.cwd(), asset.import) : asset.import;
15363
15596
  nativeImports.push(`import ${varName} from ${JSON.stringify(importSpecifier)} with { type: "file" };`);
15364
15597
  nativeMappings.push(` [${JSON.stringify(asset.env)}, resolveNativeAssetPath(${varName})],`);
15365
15598
  });
15366
15599
  embeddedFiles.forEach((filePath, idx) => {
15367
- const rel = relative22(distDir, filePath).replace(/\\/g, "/");
15600
+ const rel = relative23(distDir, filePath).replace(/\\/g, "/");
15368
15601
  const varName = `__a${idx}`;
15369
15602
  embeddedVarMap.set(rel, varName);
15370
15603
  imports.push(`import ${varName} from "./${rel}" with { type: "file" };`);
15371
15604
  embeddedMappings.push(` ["${rel}", ${varName}],`);
15372
15605
  });
15373
15606
  clientFiles.forEach((filePath) => {
15374
- const rel = relative22(distDir, filePath).replace(/\\/g, "/");
15607
+ const rel = relative23(distDir, filePath).replace(/\\/g, "/");
15375
15608
  const varName = embeddedVarMap.get(rel);
15376
15609
  if (!varName)
15377
15610
  return;
@@ -15385,7 +15618,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
15385
15618
  const pageVarMap = new Map;
15386
15619
  const prerenderEntries = Array.from(prerenderMap.entries());
15387
15620
  prerenderEntries.forEach(([route, filePath]) => {
15388
- const rel = relative22(distDir, filePath).replace(/\\/g, "/");
15621
+ const rel = relative23(distDir, filePath).replace(/\\/g, "/");
15389
15622
  const varName = embeddedVarMap.get(rel);
15390
15623
  if (varName)
15391
15624
  pageVarMap.set(route, varName);
@@ -15418,7 +15651,7 @@ import { buildGlobalWSHandler } from "elysia/ws";
15418
15651
  const SERVER_MODULE = (runtimeDir: string) => import(pathToFileURL(join(runtimeDir, ${JSON.stringify(serverBundleName)})).href);
15419
15652
  const RUNTIME_BUILD_ID = ${JSON.stringify(runtimeBuildId)};
15420
15653
  const RUNTIME_CONFIG_SOURCE = ${JSON.stringify(runtimeConfigSource)};
15421
- const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve35(distDir))};
15654
+ const ORIGINAL_BUILD_DIR = ${JSON.stringify(resolve36(distDir))};
15422
15655
  const ORIGINAL_BUILD_DIR_NORMALIZED = ORIGINAL_BUILD_DIR.replace(/\\\\/g, "/");
15423
15656
  const EMBEDDED_NATIVE_AUTH_CLIENTS = ${JSON.stringify(process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV])};
15424
15657
 
@@ -15831,25 +16064,25 @@ console.log(\`
15831
16064
  const normalizedPath = args.path.replace(/\\/g, "/");
15832
16065
  if (normalizedPath.includes("/src/angular/"))
15833
16066
  return;
15834
- const text = await Bun.file(args.path).text();
15835
- if (text.includes("@Component") && stripStringsAndComments(text).includes("@Component")) {
16067
+ const text2 = await Bun.file(args.path).text();
16068
+ if (text2.includes("@Component") && stripStringsAndComments(text2).includes("@Component")) {
15836
16069
  return { contents: "export default {}", loader: "js" };
15837
16070
  }
15838
16071
  return;
15839
16072
  });
15840
16073
  }
15841
16074
  }), compile = async (serverEntry, outdir, outfile, configPath2) => {
15842
- const resolvedOutdir = resolve35(outdir ?? "dist");
16075
+ const resolvedOutdir = resolve36(outdir ?? "dist");
15843
16076
  await withBuildDirectoryLock(resolvedOutdir, () => compileUnlocked(serverEntry, resolvedOutdir, outfile, configPath2));
15844
16077
  }, compileUnlocked = async (serverEntry, resolvedOutdir, outfile, configPath2) => {
15845
16078
  const configuredPrerenderPort = env5.COMPILE_PORT === undefined ? Number(env5.PORT) : Number(env5.COMPILE_PORT);
15846
16079
  const prerenderPort = configuredPrerenderPort > 0 ? configuredPrerenderPort : await findFreePort();
15847
16080
  killStaleProcesses(prerenderPort);
15848
16081
  const entryName = basename12(serverEntry).replace(/\.[^.]+$/, "");
15849
- const resolvedOutfile = resolve35(outfile ?? "compiled-server");
16082
+ const resolvedOutfile = resolve36(outfile ?? "compiled-server");
15850
16083
  const absoluteVersion = resolvePackageVersion3([
15851
- resolve35(import.meta.dir, "..", "..", "..", "package.json"),
15852
- resolve35(import.meta.dir, "..", "..", "package.json")
16084
+ resolve36(import.meta.dir, "..", "..", "..", "package.json"),
16085
+ resolve36(import.meta.dir, "..", "..", "package.json")
15853
16086
  ]);
15854
16087
  compileBanner(absoluteVersion);
15855
16088
  const totalStart = performance.now();
@@ -15862,8 +16095,8 @@ console.log(\`
15862
16095
  installAbsoluteMobileAuthEnvironment(process.cwd(), normalizeAbsoluteMobileConfig(buildConfig.mobile, process.cwd()));
15863
16096
  try {
15864
16097
  const build2 = await resolveBuildModule3([
15865
- resolve35(import.meta.dir, "..", "..", "core", "build"),
15866
- resolve35(import.meta.dir, "..", "build")
16098
+ resolve36(import.meta.dir, "..", "..", "core", "build"),
16099
+ resolve36(import.meta.dir, "..", "build")
15867
16100
  ]);
15868
16101
  if (!build2)
15869
16102
  throw new Error("Could not locate build module");
@@ -15885,11 +16118,11 @@ console.log(\`
15885
16118
  buildConfig.htmxDirectory
15886
16119
  ].filter((dir) => Boolean(dir));
15887
16120
  const islandRegistrySpec = buildConfig.islands?.registry;
15888
- const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve35(islandRegistrySpec))) : undefined;
15889
- const serverBundleEntryDirectory = join44(resolvedOutdir, ".absolutejs-server-entry");
16121
+ const islandRegistryPlugin = islandRegistrySpec ? createIslandRegistryDefinitionPlugin(await loadIslandRegistryBuildInfo(resolve36(islandRegistrySpec))) : undefined;
16122
+ const serverBundleEntryDirectory = join45(resolvedOutdir, ".absolutejs-server-entry");
15890
16123
  mkdirSync18(serverBundleEntryDirectory, { recursive: true });
15891
- const typeboxSetupEntry = join44(serverBundleEntryDirectory, "_typebox_setup.ts");
15892
- const serverBundleEntry = join44(serverBundleEntryDirectory, basename12(serverEntry));
16124
+ const typeboxSetupEntry = join45(serverBundleEntryDirectory, "_typebox_setup.ts");
16125
+ const serverBundleEntry = join45(serverBundleEntryDirectory, basename12(serverEntry));
15893
16126
  writeFileSync21(typeboxSetupEntry, `import { setupTypebox } from 'elysia';
15894
16127
  import * as compile from 'typebox/compile';
15895
16128
  import * as schema from 'typebox/schema';
@@ -15900,7 +16133,7 @@ import * as value from 'typebox/value';
15900
16133
  setupTypebox({ typebox: { compile, schema, system, type, value } });
15901
16134
  `);
15902
16135
  writeFileSync21(serverBundleEntry, `import './_typebox_setup';
15903
- import * as serverModule from ${JSON.stringify(resolve35(serverEntry))};
16136
+ import * as serverModule from ${JSON.stringify(resolve36(serverEntry))};
15904
16137
 
15905
16138
  export const server = serverModule.server ?? serverModule.app ?? serverModule.default;
15906
16139
  export default server;
@@ -15914,7 +16147,7 @@ export default server;
15914
16147
  ...islandRegistryPlugin ? [islandRegistryPlugin] : [],
15915
16148
  ...buildConfig.mobile ? [
15916
16149
  createAbsoluteMobileRouteMetadataPlugin({
15917
- entry: resolve35(serverEntry)
16150
+ entry: resolve36(serverEntry)
15918
16151
  })
15919
16152
  ] : [],
15920
16153
  createElysiaOpenApiTypeboxPlugin(),
@@ -15938,13 +16171,13 @@ export default server;
15938
16171
  console.error(cliTag4("\x1B[31m", "Server bundle failed."));
15939
16172
  process.exit(1);
15940
16173
  }
15941
- const outputPath = resolve35(resolvedOutdir, `${entryName}.js`);
16174
+ const outputPath = resolve36(resolvedOutdir, `${entryName}.js`);
15942
16175
  if (!existsSync41(outputPath)) {
15943
16176
  console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
15944
16177
  process.exit(1);
15945
16178
  }
15946
- if (existsSync41(resolve35(resolvedOutdir, "angular", "vendor", "server"))) {
15947
- const vendorDir = resolve35(resolvedOutdir, "angular", "vendor", "server");
16179
+ if (existsSync41(resolve36(resolvedOutdir, "angular", "vendor", "server"))) {
16180
+ const vendorDir = resolve36(resolvedOutdir, "angular", "vendor", "server");
15948
16181
  const vendorEntries = readdirSync7(vendorDir).filter((fileName) => fileName.endsWith(".js"));
15949
16182
  const angularServerVendorPaths = {};
15950
16183
  for (const file of vendorEntries) {
@@ -15953,7 +16186,7 @@ export default server;
15953
16186
  if (scope !== "angular" || rest.length === 0)
15954
16187
  continue;
15955
16188
  const specifier = `@angular/${rest.join("/")}`;
15956
- const relPath = relative22(dirname27(outputPath), resolve35(vendorDir, file));
16189
+ const relPath = relative23(dirname27(outputPath), resolve36(vendorDir, file));
15957
16190
  angularServerVendorPaths[specifier] = relPath.startsWith(".") ? relPath : `./${relPath}`;
15958
16191
  }
15959
16192
  if (Object.keys(angularServerVendorPaths).length > 0) {
@@ -15965,7 +16198,7 @@ export default server;
15965
16198
  copyServerRuntimeAssetReferences(resolvedOutdir);
15966
16199
  const prerenderStart = performance.now();
15967
16200
  process.stdout.write(cliTag4("\x1B[36m", "Pre-rendering pages"));
15968
- rmSync7(join44(resolvedOutdir, "_prerendered"), {
16201
+ rmSync7(join45(resolvedOutdir, "_prerendered"), {
15969
16202
  force: true,
15970
16203
  recursive: true
15971
16204
  });
@@ -15995,7 +16228,7 @@ export default server;
15995
16228
  const compileStart = performance.now();
15996
16229
  process.stdout.write(cliTag4("\x1B[36m", "Compiling standalone executable"));
15997
16230
  const entrypointCode = generateEntrypoint(resolvedOutdir, serverEntry, prerenderMap, absoluteVersion, buildConfig);
15998
- const entrypointPath = join44(resolvedOutdir, "_compile_entrypoint.ts");
16231
+ const entrypointPath = join45(resolvedOutdir, "_compile_entrypoint.ts");
15999
16232
  await Bun.write(entrypointPath, entrypointCode);
16000
16233
  mkdirSync18(dirname27(resolvedOutfile), { recursive: true });
16001
16234
  const result = await Bun.build({
@@ -16081,7 +16314,7 @@ var init_compile = __esm(() => {
16081
16314
 
16082
16315
  // src/mobile/nativeDeepLinks.ts
16083
16316
  import { readFile as readFile11, rename as rename8, writeFile as writeFile9 } from "fs/promises";
16084
- import { join as join45 } from "path";
16317
+ import { join as join46 } from "path";
16085
16318
  var START_MARKER = "<!-- absolutejs:deep-links:start -->", END_MARKER = "<!-- absolutejs:deep-links:end -->", IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements", NOT_FOUND = -1, escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;"), writeChangedFile = async (path, source) => {
16086
16319
  const current = await readFile11(path, "utf8");
16087
16320
  if (current === source)
@@ -16130,7 +16363,7 @@ ${hosts}
16130
16363
  ${END_MARKER}
16131
16364
  `;
16132
16365
  }, configureAndroid = async (config) => {
16133
- const path = join45(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
16366
+ const path = join46(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
16134
16367
  const source = await readFile11(path, "utf8");
16135
16368
  const mainActivity = source.indexOf('android:name=".MainActivity"');
16136
16369
  if (mainActivity === NOT_FOUND) {
@@ -16154,7 +16387,7 @@ ${hosts}
16154
16387
  </array>
16155
16388
  ${END_MARKER}
16156
16389
  `, configureIosInfo = async (config) => {
16157
- const path = join45(config.nativeProjectDirectory, "ios/App/App/Info.plist");
16390
+ const path = join46(config.nativeProjectDirectory, "ios/App/App/Info.plist");
16158
16391
  const source = await readFile11(path, "utf8");
16159
16392
  const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
16160
16393
  ${END_MARKER}
@@ -16176,7 +16409,7 @@ ${domains}
16176
16409
  </plist>
16177
16410
  `;
16178
16411
  }, configureIosEntitlements = async (config) => {
16179
- const path = join45(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
16412
+ const path = join46(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
16180
16413
  let current = "";
16181
16414
  try {
16182
16415
  current = await readFile11(path, "utf8");
@@ -16193,7 +16426,7 @@ ${domains}
16193
16426
  await rename8(temporary, path);
16194
16427
  return true;
16195
16428
  }, configureIosProject = async (config) => {
16196
- const path = join45(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
16429
+ const path = join46(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
16197
16430
  const source = await readFile11(path, "utf8");
16198
16431
  const declarations = [
16199
16432
  ...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
@@ -16231,10 +16464,10 @@ ${domains}
16231
16464
  };
16232
16465
  var init_nativeDeepLinks = () => {};
16233
16466
 
16234
- // src/mobile/nativeBackgroundSync.ts
16467
+ // src/mobile/nativeDeviceCapabilities.ts
16235
16468
  import { readFile as readFile12, rename as rename9, writeFile as writeFile10 } from "fs/promises";
16236
- import { join as join46 } from "path";
16237
- var writeChanged = async (path, source) => {
16469
+ import { join as join47 } from "path";
16470
+ var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->", END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->", NOT_FOUND2 = -1, escapeXml2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&apos;").replaceAll("<", "&lt;").replaceAll(">", "&gt;"), writeChangedFile2 = async (path, source) => {
16238
16471
  const current = await readFile12(path, "utf8");
16239
16472
  if (current === source)
16240
16473
  return false;
@@ -16242,6 +16475,85 @@ var writeChanged = async (path, source) => {
16242
16475
  await writeFile10(temporary, source, { flag: "wx" });
16243
16476
  await rename9(temporary, path);
16244
16477
  return true;
16478
+ }, managed = (source, region, insertion) => {
16479
+ const start2 = source.indexOf(START_MARKER2);
16480
+ const end = source.indexOf(END_MARKER2);
16481
+ if (start2 === NOT_FOUND2 !== (end === NOT_FOUND2) || start2 !== NOT_FOUND2 && end < start2)
16482
+ throw new TypeError("AbsoluteJS device-capability ownership markers are malformed.");
16483
+ if (start2 !== NOT_FOUND2) {
16484
+ const lineStart = source.lastIndexOf(`
16485
+ `, start2) + 1;
16486
+ const nextLine = source.indexOf(`
16487
+ `, end + END_MARKER2.length);
16488
+ const lineEnd = nextLine === NOT_FOUND2 ? source.length : nextLine + 1;
16489
+ return `${source.slice(0, lineStart)}${region}${source.slice(lineEnd)}`;
16490
+ }
16491
+ if (region.length === 0)
16492
+ return source;
16493
+ if (insertion === NOT_FOUND2)
16494
+ throw new TypeError("Could not find a safe native project location for device permissions.");
16495
+ return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
16496
+ }, IOS_KEYS, iosDescription = (appName, purpose) => {
16497
+ if (purpose === "camera")
16498
+ return `${appName} uses your camera when you choose to take a photo.`;
16499
+ if (purpose === "photo-library")
16500
+ return `${appName} accesses your photo library only for photo actions you choose.`;
16501
+ return `${appName} adds to your photo library only for photo actions you choose.`;
16502
+ }, configureIos2 = async (config, plan) => {
16503
+ const path = join47(config.nativeProjectDirectory, "ios/App/App/Info.plist");
16504
+ const source = await readFile12(path, "utf8");
16505
+ const requirements = absoluteDeviceNativeRequirements(plan);
16506
+ const content = requirements.iosUsageDescriptions.map((purpose) => ` <key>${IOS_KEYS[purpose]}</key>
16507
+ <string>${escapeXml2(iosDescription(config.appName, purpose))}</string>`).join(`
16508
+ `);
16509
+ const region = content ? ` ${START_MARKER2}
16510
+ ${content}
16511
+ ${END_MARKER2}
16512
+ ` : "";
16513
+ return writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
16514
+ }, configureAndroid2 = async (config, plan) => {
16515
+ const path = join47(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
16516
+ const source = await readFile12(path, "utf8");
16517
+ const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
16518
+ const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
16519
+ `);
16520
+ const region = content ? ` ${START_MARKER2}
16521
+ ${content}
16522
+ ${END_MARKER2}
16523
+ ` : "";
16524
+ const application = source.indexOf("<application");
16525
+ const insertion = application === NOT_FOUND2 ? NOT_FOUND2 : source.lastIndexOf(`
16526
+ `, application) + 1;
16527
+ return writeChangedFile2(path, managed(source, region, insertion));
16528
+ }, applyAbsoluteNativeDeviceCapabilities = async (projectRoot, config, platforms = config.platforms, plan = resolveAbsoluteDeviceCapabilityPlan(projectRoot)) => {
16529
+ const results = await Promise.all(platforms.map(async (platform6) => ({
16530
+ didChange: platform6 === "ios" ? await configureIos2(config, plan) : await configureAndroid2(config, plan),
16531
+ platform: platform6
16532
+ })));
16533
+ return {
16534
+ changed: results.filter(({ didChange }) => didChange).map(({ platform: platform6 }) => platform6)
16535
+ };
16536
+ };
16537
+ var init_nativeDeviceCapabilities = __esm(() => {
16538
+ init_deviceCapabilities();
16539
+ IOS_KEYS = {
16540
+ camera: "NSCameraUsageDescription",
16541
+ "photo-library": "NSPhotoLibraryUsageDescription",
16542
+ "photo-library-add": "NSPhotoLibraryAddUsageDescription"
16543
+ };
16544
+ });
16545
+
16546
+ // src/mobile/nativeBackgroundSync.ts
16547
+ import { readFile as readFile13, rename as rename10, writeFile as writeFile11 } from "fs/promises";
16548
+ import { join as join48 } from "path";
16549
+ var writeChanged = async (path, source) => {
16550
+ const current = await readFile13(path, "utf8");
16551
+ if (current === source)
16552
+ return false;
16553
+ const temporary = `${path}.${crypto.randomUUID()}.tmp`;
16554
+ await writeFile11(temporary, source, { flag: "wx" });
16555
+ await rename10(temporary, path);
16556
+ return true;
16245
16557
  }, replaceRegion = (source, start2, end, region, insert) => {
16246
16558
  const existingStart = source.indexOf(start2);
16247
16559
  const existingEnd = source.indexOf(end);
@@ -16316,11 +16628,11 @@ ${makeRegion(values)} </array>
16316
16628
  if (!platforms.includes("ios") || !projectUsesAbsoluteAuth(projectRoot) || !projectUsesAbsoluteSync(projectRoot))
16317
16629
  return { changed: false };
16318
16630
  const identifier = `${config.appId}.absolutejs.background-sync`;
16319
- const infoPath = join46(config.nativeProjectDirectory, "ios/App/App/Info.plist");
16320
- const info2 = await readFile12(infoPath, "utf8");
16631
+ const infoPath = join48(config.nativeProjectDirectory, "ios/App/App/Info.plist");
16632
+ const info2 = await readFile13(infoPath, "utf8");
16321
16633
  const nextInfo = ensurePlistArrayValues(ensurePlistArrayValues(info2, "BGTaskSchedulerPermittedIdentifiers", [identifier], "background-sync-identifiers"), "UIBackgroundModes", ["fetch", "processing"], "background-sync-modes");
16322
- const delegatePath = join46(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
16323
- let delegate = await readFile12(delegatePath, "utf8");
16634
+ const delegatePath = join48(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
16635
+ let delegate = await readFile13(delegatePath, "utf8");
16324
16636
  if (!delegate.includes("import AbsoluteSyncCapacitor")) {
16325
16637
  const importIndex = delegate.lastIndexOf("import Capacitor");
16326
16638
  if (importIndex < 0)
@@ -16354,12 +16666,12 @@ var init_nativeBackgroundSync = __esm(() => {
16354
16666
  import {
16355
16667
  access as access7,
16356
16668
  mkdir as mkdir10,
16357
- readFile as readFile13,
16358
- rename as rename10,
16669
+ readFile as readFile14,
16670
+ rename as rename11,
16359
16671
  rm as rm7,
16360
- writeFile as writeFile11
16672
+ writeFile as writeFile12
16361
16673
  } from "fs/promises";
16362
- import { resolve as resolve36 } from "path";
16674
+ import { resolve as resolve37 } from "path";
16363
16675
  import { Elysia } from "elysia";
16364
16676
  var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERIFY_TIMEOUT_MS = 1e4, ANDROID_ASSOCIATION_PATH = "/.well-known/assetlinks.json", APPLE_ASSOCIATION_PATH = "/.well-known/apple-app-site-association", missingIdentity = (field, platform6) => new TypeError(`${field} is required to publish ${platform6} deep-link association files.`), createAppleDocument = (config, requireAll) => {
16365
16677
  if (!config.platforms.includes("ios"))
@@ -16412,7 +16724,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16412
16724
  }, writeAtomic = async (path, source) => {
16413
16725
  let current;
16414
16726
  try {
16415
- current = await readFile13(path, "utf8");
16727
+ current = await readFile14(path, "utf8");
16416
16728
  } catch (error) {
16417
16729
  if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
16418
16730
  throw error;
@@ -16421,8 +16733,8 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16421
16733
  if (current === source)
16422
16734
  return false;
16423
16735
  const temporary = `${path}.${crypto.randomUUID()}.tmp`;
16424
- await writeFile11(temporary, source, { flag: "wx" });
16425
- await rename10(temporary, path);
16736
+ await writeFile12(temporary, source, { flag: "wx" });
16737
+ await rename11(temporary, path);
16426
16738
  return true;
16427
16739
  }, exists2 = async (path) => {
16428
16740
  try {
@@ -16432,10 +16744,10 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16432
16744
  return false;
16433
16745
  }
16434
16746
  }, assertOwnedOutput = async (root) => {
16435
- const path = resolve36(root, OWNERSHIP_FILE);
16747
+ const path = resolve37(root, OWNERSHIP_FILE);
16436
16748
  let ownership;
16437
16749
  try {
16438
- ownership = JSON.parse(await readFile13(path, "utf8"));
16750
+ ownership = JSON.parse(await readFile14(path, "utf8"));
16439
16751
  } catch {
16440
16752
  throw new TypeError(`Association output ${root} already exists and is not owned by AbsoluteJS.`);
16441
16753
  }
@@ -16448,21 +16760,21 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16448
16760
  await assertOwnedOutput(root);
16449
16761
  const backup = `${root}.${crypto.randomUUID()}.previous`;
16450
16762
  if (hasCurrent)
16451
- await rename10(root, backup);
16763
+ await rename11(root, backup);
16452
16764
  try {
16453
- await rename10(temporary, root);
16765
+ await rename11(temporary, root);
16454
16766
  } catch (error) {
16455
16767
  if (hasCurrent)
16456
- await rename10(backup, root);
16768
+ await rename11(backup, root);
16457
16769
  throw error;
16458
16770
  }
16459
16771
  if (hasCurrent)
16460
16772
  await rm7(backup, { force: true, recursive: true });
16461
16773
  }, materializeHost = async (root, host2, files) => {
16462
- const directory = resolve36(root, host2, ".well-known");
16774
+ const directory = resolve37(root, host2, ".well-known");
16463
16775
  await mkdir10(directory, { recursive: true });
16464
16776
  return Promise.all(files.map(async ([name, document]) => {
16465
- const path = resolve36(directory, name);
16777
+ const path = resolve37(directory, name);
16466
16778
  await writeAtomic(path, `${JSON.stringify(document, null, 2)}
16467
16779
  `);
16468
16780
  return path;
@@ -16485,7 +16797,7 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16485
16797
  });
16486
16798
  return endpoints;
16487
16799
  }), materializeAbsoluteMobileAssociationFiles = async (config, outputDirectory) => {
16488
- const root = resolve36(outputDirectory);
16800
+ const root = resolve37(outputDirectory);
16489
16801
  const temporary = `${root}.${crypto.randomUUID()}.tmp`;
16490
16802
  const documents = createAbsoluteMobileAssociationDocuments(config, {
16491
16803
  requireAll: true
@@ -16499,10 +16811,10 @@ var OWNERSHIP_FILE = ".absolutejs-mobile-associations.json", HTTP_OK = 200, VERI
16499
16811
  await mkdir10(temporary, { recursive: true });
16500
16812
  try {
16501
16813
  const temporaryPaths = (await Promise.all(config.deepLinkHosts.map((host2) => materializeHost(temporary, host2, files)))).flat();
16502
- await writeAtomic(resolve36(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
16814
+ await writeAtomic(resolve37(temporary, OWNERSHIP_FILE), `${JSON.stringify({ format: 1, hosts: config.deepLinkHosts }, null, 2)}
16503
16815
  `);
16504
16816
  await publishGeneratedDirectory(temporary, root);
16505
- const written = temporaryPaths.map((path) => resolve36(root, path.slice(temporary.length + 1)));
16817
+ const written = temporaryPaths.map((path) => resolve37(root, path.slice(temporary.length + 1)));
16506
16818
  return { root, written };
16507
16819
  } catch (error) {
16508
16820
  await rm7(temporary, { force: true, recursive: true });
@@ -16543,8 +16855,8 @@ var init_associationFiles = __esm(() => {
16543
16855
  });
16544
16856
 
16545
16857
  // src/mobile/androidWebView.ts
16546
- import { mkdir as mkdir11, writeFile as writeFile12 } from "fs/promises";
16547
- import { dirname as dirname28, resolve as resolve37 } from "path";
16858
+ import { mkdir as mkdir11, writeFile as writeFile13 } from "fs/promises";
16859
+ import { dirname as dirname28, resolve as resolve38 } from "path";
16548
16860
 
16549
16861
  class CdpConnection {
16550
16862
  diagnostics = [];
@@ -16815,9 +17127,9 @@ var CDP_COMMAND_TIMEOUT_MS = 1e4, WEBVIEW_ATTACH_TIMEOUT_MS = 30000, WEBVIEW_POL
16815
17127
  if (typeof data !== "string") {
16816
17128
  throw new Error("Android WebView screenshot returned no image data.");
16817
17129
  }
16818
- const absolutePath = resolve37(path);
17130
+ const absolutePath = resolve38(path);
16819
17131
  await mkdir11(dirname28(absolutePath), { recursive: true });
16820
- await writeFile12(absolutePath, Buffer.from(data, "base64"));
17132
+ await writeFile13(absolutePath, Buffer.from(data, "base64"));
16821
17133
  return absolutePath;
16822
17134
  }
16823
17135
  };
@@ -16935,8 +17247,8 @@ var DEFAULT_ROUTE_TIMEOUT_MS = 30000, DEFAULT_HMR_TIMEOUT_MS = 30000, routeExpre
16935
17247
  };
16936
17248
 
16937
17249
  // src/mobile/releaseDoctor.ts
16938
- import { access as access8, readFile as readFile14, readdir as readdir4 } from "fs/promises";
16939
- import { extname as extname7, join as join47, relative as relative23 } from "path";
17250
+ import { access as access8, readFile as readFile15, readdir as readdir4 } from "fs/promises";
17251
+ import { extname as extname8, join as join49, relative as relative24 } from "path";
16940
17252
  var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
16941
17253
  try {
16942
17254
  await access8(path);
@@ -16947,15 +17259,15 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
16947
17259
  }, inspectReleaseAsset = async (path, isDirectory, isFile2) => {
16948
17260
  if (isDirectory)
16949
17261
  return findHmrAsset(path);
16950
- if (!isFile2 || !RELEASE_ASSET_EXTENSIONS.has(extname7(path)))
17262
+ if (!isFile2 || !RELEASE_ASSET_EXTENSIONS.has(extname8(path)))
16951
17263
  return;
16952
- const source = await readFile14(path, "utf8");
17264
+ const source = await readFile15(path, "utf8");
16953
17265
  return HMR_ASSET_PATTERN.test(source) ? path : undefined;
16954
17266
  }, findHmrAsset = async (root) => {
16955
17267
  if (!await pathExists5(root))
16956
17268
  return;
16957
17269
  const entries = await readdir4(root, { withFileTypes: true });
16958
- const matches = await Promise.all(entries.map((entry) => inspectReleaseAsset(join47(root, entry.name), entry.isDirectory(), entry.isFile())));
17270
+ const matches = await Promise.all(entries.map((entry) => inspectReleaseAsset(join49(root, entry.name), entry.isDirectory(), entry.isFile())));
16959
17271
  return matches.find((match) => match !== undefined);
16960
17272
  }, pass = (id, detail, path) => ({ detail, id, path, status: "pass" }), fail5 = (id, detail, path, remediation) => ({
16961
17273
  detail,
@@ -16988,13 +17300,13 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
16988
17300
  if (!await pathExists5(nativeConfigPath)) {
16989
17301
  return fail5("android.capacitor-config", "The generated Android Capacitor config is missing.", nativeConfigPath, "Run `absolute mobile sync android` before release validation.");
16990
17302
  }
16991
- const unsafe = isUnsafeCapacitorConfig(await readFile14(nativeConfigPath, "utf8"));
17303
+ const unsafe = isUnsafeCapacitorConfig(await readFile15(nativeConfigPath, "utf8"));
16992
17304
  return unsafe ? fail5("android.capacitor-config", "Android Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.", nativeConfigPath, "Run `absolute mobile sync android`; do not ship development transport overrides.") : pass("android.capacitor-config", "Android Capacitor config contains no development transport overrides.", nativeConfigPath);
16993
17305
  }, manifestReleaseCheck = async (manifestPath) => {
16994
17306
  if (!await pathExists5(manifestPath)) {
16995
17307
  return fail5("android.cleartext", "The Android manifest is missing.", manifestPath, "Run `absolute mobile sync android` before release validation.");
16996
17308
  }
16997
- const source = await readFile14(manifestPath, "utf8");
17309
+ const source = await readFile15(manifestPath, "utf8");
16998
17310
  return /android:usesCleartextTraffic=["']true["']/u.test(source) ? fail5("android.cleartext", "Android explicitly permits cleartext traffic.", manifestPath, 'Remove usesCleartextTraffic="true" from the release manifest.') : pass("android.cleartext", "Android does not explicitly permit cleartext traffic.", manifestPath);
16999
17311
  }, hmrAssetsReleaseCheck = async (publicRoot) => {
17000
17312
  const hmrAsset = await findHmrAsset(publicRoot);
@@ -17002,7 +17314,7 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17002
17314
  }, syncSchemaReleaseCheck = (projectRoot) => {
17003
17315
  if (!projectUsesAbsoluteSync(projectRoot))
17004
17316
  return;
17005
- const manifestPath = join47(projectRoot, "package.json");
17317
+ const manifestPath = join49(projectRoot, "package.json");
17006
17318
  try {
17007
17319
  const schema = discoverAbsoluteSyncSchema(projectRoot);
17008
17320
  const versions = schema.components.map((component2) => `${component2.id}@${component2.version}`).join(", ");
@@ -17021,12 +17333,46 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17021
17333
  } catch (error) {
17022
17334
  return fail5("sync.storage-schema", error instanceof Error ? error.message : "Generated offline schema metadata is invalid.", manifestPath, "Fix absolutejs.sync.localSchema metadata in the named app or package before releasing.");
17023
17335
  }
17336
+ }, IOS_USAGE_KEYS, androidDevicePermissionCheck = async (config, permissions) => {
17337
+ if (!config.platforms.includes("android") || permissions.length === 0)
17338
+ return;
17339
+ const path = join49(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
17340
+ const source = await readFile15(path, "utf8");
17341
+ const missing = permissions.filter((permission) => !source.includes(`android:name="${permission}"`) && !source.includes(`android:name='${permission}'`));
17342
+ if (missing.length === 0)
17343
+ return;
17344
+ return fail5("mobile.device-capabilities", `Android is missing native declarations for: ${missing.join(", ")}.`, path, "Run `absolute mobile sync android` to regenerate detected device permissions.");
17345
+ }, iosDevicePermissionCheck = async (config, purposes) => {
17346
+ if (!config.platforms.includes("ios") || purposes.length === 0)
17347
+ return;
17348
+ const path = join49(config.nativeProjectDirectory, "ios/App/App/Info.plist");
17349
+ const source = await readFile15(path, "utf8");
17350
+ const missing = purposes.filter((purpose) => !source.includes(`<key>${IOS_USAGE_KEYS[purpose]}</key>`));
17351
+ if (missing.length === 0)
17352
+ return;
17353
+ return fail5("mobile.device-capabilities", `iOS is missing usage descriptions for: ${missing.join(", ")}.`, path, "Run `absolute mobile sync ios` to regenerate detected device usage descriptions.");
17354
+ }, deviceCapabilityReleaseCheck = async (config, projectRoot) => {
17355
+ const manifestPath = join49(projectRoot, "package.json");
17356
+ try {
17357
+ const plan = resolveAbsoluteDeviceCapabilityPlan(projectRoot);
17358
+ assertAbsoluteDeviceCapabilityPackages(projectRoot, plan);
17359
+ const requirements = absoluteDeviceNativeRequirements(plan);
17360
+ const androidCheck = await androidDevicePermissionCheck(config, requirements.androidPermissions);
17361
+ if (androidCheck)
17362
+ return androidCheck;
17363
+ const iosCheck = await iosDevicePermissionCheck(config, requirements.iosUsageDescriptions);
17364
+ if (iosCheck)
17365
+ return iosCheck;
17366
+ return pass("mobile.device-capabilities", plan.capabilities.length > 0 ? `Native provider packages and permission declarations match detected capabilities: ${plan.capabilities.join(", ")}.` : "No optional native device capabilities are used.", manifestPath);
17367
+ } catch (error) {
17368
+ return fail5("mobile.device-capabilities", error instanceof Error ? error.message : "Native device capability provisioning is invalid.", manifestPath, "Run `absolute mobile sync` and approve the exact capability plugins before releasing.");
17369
+ }
17024
17370
  }, inspectAndroidRelease = async (config, projectRoot) => {
17025
- const androidRoot = join47(config.nativeProjectDirectory, "android");
17026
- const nativeConfigPath = join47(androidRoot, "app", "src", "main", "assets", "capacitor.config.json");
17027
- const manifestPath = join47(androidRoot, "app", "src", "main", "AndroidManifest.xml");
17028
- const publicRoot = join47(androidRoot, "app", "src", "main", "assets", "public");
17029
- const journalPath = join47(projectRoot, ".absolutejs", "mobile", "dev-session", "journal.json");
17371
+ const androidRoot = join49(config.nativeProjectDirectory, "android");
17372
+ const nativeConfigPath = join49(androidRoot, "app", "src", "main", "assets", "capacitor.config.json");
17373
+ const manifestPath = join49(androidRoot, "app", "src", "main", "AndroidManifest.xml");
17374
+ const publicRoot = join49(androidRoot, "app", "src", "main", "assets", "public");
17375
+ const journalPath = join49(projectRoot, ".absolutejs", "mobile", "dev-session", "journal.json");
17030
17376
  const checks = await Promise.all([
17031
17377
  journalReleaseCheck(journalPath, "android"),
17032
17378
  capacitorConfigReleaseCheck(nativeConfigPath),
@@ -17035,14 +17381,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17035
17381
  ]);
17036
17382
  return checks.map((check2) => ({
17037
17383
  ...check2,
17038
- path: check2.path ? relative23(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
17384
+ path: check2.path ? relative24(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
17039
17385
  }));
17040
17386
  }, inspectIosRelease = async (config, projectRoot) => {
17041
- const iosAppRoot = join47(config.nativeProjectDirectory, "ios", "App", "App");
17042
- const nativeConfigPath = join47(iosAppRoot, "capacitor.config.json");
17043
- const infoPath = join47(iosAppRoot, "Info.plist");
17044
- const publicRoot = join47(iosAppRoot, "public");
17045
- const journalPath = join47(projectRoot, ".absolutejs", "mobile", "ios-dev-session", "journal.json");
17387
+ const iosAppRoot = join49(config.nativeProjectDirectory, "ios", "App", "App");
17388
+ const nativeConfigPath = join49(iosAppRoot, "capacitor.config.json");
17389
+ const infoPath = join49(iosAppRoot, "Info.plist");
17390
+ const publicRoot = join49(iosAppRoot, "public");
17391
+ const journalPath = join49(projectRoot, ".absolutejs", "mobile", "ios-dev-session", "journal.json");
17046
17392
  const checks = [
17047
17393
  await journalReleaseCheck(journalPath, "ios")
17048
17394
  ];
@@ -17053,7 +17399,7 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17053
17399
  }
17054
17400
  if (!await pathExists5(nativeConfigPath)) {
17055
17401
  checks.push(fail5("ios.capacitor-config", "The generated iOS Capacitor config is missing.", nativeConfigPath, "Run `absolute mobile sync ios` before release validation."));
17056
- } else if (isUnsafeCapacitorConfig(await readFile14(nativeConfigPath, "utf8"))) {
17402
+ } else if (isUnsafeCapacitorConfig(await readFile15(nativeConfigPath, "utf8"))) {
17057
17403
  checks.push(fail5("ios.capacitor-config", "iOS Capacitor config contains a development server URL, cleartext transport, navigation allowlist, or invalid JSON.", nativeConfigPath, "Run `absolute mobile sync ios`; do not ship development transport overrides."));
17058
17404
  } else {
17059
17405
  checks.push(pass("ios.capacitor-config", "iOS Capacitor config contains no development transport overrides.", nativeConfigPath));
@@ -17061,14 +17407,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17061
17407
  if (!await pathExists5(infoPath)) {
17062
17408
  checks.push(fail5("ios.transport-security", "The iOS Info.plist is missing.", infoPath, "Run `absolute mobile sync ios` before release validation."));
17063
17409
  } else {
17064
- const info2 = await readFile14(infoPath, "utf8");
17410
+ const info2 = await readFile15(infoPath, "utf8");
17065
17411
  checks.push(/<key>NSAllowsArbitraryLoads<\/key>\s*<true\s*\/>/u.test(info2) ? fail5("ios.transport-security", "iOS App Transport Security permits arbitrary network loads.", infoPath, "Remove NSAllowsArbitraryLoads from the release Info.plist.") : pass("ios.transport-security", "iOS App Transport Security does not permit arbitrary loads.", infoPath));
17066
17412
  }
17067
17413
  const hmrAsset = await findHmrAsset(publicRoot);
17068
17414
  checks.push(hmrAsset ? fail5("ios.hmr-assets", "A packaged iOS asset contains the development HMR client.", hmrAsset, "Rebuild the production mobile bundle and run Capacitor sync again.") : pass("ios.hmr-assets", "Packaged iOS assets contain no development HMR markers.", publicRoot));
17069
17415
  return checks.map((check2) => ({
17070
17416
  ...check2,
17071
- path: check2.path ? relative23(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
17417
+ path: check2.path ? relative24(projectRoot, check2.path).replaceAll("\\", "/") || "." : undefined
17072
17418
  }));
17073
17419
  }, inspectAbsoluteMobileRelease = async (config, projectRoot) => {
17074
17420
  const checks = config.platforms.includes("android") ? await inspectAndroidRelease(config, projectRoot) : [];
@@ -17079,9 +17425,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17079
17425
  if (syncSchema) {
17080
17426
  checks.push({
17081
17427
  ...syncSchema,
17082
- path: syncSchema.path ? relative23(projectRoot, syncSchema.path).replaceAll("\\", "/") || "." : undefined
17428
+ path: syncSchema.path ? relative24(projectRoot, syncSchema.path).replaceAll("\\", "/") || "." : undefined
17083
17429
  });
17084
17430
  }
17431
+ const deviceCapabilities = await deviceCapabilityReleaseCheck(config, projectRoot);
17432
+ checks.push({
17433
+ ...deviceCapabilities,
17434
+ path: deviceCapabilities.path ? relative24(projectRoot, deviceCapabilities.path).replaceAll("\\", "/") || "." : undefined
17435
+ });
17085
17436
  return {
17086
17437
  checks,
17087
17438
  ready: checks.length > 0 && checks.every((check2) => check2.status === "pass")
@@ -17090,8 +17441,14 @@ var HMR_ASSET_PATTERN, RELEASE_ASSET_EXTENSIONS, pathExists5 = async (path) => {
17090
17441
  var init_releaseDoctor = __esm(() => {
17091
17442
  init_nativeAuth();
17092
17443
  init_syncSchema();
17444
+ init_deviceCapabilities();
17093
17445
  HMR_ASSET_PATTERN = /(?:__HMR_WS__|hmr-timing|__absolute_target|absolutejs-error-overlay)/u;
17094
17446
  RELEASE_ASSET_EXTENSIONS = new Set([".html", ".js", ".mjs"]);
17447
+ IOS_USAGE_KEYS = {
17448
+ camera: "NSCameraUsageDescription",
17449
+ "photo-library": "NSPhotoLibraryUsageDescription",
17450
+ "photo-library-add": "NSPhotoLibraryAddUsageDescription"
17451
+ };
17095
17452
  });
17096
17453
 
17097
17454
  // src/mobile/androidRelease.ts
@@ -17101,13 +17458,13 @@ import {
17101
17458
  copyFile as copyFile5,
17102
17459
  mkdir as mkdir12,
17103
17460
  mkdtemp as mkdtemp5,
17104
- readFile as readFile15,
17105
- rename as rename11,
17461
+ readFile as readFile16,
17462
+ rename as rename12,
17106
17463
  rm as rm8,
17107
17464
  stat as stat2,
17108
- writeFile as writeFile13
17465
+ writeFile as writeFile14
17109
17466
  } from "fs/promises";
17110
- import { dirname as dirname29, isAbsolute as isAbsolute7, join as join48, relative as relative24, resolve as resolve38, sep as sep6 } from "path";
17467
+ import { dirname as dirname29, isAbsolute as isAbsolute7, join as join50, relative as relative25, resolve as resolve39, sep as sep6 } from "path";
17111
17468
  var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifest2 = (value) => {
17112
17469
  if (!isRecord13(value) || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.runtime !== "string") {
17113
17470
  throw new TypeError("Invalid embedded AbsoluteJS mobile manifest.");
@@ -17157,20 +17514,20 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
17157
17514
  artifactPath
17158
17515
  ]);
17159
17516
  return result.exitCode === 0 && /jar verified/iu.test(result.stdout);
17160
- }, sha256File2 = async (path) => createHash12("sha256").update(await readFile15(path)).digest("hex"), safeOutputDirectory2 = (projectRoot, requested) => {
17161
- const root = resolve38(projectRoot);
17162
- const output = resolve38(root, requested ?? ".absolutejs/mobile/releases/android");
17163
- const projectRelative = relative24(root, output);
17517
+ }, sha256File2 = async (path) => createHash12("sha256").update(await readFile16(path)).digest("hex"), safeOutputDirectory2 = (projectRoot, requested) => {
17518
+ const root = resolve39(projectRoot);
17519
+ const output = resolve39(root, requested ?? ".absolutejs/mobile/releases/android");
17520
+ const projectRelative = relative25(root, output);
17164
17521
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep6}`) || isAbsolute7(projectRelative)) {
17165
17522
  throw new TypeError("mobile build --outdir must remain inside the project.");
17166
17523
  }
17167
17524
  return output;
17168
17525
  }, installRelease2 = async (artifactPath, metadata, outputRoot) => {
17169
- const releaseRoot = join48(outputRoot, metadata.releaseId);
17526
+ const releaseRoot = join50(outputRoot, metadata.releaseId);
17170
17527
  const artifactName = "app-release.aab";
17171
- const destination = join48(releaseRoot, artifactName);
17528
+ const destination = join50(releaseRoot, artifactName);
17172
17529
  if (await pathExists6(releaseRoot)) {
17173
- const existing = requireManifestIdentity(JSON.parse(await readFile15(join48(releaseRoot, "release.json"), "utf8")), metadata);
17530
+ const existing = requireManifestIdentity(JSON.parse(await readFile16(join50(releaseRoot, "release.json"), "utf8")), metadata);
17174
17531
  const [installedBytes, installedSha256] = await Promise.all([
17175
17532
  stat2(destination).then(({ size }) => size),
17176
17533
  sha256File2(destination)
@@ -17181,16 +17538,16 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
17181
17538
  return { artifactPath: destination, metadata: existing, releaseRoot };
17182
17539
  }
17183
17540
  await mkdir12(dirname29(releaseRoot), { recursive: true });
17184
- const staging = await mkdtemp5(join48(dirname29(releaseRoot), ".android-stage-"));
17541
+ const staging = await mkdtemp5(join50(dirname29(releaseRoot), ".android-stage-"));
17185
17542
  try {
17186
- await copyFile5(artifactPath, join48(staging, artifactName));
17543
+ await copyFile5(artifactPath, join50(staging, artifactName));
17187
17544
  const complete = {
17188
17545
  ...metadata,
17189
17546
  artifact: artifactName
17190
17547
  };
17191
- await writeFile13(join48(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
17548
+ await writeFile14(join50(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
17192
17549
  `, { flag: "wx" });
17193
- await rename11(staging, releaseRoot);
17550
+ await rename12(staging, releaseRoot);
17194
17551
  return { artifactPath: destination, metadata: complete, releaseRoot };
17195
17552
  } finally {
17196
17553
  await rm8(staging, { force: true, recursive: true }).catch(() => {
@@ -17213,11 +17570,11 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
17213
17570
  if (options.versionCode !== undefined && (!Number.isSafeInteger(options.versionCode) || options.versionCode < 1 || options.versionCode > 2100000000)) {
17214
17571
  throw new TypeError("Android versionCode must be an integer from 1 through 2100000000.");
17215
17572
  }
17216
- const projectRoot = resolve38(options.projectRoot);
17573
+ const projectRoot = resolve39(options.projectRoot);
17217
17574
  const host2 = options.host ?? detectAbsoluteMobileHost();
17218
17575
  const androidRoot = options.androidRoot ?? process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host2);
17219
- const nativeDirectory = join48(options.config.nativeProjectDirectory, "android");
17220
- const manifest = requireManifest2(JSON.parse(await readFile15(join48(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
17576
+ const nativeDirectory = join50(options.config.nativeProjectDirectory, "android");
17577
+ const manifest = requireManifest2(JSON.parse(await readFile16(join50(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
17221
17578
  if (manifest.appId !== options.config.appId) {
17222
17579
  throw new TypeError("Embedded mobile manifest appId does not match mobile.appId.");
17223
17580
  }
@@ -17281,7 +17638,7 @@ var init_androidRelease = __esm(() => {
17281
17638
  });
17282
17639
 
17283
17640
  // src/mobile/iosConformance.ts
17284
- import { readFile as readFile16, stat as stat3 } from "fs/promises";
17641
+ import { readFile as readFile17, stat as stat3 } from "fs/promises";
17285
17642
  var HMR_LINE, parseAbsoluteIosHmrLog = (line) => {
17286
17643
  const match = HMR_LINE.exec(line);
17287
17644
  if (!match)
@@ -17316,7 +17673,7 @@ var HMR_LINE, parseAbsoluteIosHmrLog = (line) => {
17316
17673
  if (Date.now() > deadline)
17317
17674
  throw new Error(`No iOS native HMR acknowledgement was observed within ${timeoutMs}ms.`);
17318
17675
  options.signal?.throwIfAborted();
17319
- const contents = await readFile16(options.logPath).catch(() => Buffer.alloc(0));
17676
+ const contents = await readFile17(options.logPath).catch(() => Buffer.alloc(0));
17320
17677
  if (contents.byteLength < offset) {
17321
17678
  offset = 0;
17322
17679
  buffered = "";
@@ -17341,7 +17698,7 @@ var init_iosConformance = __esm(() => {
17341
17698
 
17342
17699
  // src/mobile/releasePublisher.ts
17343
17700
  import { access as access10 } from "fs/promises";
17344
- import { isAbsolute as isAbsolute8, relative as relative25, resolve as resolve39, sep as sep7 } from "path";
17701
+ import { isAbsolute as isAbsolute8, relative as relative26, resolve as resolve40, sep as sep7 } from "path";
17345
17702
  import { pathToFileURL as pathToFileURL2 } from "url";
17346
17703
  var prepareAbsoluteIosRelease = async (publisher, options) => {
17347
17704
  if (typeof publisher.prepareIosRelease !== "function") {
@@ -17363,9 +17720,9 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
17363
17720
  }
17364
17721
  return versionCode;
17365
17722
  }, isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isPublisher = (value) => isRecord14(value) && typeof value.publish === "function", publisherModulePath = (projectRoot, requested) => {
17366
- const root = resolve39(projectRoot);
17367
- const path = resolve39(root, requested);
17368
- const projectRelative = relative25(root, path);
17723
+ const root = resolve40(projectRoot);
17724
+ const path = resolve40(root, requested);
17725
+ const projectRelative = relative26(root, path);
17369
17726
  if (projectRelative === ".." || projectRelative.startsWith(`..${sep7}`) || isAbsolute8(projectRelative)) {
17370
17727
  throw new TypeError("mobile publish --registry must remain inside the project.");
17371
17728
  }
@@ -17437,11 +17794,11 @@ var exports_mobile = {};
17437
17794
  __export(exports_mobile, {
17438
17795
  runMobile: () => runMobile
17439
17796
  });
17440
- import { access as access11, mkdir as mkdir13, readFile as readFile17, writeFile as writeFile14 } from "fs/promises";
17441
- import { join as join49, resolve as resolve40 } from "path";
17797
+ import { access as access11, mkdir as mkdir13, readFile as readFile18, writeFile as writeFile15 } from "fs/promises";
17798
+ import { join as join51, resolve as resolve41 } from "path";
17442
17799
  import { createInterface } from "readline/promises";
17443
- var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, packageNameFromSpec = (spec) => spec.slice(0, spec.lastIndexOf("@")), directProjectPackages = async (projectRoot) => {
17444
- const manifest = JSON.parse(await readFile17(join49(projectRoot, "package.json"), "utf8"));
17800
+ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, packageNameFromSpec = (spec) => spec.slice(0, spec.lastIndexOf("@")), directProjectPackages = async (projectRoot) => {
17801
+ const manifest = JSON.parse(await readFile18(join51(projectRoot, "package.json"), "utf8"));
17445
17802
  if (!isRecord15(manifest))
17446
17803
  throw new TypeError("Application package.json must contain an object.");
17447
17804
  const names = new Set;
@@ -17452,23 +17809,40 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
17452
17809
  names.add(name);
17453
17810
  }
17454
17811
  return names;
17455
- }, ensureCapacitorPackages = async (projectRoot, args) => {
17812
+ }, resolvedPackageVersion = async (projectRoot, packageName) => {
17813
+ try {
17814
+ const manifest = JSON.parse(await readFile18(join51(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
17815
+ return isRecord15(manifest) && typeof manifest.version === "string" ? manifest.version : undefined;
17816
+ } catch {
17817
+ return;
17818
+ }
17819
+ }, exactVersionFromSpec = (spec) => spec.slice(spec.lastIndexOf("@") + 1), installApprovedPackages = async (projectRoot, args, message, specs) => {
17820
+ if (specs.length === 0)
17821
+ return;
17822
+ const approved = args.includes("--yes") || await confirmInstall(message);
17823
+ if (!approved)
17824
+ throw new TypeError(`Mobile initialization requires: bun add ${specs.join(" ")}`);
17825
+ if (!installPackages(projectRoot, specs))
17826
+ throw new TypeError("Failed to install the AbsoluteJS mobile toolchain.");
17827
+ }, packagesNeedingExactInstall = async (projectRoot, specs, installed, exactPackages) => (await Promise.all(specs.map(async (spec) => {
17828
+ const name = packageNameFromSpec(spec);
17829
+ const needsInstall = !installed.has(name) || exactPackages.has(name) && await resolvedPackageVersion(projectRoot, name) !== exactVersionFromSpec(spec);
17830
+ return needsInstall ? spec : undefined;
17831
+ }))).filter((spec) => spec !== undefined), ensureCapacitorPackages = async (projectRoot, args) => {
17456
17832
  const specs = [
17457
17833
  ...CAPACITOR_PACKAGE_SPECS,
17458
17834
  ...projectUsesAbsoluteSync(projectRoot) ? CAPACITOR_SYNC_PACKAGE_SPECS : []
17459
17835
  ];
17460
17836
  const installed = await directProjectPackages(projectRoot);
17461
- const missing = specs.filter((spec) => !installed.has(packageNameFromSpec(spec)));
17462
- if (missing.length === 0)
17463
- return;
17464
- const approved = args.includes("--yes") || await confirmInstall("Capacitor and the AbsoluteJS native adapters are missing. Install the tested mobile toolchain now?");
17465
- if (!approved)
17466
- throw new TypeError(`Mobile initialization requires: bun add ${missing.join(" ")}`);
17467
- if (!installPackages(projectRoot, missing))
17468
- throw new TypeError("Failed to install the AbsoluteJS mobile toolchain.");
17837
+ const missing = await packagesNeedingExactInstall(projectRoot, specs, installed, new Set(["@absolutejs/devices", "@absolutejs/devices-capacitor"]));
17838
+ await installApprovedPackages(projectRoot, args, "Capacitor and the AbsoluteJS native adapters are missing or outdated. Install the tested mobile toolchain now?", missing);
17839
+ const capabilityPlan = resolveAbsoluteDeviceCapabilityPlan(projectRoot);
17840
+ const directCapabilityPackages = await directProjectPackages(projectRoot);
17841
+ const capabilityPackages = await packagesNeedingExactInstall(projectRoot, capabilityPlan.requiredPackages, directCapabilityPackages, new Set(capabilityPlan.requiredPackages.map(packageNameFromSpec)));
17842
+ await installApprovedPackages(projectRoot, args, `AbsoluteJS detected native device capabilities (${capabilityPlan.capabilities.join(", ")}). Install only their required Capacitor plugins now?`, capabilityPackages);
17469
17843
  }, valueAfter = (args, flag) => {
17470
17844
  const index = args.indexOf(flag);
17471
- return index === NOT_FOUND2 ? undefined : args[index + 1];
17845
+ return index === NOT_FOUND3 ? undefined : args[index + 1];
17472
17846
  }, valuesAfter = (args, flag) => args.flatMap((value, index) => {
17473
17847
  const next = args[index + 1];
17474
17848
  return value === flag && next !== undefined ? [next] : [];
@@ -17478,7 +17852,7 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
17478
17852
  }
17479
17853
  return value;
17480
17854
  }, capacitorExecutable = async (projectRoot) => {
17481
- const executable = join49(projectRoot, "node_modules", ".bin", "cap");
17855
+ const executable = join51(projectRoot, "node_modules", ".bin", "cap");
17482
17856
  try {
17483
17857
  await access11(executable);
17484
17858
  return executable;
@@ -17549,6 +17923,7 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
17549
17923
  return;
17550
17924
  await runCapacitorForPlatforms(projectRoot, "add", mobile.platforms);
17551
17925
  await applyAbsoluteNativeDeepLinks(mobile);
17926
+ await applyAbsoluteNativeDeviceCapabilities(projectRoot, mobile);
17552
17927
  await applyAbsoluteNativeBackgroundSync(projectRoot, mobile);
17553
17928
  }, sync = async (args) => {
17554
17929
  const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
@@ -17561,10 +17936,11 @@ var NOT_FOUND2 = -1, isRecord15 = (value) => typeof value === "object" && value
17561
17936
  await repairAbsoluteIosDevSession(projectRoot);
17562
17937
  await runCapacitorForPlatforms(projectRoot, "sync", platforms);
17563
17938
  await applyAbsoluteNativeDeepLinks(mobile, platforms);
17939
+ await applyAbsoluteNativeDeviceCapabilities(projectRoot, mobile, platforms);
17564
17940
  await applyAbsoluteNativeBackgroundSync(projectRoot, mobile, platforms);
17565
17941
  }, associations = async (args) => {
17566
17942
  const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
17567
- const outputDirectory = resolve40(projectRoot, valueAfter(args, "--outdir") ?? ".absolutejs/mobile/associations");
17943
+ const outputDirectory = resolve41(projectRoot, valueAfter(args, "--outdir") ?? ".absolutejs/mobile/associations");
17568
17944
  if (args.includes("--verify")) {
17569
17945
  const result2 = await verifyAbsoluteMobileAssociationFiles(mobile);
17570
17946
  console.log(`Verified ${result2.results.length} hosted association files`);
@@ -17779,6 +18155,9 @@ Mobile release transport checks failed.`);
17779
18155
  await writeAbsoluteCapacitorConfig(mobile, { projectRoot });
17780
18156
  await runCapacitorForPlatforms(projectRoot, "sync", ["android"]);
17781
18157
  await applyAbsoluteNativeDeepLinks(mobile, ["android"]);
18158
+ await applyAbsoluteNativeDeviceCapabilities(projectRoot, mobile, [
18159
+ "android"
18160
+ ]);
17782
18161
  await applyAbsoluteNativeBackgroundSync(projectRoot, mobile, [
17783
18162
  "android"
17784
18163
  ]);
@@ -17794,7 +18173,7 @@ Mobile release transport checks failed.`);
17794
18173
  const durationMs = Math.round(performance.now() - startedAt);
17795
18174
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} Android App Bundle in ${getDurationString(durationMs)}.`);
17796
18175
  console.log(`Artifact: ${release.artifactPath}`);
17797
- console.log(`Metadata: ${join49(release.releaseRoot, "release.json")}`);
18176
+ console.log(`Metadata: ${join51(release.releaseRoot, "release.json")}`);
17798
18177
  return release;
17799
18178
  } finally {
17800
18179
  sendTelemetryEvent("mobile:android-release-build", {
@@ -17881,6 +18260,9 @@ Mobile release transport checks failed.`);
17881
18260
  await writeAbsoluteCapacitorConfig(mobile, { projectRoot });
17882
18261
  await runCapacitorForPlatforms(projectRoot, "sync", ["ios"]);
17883
18262
  await applyAbsoluteNativeDeepLinks(mobile, ["ios"]);
18263
+ await applyAbsoluteNativeDeviceCapabilities(projectRoot, mobile, [
18264
+ "ios"
18265
+ ]);
17884
18266
  await applyAbsoluteNativeBackgroundSync(projectRoot, mobile, ["ios"]);
17885
18267
  await requireIosReleaseReady(mobile, projectRoot);
17886
18268
  const release = await buildAbsoluteIosRelease({
@@ -17894,7 +18276,7 @@ Mobile release transport checks failed.`);
17894
18276
  const durationMs = Math.round(performance.now() - startedAt);
17895
18277
  console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} iOS IPA ${release.metadata.marketingVersion}${release.metadata.buildNumber ? ` (${release.metadata.buildNumber})` : ""} in ${getDurationString(durationMs)}.`);
17896
18278
  console.log(`Artifact: ${release.artifactPath}`);
17897
- console.log(`Metadata: ${join49(release.releaseRoot, "release.json")}`);
18279
+ console.log(`Metadata: ${join51(release.releaseRoot, "release.json")}`);
17898
18280
  return release;
17899
18281
  } finally {
17900
18282
  sendTelemetryEvent("mobile:ios-release-build", {
@@ -18001,7 +18383,7 @@ Mobile release transport checks failed.`);
18001
18383
  checks.push({
18002
18384
  id: "sync.storage-schema",
18003
18385
  label: `Offline schema ${schema.components.map((component2) => `${component2.id}@${component2.version}`).join(", ")}`,
18004
- path: join49(projectRoot, "package.json"),
18386
+ path: join51(projectRoot, "package.json"),
18005
18387
  platform: "host",
18006
18388
  status: "pass"
18007
18389
  });
@@ -18009,7 +18391,7 @@ Mobile release transport checks failed.`);
18009
18391
  checks.push({
18010
18392
  id: "sync.storage-schema",
18011
18393
  label: "Offline schema metadata is invalid",
18012
- path: join49(projectRoot, "package.json"),
18394
+ path: join51(projectRoot, "package.json"),
18013
18395
  platform: "host",
18014
18396
  remediation: error instanceof Error ? error.message : String(error),
18015
18397
  status: "fail"
@@ -18094,7 +18476,7 @@ Emulator setup verification:`);
18094
18476
  }
18095
18477
  return { https: args.includes("--https"), port };
18096
18478
  }
18097
- const instances = listLiveInstances().filter((instance2) => resolve40(instance2.cwd) === resolve40(projectRoot) && instance2.source === "dev" && instance2.port !== null);
18479
+ const instances = listLiveInstances().filter((instance2) => resolve41(instance2.cwd) === resolve41(projectRoot) && instance2.source === "dev" && instance2.port !== null);
18098
18480
  if (instances.length !== 1) {
18099
18481
  throw new TypeError(instances.length === 0 ? "No running AbsoluteJS dev server was found for this project. Start `bun dev`, wait for Android to report ready, then run `absolute mobile test android`." : "Multiple dev servers are running for this project. Select one with mobile test android --port <port>.");
18100
18482
  }
@@ -18137,8 +18519,8 @@ Emulator setup verification:`);
18137
18519
  }
18138
18520
  return selected;
18139
18521
  }, safeArtifactRoot = (projectRoot, value) => {
18140
- const root = resolve40(projectRoot, value ?? ".absolutejs/mobile/test-artifacts");
18141
- if (root !== projectRoot && !root.startsWith(`${resolve40(projectRoot)}/`)) {
18522
+ const root = resolve41(projectRoot, value ?? ".absolutejs/mobile/test-artifacts");
18523
+ if (root !== projectRoot && !root.startsWith(`${resolve41(projectRoot)}/`)) {
18142
18524
  throw new TypeError("mobile test --artifacts must remain inside the project.");
18143
18525
  }
18144
18526
  return root;
@@ -18163,11 +18545,11 @@ Emulator setup verification:`);
18163
18545
  });
18164
18546
  }, writeAndroidFailureArtifacts = async (options) => {
18165
18547
  await mkdir13(options.artifactRoot, { recursive: true });
18166
- const screenshot = options.session ? await options.session.screenshot(join49(options.artifactRoot, "android-failure.png")).catch(() => {
18548
+ const screenshot = options.session ? await options.session.screenshot(join51(options.artifactRoot, "android-failure.png")).catch(() => {
18167
18549
  return;
18168
18550
  }) : undefined;
18169
- const diagnosticPath = join49(options.artifactRoot, "android-failure.json");
18170
- await writeFile14(diagnosticPath, `${JSON.stringify({
18551
+ const diagnosticPath = join51(options.artifactRoot, "android-failure.json");
18552
+ await writeFile15(diagnosticPath, `${JSON.stringify({
18171
18553
  diagnostics: options.session?.diagnostics ?? [],
18172
18554
  error: options.error instanceof Error ? options.error.message : String(options.error),
18173
18555
  platform: "android",
@@ -18257,14 +18639,14 @@ Emulator setup verification:`);
18257
18639
  const port = Number(explicit);
18258
18640
  if (!Number.isInteger(port) || port < 1 || port > 65535)
18259
18641
  throw new TypeError("mobile test --port must be a valid TCP port.");
18260
- const instance2 = listLiveInstances().find((candidate) => resolve40(candidate.cwd) === resolve40(projectRoot) && candidate.source === "dev" && candidate.port === port);
18642
+ const instance2 = listLiveInstances().find((candidate) => resolve41(candidate.cwd) === resolve41(projectRoot) && candidate.source === "dev" && candidate.port === port);
18261
18643
  return {
18262
18644
  https: instance2?.https ?? args.includes("--https"),
18263
18645
  instance: instance2,
18264
18646
  port
18265
18647
  };
18266
18648
  }
18267
- const instances = listLiveInstances().filter((instance2) => resolve40(instance2.cwd) === resolve40(projectRoot) && instance2.source === "dev" && instance2.port !== null);
18649
+ const instances = listLiveInstances().filter((instance2) => resolve41(instance2.cwd) === resolve41(projectRoot) && instance2.source === "dev" && instance2.port !== null);
18268
18650
  if (instances.length !== 1)
18269
18651
  throw new TypeError(instances.length === 0 ? "No running AbsoluteJS dev server was found for this project. Start `bun dev`, wait for iOS to report ready, then run `absolute mobile test ios`." : "Multiple dev servers are running for this project. Select one with mobile test ios --port <port>.");
18270
18652
  const [instance] = instances;
@@ -18344,7 +18726,7 @@ Emulator setup verification:`);
18344
18726
  return result;
18345
18727
  }, writeIosFailureArtifacts = async (options) => {
18346
18728
  await mkdir13(options.artifactRoot, { recursive: true });
18347
- const screenshot = join49(options.artifactRoot, "ios-failure.png");
18729
+ const screenshot = join51(options.artifactRoot, "ios-failure.png");
18348
18730
  const screenshotResult = captureCommand4([
18349
18731
  options.xcrun,
18350
18732
  "simctl",
@@ -18353,8 +18735,8 @@ Emulator setup verification:`);
18353
18735
  "screenshot",
18354
18736
  screenshot
18355
18737
  ]);
18356
- const diagnosticPath = join49(options.artifactRoot, "ios-failure.json");
18357
- await writeFile14(diagnosticPath, `${JSON.stringify({
18738
+ const diagnosticPath = join51(options.artifactRoot, "ios-failure.json");
18739
+ await writeFile15(diagnosticPath, `${JSON.stringify({
18358
18740
  appId: options.appId,
18359
18741
  error: options.error instanceof Error ? options.error.message : String(options.error),
18360
18742
  platform: "ios",
@@ -18399,7 +18781,7 @@ Emulator setup verification:`);
18399
18781
  ], "iOS app launch");
18400
18782
  await waitForIosHmrClient({ https, port, timeoutMs });
18401
18783
  await mkdir13(artifactRoot, { recursive: true });
18402
- const screenshot = join49(artifactRoot, "ios-simulator.png");
18784
+ const screenshot = join51(artifactRoot, "ios-simulator.png");
18403
18785
  requireCapturedIosCommand([xcrun, "simctl", "io", simulator.udid, "screenshot", screenshot], "iOS simulator screenshot");
18404
18786
  const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
18405
18787
  const report = {
@@ -18503,6 +18885,7 @@ var init_mobile = __esm(() => {
18503
18885
  init_capacitorProject();
18504
18886
  init_config();
18505
18887
  init_nativeDeepLinks();
18888
+ init_nativeDeviceCapabilities();
18506
18889
  init_nativeBackgroundSync();
18507
18890
  init_emulatorDoctor();
18508
18891
  init_emulatorInstaller();
@@ -18524,6 +18907,7 @@ var init_mobile = __esm(() => {
18524
18907
  init_remoteMacProtocol();
18525
18908
  init_nativeAuth();
18526
18909
  init_syncSchema();
18910
+ init_deviceCapabilities();
18527
18911
  CAPACITOR_PACKAGES = [
18528
18912
  "@capacitor/core",
18529
18913
  "@capacitor/app",
@@ -18545,11 +18929,11 @@ var init_mobile = __esm(() => {
18545
18929
  "@capacitor/cli@8.5.0",
18546
18930
  "@capacitor/android@8.5.0",
18547
18931
  "@capacitor/ios@8.5.0",
18548
- "@absolutejs/devices@0.0.3",
18549
- "@absolutejs/devices-capacitor@0.1.3"
18932
+ "@absolutejs/devices@0.2.0",
18933
+ "@absolutejs/devices-capacitor@0.3.1"
18550
18934
  ];
18551
18935
  CAPACITOR_SYNC_PACKAGE_SPECS = [
18552
- "@absolutejs/sync-capacitor@0.8.0",
18936
+ "@absolutejs/sync-capacitor@0.9.0",
18553
18937
  "@capacitor-community/sqlite@8.1.1"
18554
18938
  ];
18555
18939
  });
@@ -18559,10 +18943,10 @@ var exports_typecheck = {};
18559
18943
  __export(exports_typecheck, {
18560
18944
  typecheck: () => typecheck
18561
18945
  });
18562
- import { resolve as resolve41, join as join50 } from "path";
18563
- import { existsSync as existsSync42, readFileSync as readFileSync39 } from "fs";
18564
- import { mkdir as mkdir14, writeFile as writeFile15 } from "fs/promises";
18565
- var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve41(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
18946
+ import { resolve as resolve42, join as join52 } from "path";
18947
+ import { existsSync as existsSync42, readFileSync as readFileSync40 } from "fs";
18948
+ import { mkdir as mkdir14, writeFile as writeFile16 } from "fs/promises";
18949
+ var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve42(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
18566
18950
  if (!existsSync42(resolveConfigPath(configPath2))) {
18567
18951
  const defaultService = {};
18568
18952
  return [defaultService];
@@ -18584,7 +18968,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
18584
18968
  const exitCode = await proc.exited;
18585
18969
  return { exitCode, name, output: (stdout + stderr).trim() };
18586
18970
  }, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
18587
- const local = resolve41("node_modules", ".bin", name);
18971
+ const local = resolve42("node_modules", ".bin", name);
18588
18972
  return existsSync42(local) ? local : null;
18589
18973
  }, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi4 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
18590
18974
  const cwd = `${process.cwd()}/`;
@@ -18632,15 +19016,15 @@ Found ${errorCount} error${suffix}.`;
18632
19016
  return formatted;
18633
19017
  }, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
18634
19018
  const candidates = [
18635
- resolve41("node_modules/@absolutejs/absolute/dist/types", fileName),
18636
- resolve41(import.meta.dir, "../types", fileName),
18637
- resolve41(import.meta.dir, "../../types", fileName),
18638
- resolve41(import.meta.dir, "../../../types", fileName)
19019
+ resolve42("node_modules/@absolutejs/absolute/dist/types", fileName),
19020
+ resolve42(import.meta.dir, "../types", fileName),
19021
+ resolve42(import.meta.dir, "../../types", fileName),
19022
+ resolve42(import.meta.dir, "../../../types", fileName)
18639
19023
  ];
18640
19024
  return candidates.find((candidate) => existsSync42(candidate)) ?? candidates[0];
18641
19025
  }, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
18642
19026
  try {
18643
- return JSON.parse(readFileSync39(resolve41("tsconfig.json"), "utf-8"));
19027
+ return JSON.parse(readFileSync40(resolve42("tsconfig.json"), "utf-8"));
18644
19028
  } catch {
18645
19029
  return {};
18646
19030
  }
@@ -18668,27 +19052,27 @@ Found ${errorCount} error${suffix}.`;
18668
19052
  console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
18669
19053
  process.exit(1);
18670
19054
  }
18671
- const vueTsconfigPath = join50(cacheDir, "tsconfig.vue-check.json");
18672
- await writeFile15(vueTsconfigPath, JSON.stringify({
19055
+ const vueTsconfigPath = join52(cacheDir, "tsconfig.vue-check.json");
19056
+ await writeFile16(vueTsconfigPath, JSON.stringify({
18673
19057
  compilerOptions: {
18674
19058
  rootDir: ".."
18675
19059
  },
18676
19060
  exclude: getProjectTypecheckExcludes(),
18677
- extends: resolve41("tsconfig.json"),
19061
+ extends: resolve42("tsconfig.json"),
18678
19062
  include: getProjectTypecheckIncludes()
18679
19063
  }, null, "\t"));
18680
19064
  const base = [
18681
19065
  vueTscBin,
18682
19066
  "--noEmit",
18683
19067
  "--project",
18684
- resolve41(vueTsconfigPath),
19068
+ resolve42(vueTsconfigPath),
18685
19069
  "--pretty"
18686
19070
  ];
18687
19071
  const cached = await run("vue-tsc", [
18688
19072
  ...base,
18689
19073
  "--incremental",
18690
19074
  "--tsBuildInfoFile",
18691
- join50(cacheDir, "vue-tsc.tsbuildinfo")
19075
+ join52(cacheDir, "vue-tsc.tsbuildinfo")
18692
19076
  ]);
18693
19077
  if (cached.exitCode === 0 || cached.output.length > 0)
18694
19078
  return cached;
@@ -18699,8 +19083,8 @@ Found ${errorCount} error${suffix}.`;
18699
19083
  console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
18700
19084
  process.exit(1);
18701
19085
  }
18702
- const angularTsconfigPath = join50(cacheDir, "tsconfig.angular-check.json");
18703
- await writeFile15(angularTsconfigPath, JSON.stringify({
19086
+ const angularTsconfigPath = join52(cacheDir, "tsconfig.angular-check.json");
19087
+ await writeFile16(angularTsconfigPath, JSON.stringify({
18704
19088
  angularCompilerOptions: {
18705
19089
  strictTemplates: true
18706
19090
  },
@@ -18709,32 +19093,32 @@ Found ${errorCount} error${suffix}.`;
18709
19093
  rootDir: ".."
18710
19094
  },
18711
19095
  exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
18712
- extends: resolve41("tsconfig.json"),
19096
+ extends: resolve42("tsconfig.json"),
18713
19097
  include: [`../${angularDir}/**/*`]
18714
19098
  }, null, "\t"));
18715
- return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve41(angularTsconfigPath))}`);
19099
+ return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve42(angularTsconfigPath))}`);
18716
19100
  }, buildTscCheck = (cacheDir) => {
18717
19101
  const tscBin = findBin("tsc");
18718
19102
  if (!tscBin) {
18719
19103
  console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
18720
19104
  process.exit(1);
18721
19105
  }
18722
- const tscConfigPath = join50(cacheDir, "tsconfig.typecheck.json");
18723
- return writeFile15(tscConfigPath, JSON.stringify({
19106
+ const tscConfigPath = join52(cacheDir, "tsconfig.typecheck.json");
19107
+ return writeFile16(tscConfigPath, JSON.stringify({
18724
19108
  compilerOptions: {
18725
19109
  rootDir: ".."
18726
19110
  },
18727
19111
  exclude: getProjectTypecheckExcludes(),
18728
- extends: resolve41("tsconfig.json"),
19112
+ extends: resolve42("tsconfig.json"),
18729
19113
  include: getProjectTypecheckIncludes()
18730
19114
  }, null, "\t")).then(() => run("tsc", [
18731
19115
  tscBin,
18732
19116
  "--noEmit",
18733
19117
  "--project",
18734
- resolve41(tscConfigPath),
19118
+ resolve42(tscConfigPath),
18735
19119
  "--incremental",
18736
19120
  "--tsBuildInfoFile",
18737
- join50(cacheDir, "tsc.tsbuildinfo"),
19121
+ join52(cacheDir, "tsc.tsbuildinfo"),
18738
19122
  "--pretty"
18739
19123
  ]));
18740
19124
  }, buildSvelteCheck = async (cacheDir, svelteDir) => {
@@ -18743,16 +19127,16 @@ Found ${errorCount} error${suffix}.`;
18743
19127
  console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
18744
19128
  process.exit(1);
18745
19129
  }
18746
- const svelteTsconfigPath = join50(cacheDir, "tsconfig.svelte-check.json");
18747
- await writeFile15(svelteTsconfigPath, JSON.stringify({
18748
- extends: resolve41("tsconfig.json"),
19130
+ const svelteTsconfigPath = join52(cacheDir, "tsconfig.svelte-check.json");
19131
+ await writeFile16(svelteTsconfigPath, JSON.stringify({
19132
+ extends: resolve42("tsconfig.json"),
18749
19133
  files: ABSOLUTE_TYPECHECK_FILES,
18750
19134
  include: [`../${svelteDir}/**/*`]
18751
19135
  }, null, "\t"));
18752
19136
  return run("svelte-check", [
18753
19137
  svelteBin,
18754
19138
  "--tsconfig",
18755
- resolve41(svelteTsconfigPath),
19139
+ resolve42(svelteTsconfigPath),
18756
19140
  "--threshold",
18757
19141
  "error",
18758
19142
  "--compiler-warnings",
@@ -18946,11 +19330,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
18946
19330
  url: url.pathname + url.search,
18947
19331
  ...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
18948
19332
  };
18949
- const responsePromise = new Promise((resolve42) => {
18950
- pending.set(id, resolve42);
19333
+ const responsePromise = new Promise((resolve43) => {
19334
+ pending.set(id, resolve43);
18951
19335
  });
18952
19336
  client.send(encodeTunnelMessage(message));
18953
- const timeout = new Promise((resolve42) => setTimeout(() => resolve42({ id, message: "timeout", type: "error" }), requestTimeoutMs));
19337
+ const timeout = new Promise((resolve43) => setTimeout(() => resolve43({ id, message: "timeout", type: "error" }), requestTimeoutMs));
18954
19338
  const result = await Promise.race([responsePromise, timeout]);
18955
19339
  pending.delete(id);
18956
19340
  if (result.type === "error") {
@@ -21202,12 +21586,12 @@ import {
21202
21586
  existsSync as existsSync12,
21203
21587
  mkdirSync as mkdirSync7,
21204
21588
  readdirSync as readdirSync2,
21205
- readFileSync as readFileSync15,
21589
+ readFileSync as readFileSync16,
21206
21590
  unlinkSync as unlinkSync3,
21207
21591
  writeFileSync as writeFileSync6
21208
21592
  } from "fs";
21209
21593
  import { createConnection } from "net";
21210
- import { resolve as resolve21 } from "path";
21594
+ import { resolve as resolve22 } from "path";
21211
21595
 
21212
21596
  // src/cli/workspaceTui.ts
21213
21597
  init_constants();
@@ -21769,18 +22153,18 @@ var createWorkspaceTui = ({
21769
22153
 
21770
22154
  // src/cli/scripts/workspace.ts
21771
22155
  init_utils();
21772
- var sourceServerBootstrap2 = resolve21(import.meta.dir, "../../dev/serverBootstrap.ts");
21773
- var serverBootstrap2 = existsSync12(sourceServerBootstrap2) ? sourceServerBootstrap2 : resolve21(import.meta.dir, "../dev/serverBootstrap.js");
22156
+ var sourceServerBootstrap2 = resolve22(import.meta.dir, "../../dev/serverBootstrap.ts");
22157
+ var serverBootstrap2 = existsSync12(sourceServerBootstrap2) ? sourceServerBootstrap2 : resolve22(import.meta.dir, "../dev/serverBootstrap.js");
21774
22158
  var ANSI_REGEX2 = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
21775
22159
  var sleep = (durationMs) => Bun.sleep(durationMs);
21776
22160
  var stripAnsi3 = (value) => value.replace(ANSI_REGEX2, "");
21777
22161
  var sanitizeLogFileName = (value) => value.replace(/[^a-zA-Z0-9._-]/g, "_") || "unknown";
21778
22162
  var createWorkspaceLogSink = (appendLog) => {
21779
- const logDirectory = resolve21(".absolutejs", "workspace", "logs");
22163
+ const logDirectory = resolve22(".absolutejs", "workspace", "logs");
21780
22164
  mkdirSync7(logDirectory, { recursive: true });
21781
- readdirSync2(logDirectory).filter((file) => file.endsWith(".log")).forEach((file) => unlinkSync3(resolve21(logDirectory, file)));
21782
- writeFileSync6(resolve21(logDirectory, "all.log"), "");
21783
- writeFileSync6(resolve21(logDirectory, "workspace.log"), "");
22165
+ readdirSync2(logDirectory).filter((file) => file.endsWith(".log")).forEach((file) => unlinkSync3(resolve22(logDirectory, file)));
22166
+ writeFileSync6(resolve22(logDirectory, "all.log"), "");
22167
+ writeFileSync6(resolve22(logDirectory, "workspace.log"), "");
21784
22168
  const initializedSources = new Set(["workspace"]);
21785
22169
  const writeLog = (source, message, level) => {
21786
22170
  const cleanMessage = stripAnsi3(message).trimEnd();
@@ -21790,13 +22174,13 @@ var createWorkspaceLogSink = (appendLog) => {
21790
22174
  const timestamp = new Date().toISOString();
21791
22175
  const line = `[${timestamp}] [${level}] [${source}] ${cleanMessage}
21792
22176
  `;
21793
- const sourceFile = resolve21(logDirectory, `${sanitizeLogFileName(source)}.log`);
22177
+ const sourceFile = resolve22(logDirectory, `${sanitizeLogFileName(source)}.log`);
21794
22178
  if (!initializedSources.has(source)) {
21795
22179
  writeFileSync6(sourceFile, "");
21796
22180
  initializedSources.add(source);
21797
22181
  }
21798
22182
  appendFileSync(sourceFile, line);
21799
- appendFileSync(resolve21(logDirectory, "all.log"), line);
22183
+ appendFileSync(resolve22(logDirectory, "all.log"), line);
21800
22184
  };
21801
22185
  return {
21802
22186
  appendLog: (source, message, level = "info") => {
@@ -21808,7 +22192,7 @@ var createWorkspaceLogSink = (appendLog) => {
21808
22192
  };
21809
22193
  var readPackageVersion3 = (candidate) => {
21810
22194
  try {
21811
- const pkg = JSON.parse(readFileSync15(candidate, "utf-8"));
22195
+ const pkg = JSON.parse(readFileSync16(candidate, "utf-8"));
21812
22196
  if (pkg.name !== "@absolutejs/absolute") {
21813
22197
  return null;
21814
22198
  }
@@ -21820,9 +22204,9 @@ var readPackageVersion3 = (candidate) => {
21820
22204
  };
21821
22205
  var resolvePackageVersion2 = () => {
21822
22206
  const candidates = [
21823
- resolve21(import.meta.dir, "..", "..", "package.json"),
21824
- resolve21(import.meta.dir, "..", "..", "..", "package.json"),
21825
- resolve21(import.meta.dir, "..", "..", "..", "..", "package.json")
22207
+ resolve22(import.meta.dir, "..", "..", "package.json"),
22208
+ resolve22(import.meta.dir, "..", "..", "..", "package.json"),
22209
+ resolve22(import.meta.dir, "..", "..", "..", "..", "package.json")
21826
22210
  ];
21827
22211
  for (const candidate of candidates) {
21828
22212
  const version2 = readPackageVersion3(candidate);
@@ -22176,15 +22560,15 @@ var createWorkspaceServiceEnv = (services) => {
22176
22560
  var getDefinedProcessEnv = () => Object.fromEntries(Object.entries(process.env).filter((entry) => typeof entry[1] === "string"));
22177
22561
  var resolveAbsoluteServiceConfigPath = (service, cwd, options) => {
22178
22562
  if (service.config)
22179
- return resolve21(cwd, service.config);
22563
+ return resolve22(cwd, service.config);
22180
22564
  if (options.configPath)
22181
- return resolve21(options.configPath);
22565
+ return resolve22(options.configPath);
22182
22566
  if (process.env.ABSOLUTE_CONFIG)
22183
- return resolve21(process.env.ABSOLUTE_CONFIG);
22567
+ return resolve22(process.env.ABSOLUTE_CONFIG);
22184
22568
  return;
22185
22569
  };
22186
22570
  var resolveService = (name, service, workspaceEnv, options) => {
22187
- const cwd = resolve21(service.cwd ?? ".");
22571
+ const cwd = resolve22(service.cwd ?? ".");
22188
22572
  const envVars = Object.assign(getDefinedProcessEnv(), workspaceEnv, service.port ? { PORT: String(service.port) } : {}, service.env, {
22189
22573
  ABSOLUTE_INSTANCE_MANAGED: "1",
22190
22574
  ABSOLUTE_WORKSPACE_MANAGED: "1",
@@ -22196,7 +22580,7 @@ var resolveService = (name, service, workspaceEnv, options) => {
22196
22580
  if (isAbsoluteService(service)) {
22197
22581
  const configPath2 = resolveAbsoluteServiceConfigPath(service, cwd, options);
22198
22582
  Object.assign(envVars, configPath2 ? { ABSOLUTE_CONFIG: configPath2 } : {}, {
22199
- ABSOLUTE_SERVER_ENTRY: resolve21(cwd, service.entry ?? DEFAULT_SERVER_ENTRY)
22583
+ ABSOLUTE_SERVER_ENTRY: resolve22(cwd, service.entry ?? DEFAULT_SERVER_ENTRY)
22200
22584
  });
22201
22585
  const command = [
22202
22586
  process.execPath,
@@ -22226,8 +22610,8 @@ var resolveService = (name, service, workspaceEnv, options) => {
22226
22610
  var resolveServiceBuildDirectory = (service) => {
22227
22611
  if (!isAbsoluteService(service))
22228
22612
  return null;
22229
- const cwd = resolve21(service.cwd ?? ".");
22230
- return resolve21(cwd, service.buildDirectory ?? "build");
22613
+ const cwd = resolve22(service.cwd ?? ".");
22614
+ return resolve22(cwd, service.buildDirectory ?? "build");
22231
22615
  };
22232
22616
  var findSharedWorkspaceBuildDirectories = (services) => {
22233
22617
  const byBuildDirectory = new Map;
@@ -22445,7 +22829,7 @@ var workspace = async (subcommand, options) => {
22445
22829
  frameworks: [],
22446
22830
  host: getServicePublicHost(resolved.service),
22447
22831
  https: getServiceProtocol(resolved.service) === "https",
22448
- logFile: resolve21(workspaceLogs.logDirectory, `${sanitizeLogFileName(name)}.log`),
22832
+ logFile: resolve22(workspaceLogs.logDirectory, `${sanitizeLogFileName(name)}.log`),
22449
22833
  name,
22450
22834
  pid: processHandle.pid,
22451
22835
  port: resolved.service.port ?? null,