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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/angular/browser.js +378 -361
  2. package/dist/angular/browser.js.map +2 -2
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +7 -7
  4. package/dist/angular/components/core/streamingSlotRegistry.js +4 -4
  5. package/dist/angular/index.js +300 -294
  6. package/dist/angular/index.js.map +2 -2
  7. package/dist/angular/server.js +54 -50
  8. package/dist/angular/server.js.map +2 -2
  9. package/dist/build.js +199 -203
  10. package/dist/build.js.map +2 -2
  11. package/dist/cli/config/client.js +12 -12
  12. package/dist/cli/config/server.js +1096 -1090
  13. package/dist/cli/index.js +275 -161
  14. package/dist/client/index.js +29 -25
  15. package/dist/client/index.js.map +2 -2
  16. package/dist/core/streamingSlotRegistrar.js +15 -13
  17. package/dist/core/streamingSlotRegistrar.js.map +2 -2
  18. package/dist/core/streamingSlotRegistry.js +11 -9
  19. package/dist/core/streamingSlotRegistry.js.map +2 -2
  20. package/dist/image-client/imageClient.js +7 -7
  21. package/dist/index.js +782 -732
  22. package/dist/index.js.map +6 -5
  23. package/dist/islands/browser.js +11 -9
  24. package/dist/islands/browser.js.map +2 -2
  25. package/dist/islands/index.js +39 -35
  26. package/dist/islands/index.js.map +2 -2
  27. package/dist/mobile/browser.js +23 -22
  28. package/dist/mobile/browser.js.map +2 -2
  29. package/dist/mobile/index.js +552 -423
  30. package/dist/mobile/index.js.map +9 -9
  31. package/dist/mobile/remoteMacAgentEntry.js +115 -37
  32. package/dist/mobile/shellBootstrap.js +0 -1
  33. package/dist/mobile/shellExpoAuth.js +184 -0
  34. package/dist/mobile/shellExpoDevices.js +4 -5
  35. package/dist/mobile/shellSync.js +4 -4
  36. package/dist/react/browser.js +17 -15
  37. package/dist/react/browser.js.map +2 -2
  38. package/dist/react/components/browser/index.js +107 -107
  39. package/dist/react/components/index.js +118 -116
  40. package/dist/react/components/index.js.map +2 -2
  41. package/dist/react/hooks/index.js +11 -9
  42. package/dist/react/hooks/index.js.map +2 -2
  43. package/dist/react/index.js +53 -49
  44. package/dist/react/index.js.map +2 -2
  45. package/dist/react/jsxDevRuntimeCompat.js +11 -9
  46. package/dist/react/jsxDevRuntimeCompat.js.map +2 -2
  47. package/dist/react/jsxRuntimeCompat.js +11 -9
  48. package/dist/react/jsxRuntimeCompat.js.map +2 -2
  49. package/dist/react/router/browser.js +9 -7
  50. package/dist/react/router/browser.js.map +2 -2
  51. package/dist/react/router/index.js +9 -7
  52. package/dist/react/router/index.js.map +2 -2
  53. package/dist/react/server.js +12 -10
  54. package/dist/react/server.js.map +2 -2
  55. package/dist/src/mobile/devDeviceAdapter.d.ts +1 -1
  56. package/dist/src/mobile/expoBridge.d.ts +12 -12
  57. package/dist/src/mobile/nativeAuth.d.ts +3 -0
  58. package/dist/src/mobile/shellExpoAuth.d.ts +12 -0
  59. package/dist/svelte/browser.js +12 -10
  60. package/dist/svelte/browser.js.map +2 -2
  61. package/dist/svelte/index.js +47 -43
  62. package/dist/svelte/index.js.map +2 -2
  63. package/dist/svelte/server.js +29 -27
  64. package/dist/svelte/server.js.map +2 -2
  65. package/dist/vue/browser.js +14 -12
  66. package/dist/vue/browser.js.map +2 -2
  67. package/dist/vue/components/Image.js +9 -7
  68. package/dist/vue/components/Image.js.map +2 -2
  69. package/dist/vue/components/index.js +11 -9
  70. package/dist/vue/components/index.js.map +2 -2
  71. package/dist/vue/index.js +52 -48
  72. package/dist/vue/index.js.map +2 -2
  73. package/dist/vue/server.js +14 -12
  74. package/dist/vue/server.js.map +2 -2
  75. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -847,6 +847,50 @@ var init_config = __esm(() => {
847
847
  HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/;
848
848
  });
849
849
 
850
+ // src/mobile/nativeAuth.ts
851
+ import { readFileSync as readFileSync5 } from "fs";
852
+ import { join as join5 } from "path";
853
+ var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth", ABSOLUTE_EXPO_AUTH_CORE_VERSION = "0.75.6", ABSOLUTE_EXPO_AUTH_PACKAGE = "@absolutejs/auth-expo", ABSOLUTE_EXPO_AUTH_VERSION = "0.0.2", ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS", ABSOLUTE_NATIVE_AUTH_SCOPES, ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync", readPackageManifest = (projectRoot) => {
854
+ try {
855
+ return JSON.parse(readFileSync5(join5(projectRoot, "package.json"), "utf8"));
856
+ } catch {
857
+ return;
858
+ }
859
+ }, packageManifestHas = (manifest, packageName) => {
860
+ if (typeof manifest !== "object" || manifest === null)
861
+ return false;
862
+ return [
863
+ Reflect.get(manifest, "dependencies"),
864
+ Reflect.get(manifest, "devDependencies"),
865
+ Reflect.get(manifest, "optionalDependencies"),
866
+ Reflect.get(manifest, "peerDependencies")
867
+ ].some((dependencies) => typeof dependencies === "object" && dependencies !== null && Object.hasOwn(dependencies, packageName));
868
+ }, createAbsoluteMobileAuthManifest = (config) => {
869
+ const scheme = config.deepLinkScheme ?? config.appId.toLowerCase();
870
+ return {
871
+ clientId: `absolutejs-native:${config.appId}`,
872
+ issuer: config.productionOrigin,
873
+ redirectUri: `${scheme}://auth/callback`,
874
+ scopes: [...ABSOLUTE_NATIVE_AUTH_SCOPES]
875
+ };
876
+ }, installAbsoluteMobileAuthEnvironment = (projectRoot, config) => {
877
+ const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
878
+ const serialized = serializeAbsoluteMobileAuthEnvironment(config, auth);
879
+ if (serialized === undefined)
880
+ delete process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV];
881
+ else
882
+ process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV] = serialized;
883
+ return auth;
884
+ }, projectUsesAbsoluteAuth = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_AUTH_PACKAGE), projectUsesAbsoluteSync = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_SYNC_PACKAGE), resolveAbsoluteMobileAuthManifest = (projectRoot, config) => projectUsesAbsoluteAuth(projectRoot) ? createAbsoluteMobileAuthManifest(config) : undefined, serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefined ? undefined : JSON.stringify([
885
+ {
886
+ ...auth,
887
+ name: `${config.appName} native app`
888
+ }
889
+ ]);
890
+ var init_nativeAuth = __esm(() => {
891
+ ABSOLUTE_NATIVE_AUTH_SCOPES = ["openid", "profile"];
892
+ });
893
+
850
894
  // src/mobile/expoProject.ts
851
895
  import {
852
896
  access,
@@ -860,7 +904,7 @@ import {
860
904
  writeFile
861
905
  } from "fs/promises";
862
906
  import { createHash } from "crypto";
863
- import { basename as basename2, dirname as dirname3, join as join5, relative, resolve as resolve3 } from "path";
907
+ import { basename as basename2, dirname as dirname3, join as join6, relative, resolve as resolve3 } from "path";
864
908
  var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
865
909
  `, EXPO_ASSET_EXTENSION = ".absasset", EXPO_PROJECT_MARKER = ".absolutejs-expo-project", exists = async (path) => {
866
910
  try {
@@ -879,8 +923,12 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
879
923
  throw new TypeError(`Expo native route ${route} contains an unsupported segment ${segment}.`);
880
924
  }
881
925
  return segment;
882
- }), routeFile = (project, route) => join5(project, "app", ...routeSegments(route), "index.tsx"), expoPackage = () => ({
926
+ }), routeFile = (project, route) => join6(project, "app", ...routeSegments(route), "index.tsx"), expoPackage = (auth) => ({
883
927
  dependencies: {
928
+ ...auth ? {
929
+ "@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
930
+ [ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
931
+ } : {},
884
932
  expo: "~57.0.9",
885
933
  "expo-asset": "~57.0.15",
886
934
  "expo-constants": "~57.0.16",
@@ -889,6 +937,10 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
889
937
  "expo-haptics": "~57.0.2",
890
938
  "expo-linking": "~57.0.8",
891
939
  "expo-router": "~57.0.17",
940
+ ...auth ? {
941
+ "expo-secure-store": "~57.0.2",
942
+ "expo-web-browser": "~57.0.2"
943
+ } : {},
892
944
  react: "19.2.3",
893
945
  "react-native": "0.86.3",
894
946
  "react-native-safe-area-context": "~5.7.0",
@@ -908,7 +960,7 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
908
960
  start: "expo start --dev-client"
909
961
  },
910
962
  version: "0.0.0"
911
- }), expoAppConfig = (config) => ({
963
+ }), expoAppConfig = (config, auth) => ({
912
964
  expo: {
913
965
  android: {
914
966
  intentFilters: config.deepLinkHosts.map((host) => ({
@@ -928,7 +980,8 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
928
980
  name: config.appName,
929
981
  plugins: [
930
982
  "expo-router",
931
- ["expo-dev-client", { launchMode: "most-recent" }]
983
+ ["expo-dev-client", { launchMode: "most-recent" }],
984
+ ...auth ? ["expo-secure-store"] : []
932
985
  ],
933
986
  runtimeVersion: { policy: "appVersion" },
934
987
  scheme: config.deepLinkScheme,
@@ -949,7 +1002,48 @@ config.resolver.nodeModulesPaths = [
949
1002
  config.watchFolders = [appRoot];
950
1003
 
951
1004
  module.exports = config;
952
- `, layoutSource, nativeDiagnosticSource, webHostSource = (config) => {
1005
+ `, layoutSource = (auth) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
1006
+ ${auth ? `import { useEffect } from 'react';
1007
+ import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
1008
+
1009
+ export default function AbsoluteLayout() {
1010
+ ${auth ? `useEffect(() => {
1011
+ void startAbsoluteExpoAuth();
1012
+ }, []);` : ""}
1013
+ return <Stack screenOptions={{ headerShown: false }} />;
1014
+ }
1015
+ `, nativeDiagnosticSource, authRuntimeSource = (auth, appId) => {
1016
+ const storageIdentity = createHash("sha256").update(appId).digest("hex").slice(0, 24);
1017
+ return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
1018
+ import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
1019
+
1020
+ export const absoluteExpoAuth = createAbsoluteExpoAuthClient({
1021
+ allowedOrigins: [${JSON.stringify(auth.issuer)}],
1022
+ clientId: ${JSON.stringify(auth.clientId)},
1023
+ issuer: ${JSON.stringify(auth.issuer)},
1024
+ redirectUri: ${JSON.stringify(auth.redirectUri)},
1025
+ resource: ${JSON.stringify(auth.issuer)},
1026
+ scopes: ${JSON.stringify(auth.scopes)},
1027
+ storagePrefix: ${JSON.stringify(`absolutejs.auth.${storageIdentity}`)}
1028
+ });
1029
+ installAuthClientRuntimeTransport(createMobileAuthTransport(absoluteExpoAuth, { baseUrl: ${JSON.stringify(auth.issuer)} }));
1030
+
1031
+ let currentPrincipal: Awaited<ReturnType<typeof absoluteExpoAuth.principal>> = null;
1032
+ absoluteExpoAuth.onPrincipalChange(principal => {
1033
+ currentPrincipal = principal;
1034
+ });
1035
+ export const getAbsoluteExpoAuthPrincipal = () => currentPrincipal;
1036
+
1037
+ let startPromise: Promise<void> | undefined;
1038
+ export const startAbsoluteExpoAuth = () => {
1039
+ startPromise ??= absoluteExpoAuth.start().then(async () => {
1040
+ await absoluteExpoAuth.principal();
1041
+ });
1042
+
1043
+ return startPromise;
1044
+ };
1045
+ `;
1046
+ }, webHostSource = (config, auth) => {
953
1047
  const nativeRoutes = [
954
1048
  "/__absolute/native",
955
1049
  ...Object.keys(config.expoNativeRoutes)
@@ -961,8 +1055,9 @@ import { useEffect, useRef, useState } from 'react';
961
1055
  import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
962
1056
  import { WebView, type WebViewMessageEvent } from 'react-native-webview';
963
1057
  import { materializeAbsoluteWebBundle } from './webAssets';
1058
+ ${auth ? "import { absoluteExpoAuth, getAbsoluteExpoAuthPrincipal, startAbsoluteExpoAuth } from './AbsoluteAuth';" : ""}
964
1059
 
965
- const BRIDGE_FORMAT = 1;
1060
+ const BRIDGE_FORMAT = 2;
966
1061
  const MAX_MESSAGE_BYTES = 64 * 1024;
967
1062
  const MAX_HTTP_BODY_BYTES = 48 * 1024;
968
1063
  const NATIVE_ROUTES = new Set(${JSON.stringify(nativeRoutes)});
@@ -971,6 +1066,7 @@ const DEV_ORIGIN = Platform.OS === 'android'
971
1066
  ? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
972
1067
  : process.env.EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN;
973
1068
  const HMR_TARGET = Platform.OS === 'android' ? 'expo-android' : 'expo-ios';
1069
+ const AUTH_ENABLED = ${auth ? "true" : "false"};
974
1070
 
975
1071
  const bridgeBootstrap = (path: string) => {
976
1072
  const initialPath = DEV_ORIGIN
@@ -978,6 +1074,7 @@ const bridgeBootstrap = (path: string) => {
978
1074
  : JSON.stringify(path);
979
1075
  return \`(() => {
980
1076
  const pending = new Map();
1077
+ const listeners = new Map();
981
1078
  let sequence = 0;
982
1079
  let currentPath = \${initialPath};
983
1080
  const send = value => {
@@ -987,6 +1084,10 @@ const bridgeBootstrap = (path: string) => {
987
1084
  };
988
1085
  globalThis.__absoluteExpoReceive = source => {
989
1086
  const message = JSON.parse(source);
1087
+ if (message.kind === 'event') {
1088
+ for (const listener of listeners.get(message.event) || []) listener(message.payload || {});
1089
+ return;
1090
+ }
990
1091
  const operation = pending.get(message.id);
991
1092
  if (!operation) return;
992
1093
  pending.delete(message.id);
@@ -994,9 +1095,18 @@ const bridgeBootstrap = (path: string) => {
994
1095
  message.error ? operation.reject(new Error(message.error.message)) : operation.resolve(message.result);
995
1096
  };
996
1097
  globalThis.__absoluteExpoBridge = {
1098
+ on(event, listener) {
1099
+ const values = listeners.get(event) || new Set();
1100
+ values.add(listener);
1101
+ listeners.set(event, values);
1102
+ return () => {
1103
+ values.delete(listener);
1104
+ if (values.size === 0) listeners.delete(event);
1105
+ };
1106
+ },
997
1107
  request(method, params) {
998
1108
  const id = 'web_' + Date.now().toString(36) + '_' + (++sequence).toString(36);
999
- send({ format: 1, id, kind: 'request', method, params, path: currentPath });
1109
+ send({ format: 2, id, kind: 'request', method, params, path: currentPath });
1000
1110
  return new Promise((resolve, reject) => {
1001
1111
  const timer = setTimeout(() => {
1002
1112
  pending.delete(id);
@@ -1007,7 +1117,7 @@ const bridgeBootstrap = (path: string) => {
1007
1117
  },
1008
1118
  setPath(path) {
1009
1119
  currentPath = path;
1010
- send({ format: 1, kind: 'event', event: 'navigation', path });
1120
+ send({ format: 2, kind: 'event', event: 'navigation', path });
1011
1121
  }
1012
1122
  };
1013
1123
  if (\${DEV_ORIGIN ? 'true' : 'false'}) {
@@ -1015,7 +1125,7 @@ const bridgeBootstrap = (path: string) => {
1015
1125
  const path = location.pathname + location.search + location.hash;
1016
1126
  if (path === currentPath) return;
1017
1127
  currentPath = path;
1018
- send({ format: 1, kind: 'event', event: 'navigation', path });
1128
+ send({ format: 2, kind: 'event', event: 'navigation', path });
1019
1129
  };
1020
1130
  for (const method of ['pushState', 'replaceState']) {
1021
1131
  const original = history[method];
@@ -1034,9 +1144,9 @@ const bridgeBootstrap = (path: string) => {
1034
1144
  const url = new URL(anchor.href, location.href);
1035
1145
  if (!${JSON.stringify(nativeRoutes)}.includes(url.pathname)) return;
1036
1146
  event.preventDefault();
1037
- send({ format: 1, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
1147
+ send({ format: 2, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
1038
1148
  }, true);
1039
- send({ format: 1, kind: 'event', event: 'ready', path: currentPath });
1149
+ send({ format: 2, kind: 'event', event: 'ready', path: currentPath });
1040
1150
  })(); true;\`;
1041
1151
  };
1042
1152
 
@@ -1052,16 +1162,16 @@ const impact = async (params: Record<string, unknown>) => {
1052
1162
  };
1053
1163
 
1054
1164
  const bridgeFetch = async (params: Record<string, unknown>) => {
1055
- if (params.method !== 'GET' || typeof params.url !== 'string' || typeof params.headers !== 'object' || params.headers === null || Array.isArray(params.headers)) throw new Error('Expo bridge HTTP request is invalid.');
1165
+ if (typeof params.method !== 'string' || !['DELETE', 'GET', 'PATCH', 'POST', 'PUT'].includes(params.method) || typeof params.url !== 'string' || typeof params.headers !== 'object' || params.headers === null || Array.isArray(params.headers) || params.body !== undefined && typeof params.body !== 'string') throw new Error('Expo bridge HTTP request is invalid.');
1056
1166
  const url = new URL(params.url);
1057
1167
  if (url.origin !== PRODUCTION_ORIGIN || url.username || url.password) throw new Error('Expo bridge HTTP request left productionOrigin.');
1058
1168
  const headers = new Headers();
1059
1169
  for (const [name, value] of Object.entries(params.headers as Record<string, unknown>)) {
1060
1170
  const normalized = name.toLowerCase();
1061
- if (typeof value !== 'string' || (normalized !== 'accept' && !normalized.startsWith('x-absolute-mobile-'))) throw new Error('Expo bridge HTTP header is not allowed.');
1171
+ if (typeof value !== 'string' || (normalized !== 'accept' && normalized !== 'content-type' && !normalized.startsWith('x-absolute-mobile-'))) throw new Error('Expo bridge HTTP header is not allowed.');
1062
1172
  headers.set(normalized, value);
1063
1173
  }
1064
- const response = await fetch(url, { headers, method: 'GET', redirect: 'manual' });
1174
+ const response = await ${auth ? "absoluteExpoAuth.fetchOptional" : "fetch"}(url, { ...(typeof params.body === 'string' ? { body: params.body } : {}), headers, method: params.method, redirect: 'manual' });
1065
1175
  if (new URL(response.url || url.href).origin !== PRODUCTION_ORIGIN || response.status >= 300 && response.status < 400) throw new Error('Expo bridge HTTP redirects are not allowed.');
1066
1176
  const body = await response.text();
1067
1177
  if (new TextEncoder().encode(body).byteLength > MAX_HTTP_BODY_BYTES) throw new Error('Expo bridge HTTP response exceeds 48 KiB.');
@@ -1073,13 +1183,32 @@ const bridgeFetch = async (params: Record<string, unknown>) => {
1073
1183
  return { body, headers: responseHeaders, status: response.status };
1074
1184
  };
1075
1185
 
1186
+ const authStatus = async () => {
1187
+ ${auth ? `const user = await absoluteExpoAuth.status();
1188
+ const principal = getAbsoluteExpoAuthPrincipal();
1189
+ return { principal: principal ? { namespace: principal.namespace } : null, user };` : "throw new Error('Expo Auth is not configured.');"}
1190
+ };
1191
+
1076
1192
  export function AbsoluteWebHost() {
1077
1193
  const pathname = usePathname() || '/';
1078
1194
  const webView = useRef<WebView>(null);
1079
1195
  const [indexUri, setIndexUri] = useState<string>();
1080
1196
  const [canGoBack, setCanGoBack] = useState(false);
1197
+ const [authReady, setAuthReady] = useState(!AUTH_ENABLED);
1081
1198
  const activeWebPath = useRef(pathname);
1082
1199
 
1200
+ useEffect(() => {
1201
+ if (!AUTH_ENABLED) return;
1202
+ let active = true;
1203
+ ${auth ? `const stop = absoluteExpoAuth.onPrincipalChange(principal => {
1204
+ if (!active) return;
1205
+ const source = JSON.stringify({ event: 'auth.principal', format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload: { principal: principal ? { namespace: principal.namespace } : null } });
1206
+ webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
1207
+ });
1208
+ void startAbsoluteExpoAuth().then(() => { if (active) setAuthReady(true); });
1209
+ return () => { active = false; stop(); };` : ""}
1210
+ }, []);
1211
+
1083
1212
  useEffect(() => {
1084
1213
  if (DEV_ORIGIN) {
1085
1214
  const target = new URL(pathname, DEV_ORIGIN);
@@ -1129,6 +1258,16 @@ export function AbsoluteWebHost() {
1129
1258
  respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });
1130
1259
  } else if (message.method === 'http.fetch') {
1131
1260
  respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await bridgeFetch(message.params as Record<string, unknown>) });
1261
+ } else if (message.method === 'auth.signIn') {
1262
+ ${auth ? `const params = message.params as Record<string, unknown>;
1263
+ if (typeof params.email !== 'string' || typeof params.signup !== 'boolean') throw new Error('Expo Auth sign-in params are invalid.');
1264
+ await absoluteExpoAuth.signIn({ authorizationParameters: { login_hint: params.email, ...(params.signup ? { screen_hint: 'signup' } : {}) } });
1265
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });` : "throw new Error('Expo Auth is not configured.');"}
1266
+ } else if (message.method === 'auth.signOut') {
1267
+ ${auth ? `await absoluteExpoAuth.signOut();
1268
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });` : "throw new Error('Expo Auth is not configured.');"}
1269
+ } else if (message.method === 'auth.status') {
1270
+ respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });
1132
1271
  } else {
1133
1272
  throw new Error('Expo bridge method is not allowed.');
1134
1273
  }
@@ -1137,7 +1276,7 @@ export function AbsoluteWebHost() {
1137
1276
  }
1138
1277
  };
1139
1278
 
1140
- if (!indexUri) return <View style={styles.loading}><ActivityIndicator /></View>;
1279
+ if (!indexUri || !authReady) return <View style={styles.loading}><ActivityIndicator /></View>;
1141
1280
  return <WebView
1142
1281
  allowFileAccess
1143
1282
  allowFileAccessFromFileURLs
@@ -1160,9 +1299,17 @@ export function AbsoluteWebHost() {
1160
1299
  const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, justifyContent: 'center' }, web: { flex: 1 } });
1161
1300
  `;
1162
1301
  }, webRouteSource, catchAllRouteSource, nativeWrapperSource = (wrapper, module) => `${EXPO_GENERATED_HEADER}export { default } from ${JSON.stringify(portableRelative(dirname3(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
1163
- `, expoTsConfig = (projectRoot, project) => ({
1302
+ `, expoTsConfig = (projectRoot, project, auth) => ({
1164
1303
  compilerOptions: {
1165
1304
  paths: {
1305
+ ...auth ? {
1306
+ "@absolutejs/auth": [
1307
+ "./node_modules/@absolutejs/auth/dist/index.d.ts"
1308
+ ],
1309
+ "@absolutejs/auth/*": [
1310
+ "./node_modules/@absolutejs/auth/dist/*"
1311
+ ]
1312
+ } : {},
1166
1313
  "*": [
1167
1314
  "./node_modules/*",
1168
1315
  `${portableRelative(project, projectRoot)}/node_modules/*`
@@ -1193,6 +1340,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
1193
1340
  throw new TypeError("Expo project generation requires mobile.engine: expo.");
1194
1341
  const projectRoot = resolve3(options.projectRoot);
1195
1342
  const project = config.nativeProjectDirectory;
1343
+ const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
1196
1344
  const routeModules = Object.entries(config.expoNativeRoutes);
1197
1345
  const moduleChecks = await Promise.all(routeModules.map(async ([route, module]) => ({
1198
1346
  exists: await exists(module),
@@ -1203,7 +1351,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
1203
1351
  if (missing) {
1204
1352
  throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
1205
1353
  }
1206
- const marker = join5(project, EXPO_PROJECT_MARKER);
1354
+ const marker = join6(project, EXPO_PROJECT_MARKER);
1207
1355
  if (await exists(project) && !await exists(marker)) {
1208
1356
  const entries = await readdir(project);
1209
1357
  if (entries.length > 0 && !options.force) {
@@ -1213,47 +1361,54 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
1213
1361
  await mkdir(project, { recursive: true });
1214
1362
  await writeFile(marker, `format=1
1215
1363
  `);
1364
+ const authEnabled = Boolean(auth);
1216
1365
  const files = new Map([
1217
1366
  [
1218
- join5(project, ".gitignore"),
1367
+ join6(project, ".gitignore"),
1219
1368
  `.expo/
1220
1369
  android/
1221
1370
  ios/
1222
1371
  node_modules/
1223
1372
  `
1224
1373
  ],
1225
- [join5(project, "app.json"), jsonSource(expoAppConfig(config))],
1226
- [join5(project, "app.config.js"), expoDynamicAppConfig],
1227
- [join5(project, "package.json"), jsonSource(expoPackage())],
1228
- [join5(project, "metro.config.js"), metroConfig(projectRoot)],
1229
1374
  [
1230
- join5(project, "plugins", "withAbsoluteDevelopmentCa.js"),
1375
+ join6(project, "app.json"),
1376
+ jsonSource(expoAppConfig(config, authEnabled))
1377
+ ],
1378
+ [join6(project, "app.config.js"), expoDynamicAppConfig],
1379
+ [join6(project, "package.json"), jsonSource(expoPackage(authEnabled))],
1380
+ [join6(project, "metro.config.js"), metroConfig(projectRoot)],
1381
+ [
1382
+ join6(project, "plugins", "withAbsoluteDevelopmentCa.js"),
1231
1383
  expoDevelopmentCaPlugin
1232
1384
  ],
1233
1385
  [
1234
- join5(project, "tsconfig.json"),
1235
- jsonSource(expoTsConfig(projectRoot, project))
1386
+ join6(project, "tsconfig.json"),
1387
+ jsonSource(expoTsConfig(projectRoot, project, authEnabled))
1236
1388
  ],
1237
- [join5(project, "app", "_layout.tsx"), layoutSource],
1389
+ [join6(project, "app", "_layout.tsx"), layoutSource(authEnabled)],
1238
1390
  [
1239
- join5(project, "app", "__absolute", "native", "index.tsx"),
1391
+ join6(project, "app", "__absolute", "native", "index.tsx"),
1240
1392
  nativeDiagnosticSource
1241
1393
  ],
1242
1394
  [
1243
- join5(project, "src", "generated", "AbsoluteWebHost.tsx"),
1244
- webHostSource(config)
1395
+ join6(project, "src", "generated", "AbsoluteWebHost.tsx"),
1396
+ webHostSource(config, auth)
1245
1397
  ]
1246
1398
  ]);
1247
- const webAssetsPath = join5(project, "src", "generated", "webAssets.ts");
1399
+ if (auth) {
1400
+ files.set(join6(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
1401
+ }
1402
+ const webAssetsPath = join6(project, "src", "generated", "webAssets.ts");
1248
1403
  if (!await exists(webAssetsPath)) {
1249
1404
  files.set(webAssetsPath, emptyWebAssetsSource);
1250
1405
  }
1251
1406
  if (!config.expoNativeRoutes["/"]) {
1252
- files.set(join5(project, "app", "index.tsx"), webRouteSource);
1407
+ files.set(join6(project, "app", "index.tsx"), webRouteSource);
1253
1408
  }
1254
- files.set(join5(project, "app", "[...absolute].tsx"), catchAllRouteSource);
1409
+ files.set(join6(project, "app", "[...absolute].tsx"), catchAllRouteSource);
1255
1410
  for (const [route, module] of routeModules) {
1256
- const wrapper = route === "/" ? join5(project, "app", "index.tsx") : routeFile(project, route);
1411
+ const wrapper = route === "/" ? join6(project, "app", "index.tsx") : routeFile(project, route);
1257
1412
  files.set(wrapper, nativeWrapperSource(wrapper, module));
1258
1413
  }
1259
1414
  const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
@@ -1262,7 +1417,7 @@ node_modules/
1262
1417
  }, walkFiles = async (root, directory = root) => {
1263
1418
  const entries = await readdir(directory, { withFileTypes: true });
1264
1419
  const nested = await Promise.all(entries.map((entry) => {
1265
- const path = join5(directory, entry.name);
1420
+ const path = join6(directory, entry.name);
1266
1421
  if (entry.isDirectory())
1267
1422
  return walkFiles(root, path);
1268
1423
  if (entry.isFile())
@@ -1323,11 +1478,11 @@ export const materializeAbsoluteWebBundle = async () => {
1323
1478
  `, syncAbsoluteExpoWebAssets = async (config) => {
1324
1479
  if (config.engine !== "expo")
1325
1480
  throw new TypeError("Expo asset sync requires mobile.engine: expo.");
1326
- const marker = join5(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
1481
+ const marker = join6(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
1327
1482
  if (!await exists(marker)) {
1328
1483
  throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
1329
1484
  }
1330
- const manifestPath = join5(config.bundleDirectory, "absolute-mobile-manifest.json");
1485
+ const manifestPath = join6(config.bundleDirectory, "absolute-mobile-manifest.json");
1331
1486
  const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
1332
1487
  const appBuild = typeof manifest === "object" && manifest !== null && typeof Reflect.get(manifest, "appBuild") === "string" ? String(Reflect.get(manifest, "appBuild")) : undefined;
1333
1488
  if (!appBuild)
@@ -1342,16 +1497,16 @@ export const materializeAbsoluteWebBundle = async () => {
1342
1497
  bundleHash.update("\x00");
1343
1498
  });
1344
1499
  const bundleId = `amexpo_${bundleHash.digest("hex")}`;
1345
- const destination = join5(config.nativeProjectDirectory, "assets", "absolute");
1500
+ const destination = join6(config.nativeProjectDirectory, "assets", "absolute");
1346
1501
  await mkdir(dirname3(destination), { recursive: true });
1347
- const staging = await mkdtemp(join5(dirname3(destination), `.${basename2(destination)}.stage-`));
1502
+ const staging = await mkdtemp(join6(dirname3(destination), `.${basename2(destination)}.stage-`));
1348
1503
  let assets;
1349
1504
  try {
1350
1505
  assets = await Promise.all(files.map(async (source, index) => {
1351
1506
  const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
1352
- await cp(source, join5(staging, name));
1507
+ await cp(source, join6(staging, name));
1353
1508
  return {
1354
- asset: portableRelative(join5(config.nativeProjectDirectory, "src", "generated"), join5(destination, name)),
1509
+ asset: portableRelative(join6(config.nativeProjectDirectory, "src", "generated"), join6(destination, name)),
1355
1510
  path: relative(config.bundleDirectory, source).replaceAll("\\", "/")
1356
1511
  };
1357
1512
  }));
@@ -1360,11 +1515,12 @@ export const materializeAbsoluteWebBundle = async () => {
1360
1515
  await rm(staging, { force: true, recursive: true });
1361
1516
  throw error;
1362
1517
  }
1363
- const generated = join5(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
1518
+ const generated = join6(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
1364
1519
  await writeManagedFile(generated, assetModuleSource(assets, bundleId), true);
1365
1520
  return { appBuild, assets: assets.length, bundleId, path: destination };
1366
1521
  };
1367
1522
  var init_expoProject = __esm(() => {
1523
+ init_nativeAuth();
1368
1524
  expoDynamicAppConfig = `${EXPO_GENERATED_HEADER}const config = require('./app.json');
1369
1525
 
1370
1526
  if (process.env.ABSOLUTE_EXPO_DEVELOPMENT === '1' && process.env.ABSOLUTE_EXPO_DEVELOPMENT_CA_PATH) {
@@ -1415,12 +1571,6 @@ const withAbsoluteDevelopmentCa = config => {
1415
1571
  };
1416
1572
 
1417
1573
  module.exports = withAbsoluteDevelopmentCa;
1418
- `;
1419
- layoutSource = `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
1420
-
1421
- export default function AbsoluteLayout() {
1422
- return <Stack screenOptions={{ headerShown: false }} />;
1423
- }
1424
1574
  `;
1425
1575
  nativeDiagnosticSource = `${EXPO_GENERATED_HEADER}import * as Haptics from 'expo-haptics';
1426
1576
  import { Link } from 'expo-router';
@@ -1558,50 +1708,6 @@ var closeServer = (server) => new Promise((resolve4, reject) => {
1558
1708
  };
1559
1709
  var init_iosPhysicalDeviceTransport = () => {};
1560
1710
 
1561
- // src/mobile/nativeAuth.ts
1562
- import { readFileSync as readFileSync5 } from "fs";
1563
- import { join as join7 } from "path";
1564
- var ABSOLUTE_AUTH_PACKAGE = "@absolutejs/auth", ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV = "ABSOLUTE_AUTH_NATIVE_CLIENTS", ABSOLUTE_NATIVE_AUTH_SCOPES, ABSOLUTE_SYNC_PACKAGE = "@absolutejs/sync", readPackageManifest = (projectRoot) => {
1565
- try {
1566
- return JSON.parse(readFileSync5(join7(projectRoot, "package.json"), "utf8"));
1567
- } catch {
1568
- return;
1569
- }
1570
- }, packageManifestHas = (manifest, packageName) => {
1571
- if (typeof manifest !== "object" || manifest === null)
1572
- return false;
1573
- return [
1574
- Reflect.get(manifest, "dependencies"),
1575
- Reflect.get(manifest, "devDependencies"),
1576
- Reflect.get(manifest, "optionalDependencies"),
1577
- Reflect.get(manifest, "peerDependencies")
1578
- ].some((dependencies) => typeof dependencies === "object" && dependencies !== null && Object.hasOwn(dependencies, packageName));
1579
- }, createAbsoluteMobileAuthManifest = (config) => {
1580
- const scheme = config.deepLinkScheme ?? config.appId.toLowerCase();
1581
- return {
1582
- clientId: `absolutejs-native:${config.appId}`,
1583
- issuer: config.productionOrigin,
1584
- redirectUri: `${scheme}://auth/callback`,
1585
- scopes: [...ABSOLUTE_NATIVE_AUTH_SCOPES]
1586
- };
1587
- }, installAbsoluteMobileAuthEnvironment = (projectRoot, config) => {
1588
- const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
1589
- const serialized = serializeAbsoluteMobileAuthEnvironment(config, auth);
1590
- if (serialized === undefined)
1591
- delete process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV];
1592
- else
1593
- process.env[ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV] = serialized;
1594
- return auth;
1595
- }, projectUsesAbsoluteAuth = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_AUTH_PACKAGE), projectUsesAbsoluteSync = (projectRoot) => packageManifestHas(readPackageManifest(projectRoot), ABSOLUTE_SYNC_PACKAGE), resolveAbsoluteMobileAuthManifest = (projectRoot, config) => projectUsesAbsoluteAuth(projectRoot) ? createAbsoluteMobileAuthManifest(config) : undefined, serializeAbsoluteMobileAuthEnvironment = (config, auth) => auth === undefined ? undefined : JSON.stringify([
1596
- {
1597
- ...auth,
1598
- name: `${config.appName} native app`
1599
- }
1600
- ]);
1601
- var init_nativeAuth = __esm(() => {
1602
- ABSOLUTE_NATIVE_AUTH_SCOPES = ["openid", "profile"];
1603
- });
1604
-
1605
1711
  // src/cli/utils.ts
1606
1712
  var {$: $2 } = globalThis.Bun;
1607
1713
  import { execSync } from "child_process";
@@ -5178,13 +5284,13 @@ var init_remoteMacProtocol = __esm(() => {
5178
5284
  // src/dev/devCert.ts
5179
5285
  var exports_devCert = {};
5180
5286
  __export(exports_devCert, {
5181
- setupMkcert: () => setupMkcert,
5182
- normalizeDevCertificateHosts: () => normalizeDevCertificateHosts,
5183
- loadDevCert: () => loadDevCert,
5184
- hasMkcert: () => hasMkcert,
5185
- hasCert: () => hasCert,
5287
+ ensureDevCert: () => ensureDevCert,
5186
5288
  getDevCertificateAuthorityPath: () => getDevCertificateAuthorityPath,
5187
- ensureDevCert: () => ensureDevCert
5289
+ hasCert: () => hasCert,
5290
+ hasMkcert: () => hasMkcert,
5291
+ loadDevCert: () => loadDevCert,
5292
+ normalizeDevCertificateHosts: () => normalizeDevCertificateHosts,
5293
+ setupMkcert: () => setupMkcert
5188
5294
  });
5189
5295
  import {
5190
5296
  copyFileSync,
@@ -5492,13 +5598,13 @@ var init_devCert = __esm(() => {
5492
5598
  // src/cli/scripts/eslintChunked.ts
5493
5599
  var exports_eslintChunked = {};
5494
5600
  __export(exports_eslintChunked, {
5495
- upstreamRef: () => upstreamRef,
5496
- ruleSummary: () => ruleSummary,
5497
- resolveLintTargets: () => resolveLintTargets,
5498
- parseChunkedArgs: () => parseChunkedArgs,
5499
- gitVisibleFiles: () => gitVisibleFiles,
5601
+ eslintChunked: () => eslintChunked,
5500
5602
  gitChangedFiles: () => gitChangedFiles,
5501
- eslintChunked: () => eslintChunked
5603
+ gitVisibleFiles: () => gitVisibleFiles,
5604
+ parseChunkedArgs: () => parseChunkedArgs,
5605
+ resolveLintTargets: () => resolveLintTargets,
5606
+ ruleSummary: () => ruleSummary,
5607
+ upstreamRef: () => upstreamRef
5502
5608
  });
5503
5609
  import { existsSync as existsSync6 } from "fs";
5504
5610
  import { relative as relative7, resolve as resolve9 } from "path";
@@ -7144,6 +7250,11 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
7144
7250
  if (candidate)
7145
7251
  return candidate;
7146
7252
  throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
7253
+ }, shellExpoAuthModule = () => {
7254
+ const candidate = ["js", "ts"].map((extension) => join19(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync9);
7255
+ if (candidate)
7256
+ return candidate;
7257
+ throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
7147
7258
  }, shellSyncModule = () => {
7148
7259
  const candidate = ["js", "ts"].map((extension) => join19(import.meta.dir, `shellSync.${extension}`)).find(existsSync9);
7149
7260
  if (candidate)
@@ -7217,9 +7328,10 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
7217
7328
  const capacitor = engine !== "expo";
7218
7329
  const shellCapabilities = capacitor ? deviceCapabilities.capabilities : [];
7219
7330
  const modulePath = shellBootstrapModule();
7220
- const authImport = auth ? `import { createAbsoluteMobileShellAuth } from ${JSON.stringify(shellAuthModule())};
7331
+ const authFactory = capacitor ? "createAbsoluteMobileShellAuth" : "createAbsoluteExpoShellAuth";
7332
+ const authImport = auth ? `import { ${authFactory} } from ${JSON.stringify(capacitor ? shellAuthModule() : shellExpoAuthModule())};
7221
7333
  ` : "";
7222
- const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
7334
+ const options = auth ? `{ createAuth: ${authFactory}${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
7223
7335
  const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
7224
7336
  ` : "";
7225
7337
  const pushIndex = shellCapabilities.indexOf("pushNotifications");
@@ -7241,7 +7353,7 @@ const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absolu
7241
7353
  const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
7242
7354
  const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
7243
7355
  const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : "installAbsoluteExpoWebDeviceAdapter();";
7244
- let shellOptions = "{ createFetch: createAbsoluteExpoBridgeFetch }";
7356
+ let shellOptions = auth ? options : "{ createFetch: createAbsoluteExpoBridgeFetch }";
7245
7357
  if (capacitor)
7246
7358
  shellOptions = options;
7247
7359
  if (push) {
@@ -8327,10 +8439,10 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
8327
8439
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
8328
8440
  });
8329
8441
  const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
8330
- if (mobile.engine === "expo" && auth) {
8331
- throw new TypeError("Expo mobile Auth is not released yet. The experimental Expo shell cannot safely substitute Capacitor credentials; remove engine: 'expo' or wait for @absolutejs/auth-expo.");
8332
- }
8333
8442
  const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
8443
+ if (mobile.engine === "expo" && sync) {
8444
+ throw new TypeError("Expo mobile Sync is not released yet. Auth and authenticated HTTP are available, but @absolutejs/sync requires @absolutejs/sync-expo for shared durable state.");
8445
+ }
8334
8446
  const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
8335
8447
  const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
8336
8448
  const usesPush = deviceCapabilities.capabilities.includes("pushNotifications");
@@ -8956,12 +9068,12 @@ var init_serverBundleExternals = __esm(() => {
8956
9068
  // src/core/prerender.ts
8957
9069
  var exports_prerender = {};
8958
9070
  __export(exports_prerender, {
8959
- routeToFilename: () => routeToFilename,
8960
- rerenderRoute: () => rerenderRoute,
8961
- readTimestamp: () => readTimestamp,
8962
- prerenderWithServer: () => prerenderWithServer,
9071
+ PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER,
8963
9072
  prerender: () => prerender,
8964
- PRERENDER_BYPASS_HEADER: () => PRERENDER_BYPASS_HEADER
9073
+ prerenderWithServer: () => prerenderWithServer,
9074
+ readTimestamp: () => readTimestamp,
9075
+ rerenderRoute: () => rerenderRoute,
9076
+ routeToFilename: () => routeToFilename
8965
9077
  });
8966
9078
  import { mkdirSync as mkdirSync6, readFileSync as readFileSync14 } from "fs";
8967
9079
  import { join as join24 } from "path";
@@ -9621,8 +9733,8 @@ var init_rewriteImportsPlugin = __esm(() => {
9621
9733
  // src/build/rewriteImports.ts
9622
9734
  var exports_rewriteImports = {};
9623
9735
  __export(exports_rewriteImports, {
9624
- rewriteVendorDirectories: () => rewriteVendorDirectories2,
9625
- rewriteImports: () => rewriteImports
9736
+ rewriteImports: () => rewriteImports,
9737
+ rewriteVendorDirectories: () => rewriteVendorDirectories2
9626
9738
  });
9627
9739
  var rewriteImports = async (outputPaths, vendorPaths) => {
9628
9740
  const jsFiles = outputPaths.filter((path) => path.endsWith(".js"));
@@ -10285,11 +10397,11 @@ var init_build = __esm(() => {
10285
10397
  // src/cli/scripts/lintProof.ts
10286
10398
  var exports_lintProof = {};
10287
10399
  __export(exports_lintProof, {
10288
- writeLintProof: () => writeLintProof,
10289
- verifyLintProof: () => verifyLintProof,
10290
- runLintProof: () => runLintProof,
10400
+ createLintProof: () => createLintProof,
10291
10401
  createLintSourceTree: () => createLintSourceTree,
10292
- createLintProof: () => createLintProof
10402
+ runLintProof: () => runLintProof,
10403
+ verifyLintProof: () => verifyLintProof,
10404
+ writeLintProof: () => writeLintProof
10293
10405
  });
10294
10406
  import {
10295
10407
  createHash as createHash12,
@@ -15063,9 +15175,9 @@ var init_htmx = __esm(() => {
15063
15175
  // src/cli/scripts/env.ts
15064
15176
  var exports_env = {};
15065
15177
  __export(exports_env, {
15066
- scanEnvUsage: () => scanEnvUsage,
15178
+ collectEnvVars: () => collectEnvVars,
15067
15179
  runEnv: () => runEnv,
15068
- collectEnvVars: () => collectEnvVars
15180
+ scanEnvUsage: () => scanEnvUsage
15069
15181
  });
15070
15182
  import { existsSync as existsSync33, readFileSync as readFileSync33 } from "fs";
15071
15183
  import { join as join41 } from "path";
@@ -15129,12 +15241,12 @@ var init_env = __esm(() => {
15129
15241
  // src/cli/scripts/db.ts
15130
15242
  var exports_db = {};
15131
15243
  __export(exports_db, {
15132
- runDb: () => runDb,
15133
- quoteIdent: () => quoteIdent,
15134
- encodeValue: () => encodeValue,
15135
- dependencyOrder: () => dependencyOrder,
15244
+ chunkRows: () => chunkRows,
15136
15245
  conflictClause: () => conflictClause,
15137
- chunkRows: () => chunkRows
15246
+ dependencyOrder: () => dependencyOrder,
15247
+ encodeValue: () => encodeValue,
15248
+ quoteIdent: () => quoteIdent,
15249
+ runDb: () => runDb
15138
15250
  });
15139
15251
  import { existsSync as existsSync34, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync18 } from "fs";
15140
15252
  import { join as join42 } from "path";
@@ -16474,8 +16586,8 @@ var init_externalAssetPlugin = () => {};
16474
16586
  // src/cli/scripts/compile.ts
16475
16587
  var exports_compile = {};
16476
16588
  __export(exports_compile, {
16477
- shouldEmbedCompiledAsset: () => shouldEmbedCompiledAsset,
16478
- compile: () => compile
16589
+ compile: () => compile,
16590
+ shouldEmbedCompiledAsset: () => shouldEmbedCompiledAsset
16479
16591
  });
16480
16592
  var {env: env5 } = globalThis.Bun;
16481
16593
  import {
@@ -18434,12 +18546,38 @@ import { mkdir as mkdir12, writeFile as writeFile14 } from "fs/promises";
18434
18546
  import { dirname as dirname29, resolve as resolve38 } from "path";
18435
18547
 
18436
18548
  class CdpConnection {
18437
- diagnostics = [];
18438
- socket;
18439
- #closed = false;
18440
- #nextId = 1;
18441
- #pending = new Map;
18549
+ #closed;
18550
+ #nextId;
18551
+ #pending;
18442
18552
  constructor(socket) {
18553
+ this.diagnostics = [];
18554
+ this.#closed = false;
18555
+ this.#nextId = 1;
18556
+ this.#pending = new Map;
18557
+ this.command = (method, params = {}, timeoutMs = CDP_COMMAND_TIMEOUT_MS) => {
18558
+ if (this.#closed) {
18559
+ return Promise.reject(new Error("Android WebView debugger is closed."));
18560
+ }
18561
+ const id = this.#nextId++;
18562
+ return new Promise((_resolve, reject) => {
18563
+ const timer = setTimeout(() => {
18564
+ this.#pending.delete(id);
18565
+ reject(new Error(`CDP ${method} timed out after ${timeoutMs}ms.`));
18566
+ }, timeoutMs);
18567
+ this.#pending.set(id, {
18568
+ reject,
18569
+ resolve: _resolve,
18570
+ timer
18571
+ });
18572
+ this.socket.send(JSON.stringify({ id, method, params }));
18573
+ });
18574
+ };
18575
+ this.close = async () => {
18576
+ if (this.#closed)
18577
+ return;
18578
+ this.#closed = true;
18579
+ this.socket.close();
18580
+ };
18443
18581
  this.socket = socket;
18444
18582
  socket.addEventListener("message", (event) => {
18445
18583
  this.onMessage(event.data);
@@ -18518,30 +18656,6 @@ class CdpConnection {
18518
18656
  }
18519
18657
  pending.resolve(message.result);
18520
18658
  }
18521
- command = (method, params = {}, timeoutMs = CDP_COMMAND_TIMEOUT_MS) => {
18522
- if (this.#closed) {
18523
- return Promise.reject(new Error("Android WebView debugger is closed."));
18524
- }
18525
- const id = this.#nextId++;
18526
- return new Promise((_resolve, reject) => {
18527
- const timer = setTimeout(() => {
18528
- this.#pending.delete(id);
18529
- reject(new Error(`CDP ${method} timed out after ${timeoutMs}ms.`));
18530
- }, timeoutMs);
18531
- this.#pending.set(id, {
18532
- reject,
18533
- resolve: _resolve,
18534
- timer
18535
- });
18536
- this.socket.send(JSON.stringify({ id, method, params }));
18537
- });
18538
- };
18539
- close = async () => {
18540
- if (this.#closed)
18541
- return;
18542
- this.#closed = true;
18543
- this.socket.close();
18544
- };
18545
18659
  }
18546
18660
  var CDP_COMMAND_TIMEOUT_MS = 1e4, WEBVIEW_ATTACH_TIMEOUT_MS = 30000, WEBVIEW_POLL_MS = 200, captureCommand3 = (command) => {
18547
18661
  const result = Bun.spawnSync(command, {
@@ -21019,7 +21133,7 @@ var NOT_FOUND4 = -1, isRecord15 = (value) => typeof value === "object" && value
21019
21133
  }, initialize = async (args) => {
21020
21134
  const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
21021
21135
  if (mobile.engine === "expo") {
21022
- console.warn("Experimental: Expo Auth, Sync, release publishing, and physical-device acceptance are not complete.");
21136
+ console.warn("Experimental: Expo Auth and authenticated HTTP are available; Sync, release publishing, and physical-device acceptance are not complete.");
21023
21137
  const generated2 = await writeAbsoluteExpoProject(mobile, {
21024
21138
  force: args.includes("--force"),
21025
21139
  projectRoot
@@ -23455,7 +23569,7 @@ init_expoProject();
23455
23569
  init_iosPhysicalDeviceTransport();
23456
23570
  import { spawn } from "child_process";
23457
23571
  import { access as access2 } from "fs/promises";
23458
- import { join as join6 } from "path";
23572
+ import { join as join7 } from "path";
23459
23573
  var METRO_READY_TIMEOUT_MS = 60000;
23460
23574
  var PROCESS_CLOSE_TIMEOUT_MS = 2000;
23461
23575
  var commandEnvironment = (options) => ({
@@ -23468,7 +23582,7 @@ var commandEnvironment = (options) => ({
23468
23582
  ...options.metroHost ? { REACT_NATIVE_PACKAGER_HOSTNAME: options.metroHost } : {}
23469
23583
  });
23470
23584
  var absoluteExpoExecutable = async (project) => {
23471
- const executable = join6(project, "node_modules", ".bin", "expo");
23585
+ const executable = join7(project, "node_modules", ".bin", "expo");
23472
23586
  try {
23473
23587
  await access2(executable);
23474
23588
  return executable;