@absolutejs/absolute 0.20.0-beta.40 → 0.20.0-beta.41
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/README.md +3 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +5 -1
- package/dist/build.js.map +3 -3
- package/dist/cli/index.js +7794 -7326
- package/dist/dev/client/hmrTiming.ts +4 -0
- package/dist/index.js +26 -4
- package/dist/index.js.map +4 -4
- package/dist/mobile/index.js +348 -35
- package/dist/mobile/index.js.map +6 -5
- package/dist/src/mobile/devDeviceAdapter.d.ts +1 -1
- package/dist/src/mobile/expoDevController.d.ts +49 -0
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/types/messages.d.ts +1 -1
- package/package.json +1 -1
package/dist/mobile/index.js
CHANGED
|
@@ -862,7 +862,7 @@ var init_deviceCapabilities = __esm(() => {
|
|
|
862
862
|
// src/cli/scripts/telemetry.ts
|
|
863
863
|
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync5, writeFileSync } from "fs";
|
|
864
864
|
import { homedir as homedir3 } from "os";
|
|
865
|
-
import { join as
|
|
865
|
+
import { join as join17 } from "path";
|
|
866
866
|
var configDir, configPath, getTelemetryConfig = () => {
|
|
867
867
|
try {
|
|
868
868
|
if (!existsSync4(configPath))
|
|
@@ -875,14 +875,14 @@ var configDir, configPath, getTelemetryConfig = () => {
|
|
|
875
875
|
}
|
|
876
876
|
};
|
|
877
877
|
var init_telemetry = __esm(() => {
|
|
878
|
-
configDir =
|
|
879
|
-
configPath =
|
|
878
|
+
configDir = join17(homedir3(), ".absolutejs");
|
|
879
|
+
configPath = join17(configDir, "telemetry.json");
|
|
880
880
|
});
|
|
881
881
|
|
|
882
882
|
// src/cli/telemetryEvent.ts
|
|
883
883
|
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
|
|
884
884
|
import { arch, platform } from "os";
|
|
885
|
-
import { dirname as dirname12, join as
|
|
885
|
+
import { dirname as dirname12, join as join18, parse } from "path";
|
|
886
886
|
var checkCandidate = (candidate) => {
|
|
887
887
|
if (!existsSync5(candidate)) {
|
|
888
888
|
return null;
|
|
@@ -902,7 +902,7 @@ var checkCandidate = (candidate) => {
|
|
|
902
902
|
}, findPackageVersion = () => {
|
|
903
903
|
let { dir } = import.meta;
|
|
904
904
|
while (dir !== parse(dir).root) {
|
|
905
|
-
const candidate =
|
|
905
|
+
const candidate = join18(dir, "package.json");
|
|
906
906
|
const version = checkCandidate(candidate);
|
|
907
907
|
if (version) {
|
|
908
908
|
return version;
|
|
@@ -6037,6 +6037,7 @@ var expoPackage = () => ({
|
|
|
6037
6037
|
expo: "~57.0.9",
|
|
6038
6038
|
"expo-asset": "~57.0.15",
|
|
6039
6039
|
"expo-constants": "~57.0.16",
|
|
6040
|
+
"expo-dev-client": "~57.0.16",
|
|
6040
6041
|
"expo-file-system": "~57.0.6",
|
|
6041
6042
|
"expo-haptics": "~57.0.2",
|
|
6042
6043
|
"expo-linking": "~57.0.8",
|
|
@@ -6079,7 +6080,10 @@ var expoAppConfig = (config) => ({
|
|
|
6079
6080
|
...config.iosVersion ? { buildNumber: config.iosVersion } : {}
|
|
6080
6081
|
},
|
|
6081
6082
|
name: config.appName,
|
|
6082
|
-
plugins: [
|
|
6083
|
+
plugins: [
|
|
6084
|
+
"expo-router",
|
|
6085
|
+
["expo-dev-client", { launchMode: "most-recent" }]
|
|
6086
|
+
],
|
|
6083
6087
|
runtimeVersion: { policy: "appVersion" },
|
|
6084
6088
|
scheme: config.deepLinkScheme,
|
|
6085
6089
|
slug: config.appId.toLowerCase().replaceAll(".", "-"),
|
|
@@ -6147,7 +6151,7 @@ var webHostSource = (config) => {
|
|
|
6147
6151
|
import * as Linking from 'expo-linking';
|
|
6148
6152
|
import { router, usePathname } from 'expo-router';
|
|
6149
6153
|
import { useEffect, useRef, useState } from 'react';
|
|
6150
|
-
import { ActivityIndicator, BackHandler, StyleSheet, View } from 'react-native';
|
|
6154
|
+
import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
|
|
6151
6155
|
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
6152
6156
|
import { materializeAbsoluteWebBundle } from './webAssets';
|
|
6153
6157
|
|
|
@@ -6156,11 +6160,19 @@ const MAX_MESSAGE_BYTES = 64 * 1024;
|
|
|
6156
6160
|
const MAX_HTTP_BODY_BYTES = 48 * 1024;
|
|
6157
6161
|
const NATIVE_ROUTES = new Set(${JSON.stringify(nativeRoutes)});
|
|
6158
6162
|
const PRODUCTION_ORIGIN = ${JSON.stringify(config.productionOrigin)};
|
|
6163
|
+
const DEV_ORIGIN = Platform.OS === 'android'
|
|
6164
|
+
? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
|
|
6165
|
+
: process.env.EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN;
|
|
6166
|
+
const HMR_TARGET = Platform.OS === 'android' ? 'expo-android' : 'expo-ios';
|
|
6159
6167
|
|
|
6160
|
-
const bridgeBootstrap = (path: string) =>
|
|
6168
|
+
const bridgeBootstrap = (path: string) => {
|
|
6169
|
+
const initialPath = DEV_ORIGIN
|
|
6170
|
+
? 'location.pathname + location.search + location.hash'
|
|
6171
|
+
: JSON.stringify(path);
|
|
6172
|
+
return \`(() => {
|
|
6161
6173
|
const pending = new Map();
|
|
6162
6174
|
let sequence = 0;
|
|
6163
|
-
let currentPath = \${
|
|
6175
|
+
let currentPath = \${initialPath};
|
|
6164
6176
|
const send = value => {
|
|
6165
6177
|
const source = JSON.stringify(value);
|
|
6166
6178
|
if (new TextEncoder().encode(source).byteLength > 65536) throw new Error('Expo bridge message exceeds 64 KiB.');
|
|
@@ -6191,6 +6203,24 @@ const bridgeBootstrap = (path: string) => \`(() => {
|
|
|
6191
6203
|
send({ format: 1, kind: 'event', event: 'navigation', path });
|
|
6192
6204
|
}
|
|
6193
6205
|
};
|
|
6206
|
+
if (\${DEV_ORIGIN ? 'true' : 'false'}) {
|
|
6207
|
+
const publishPath = () => {
|
|
6208
|
+
const path = location.pathname + location.search + location.hash;
|
|
6209
|
+
if (path === currentPath) return;
|
|
6210
|
+
currentPath = path;
|
|
6211
|
+
send({ format: 1, kind: 'event', event: 'navigation', path });
|
|
6212
|
+
};
|
|
6213
|
+
for (const method of ['pushState', 'replaceState']) {
|
|
6214
|
+
const original = history[method];
|
|
6215
|
+
history[method] = function(...args) {
|
|
6216
|
+
const result = original.apply(this, args);
|
|
6217
|
+
publishPath();
|
|
6218
|
+
return result;
|
|
6219
|
+
};
|
|
6220
|
+
}
|
|
6221
|
+
addEventListener('popstate', publishPath);
|
|
6222
|
+
addEventListener('hashchange', publishPath);
|
|
6223
|
+
}
|
|
6194
6224
|
document.addEventListener('click', event => {
|
|
6195
6225
|
const anchor = event.target instanceof Element ? event.target.closest('a[href]') : null;
|
|
6196
6226
|
if (!anchor) return;
|
|
@@ -6199,8 +6229,9 @@ const bridgeBootstrap = (path: string) => \`(() => {
|
|
|
6199
6229
|
event.preventDefault();
|
|
6200
6230
|
send({ format: 1, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
|
|
6201
6231
|
}, true);
|
|
6202
|
-
send({ format: 1, kind: 'event', event: 'ready', path:
|
|
6232
|
+
send({ format: 1, kind: 'event', event: 'ready', path: currentPath });
|
|
6203
6233
|
})(); true;\`;
|
|
6234
|
+
};
|
|
6204
6235
|
|
|
6205
6236
|
const impact = async (params: Record<string, unknown>) => {
|
|
6206
6237
|
const style = params.style;
|
|
@@ -6242,7 +6273,15 @@ export function AbsoluteWebHost() {
|
|
|
6242
6273
|
const [canGoBack, setCanGoBack] = useState(false);
|
|
6243
6274
|
const activeWebPath = useRef(pathname);
|
|
6244
6275
|
|
|
6245
|
-
useEffect(() => {
|
|
6276
|
+
useEffect(() => {
|
|
6277
|
+
if (DEV_ORIGIN) {
|
|
6278
|
+
const target = new URL(pathname, DEV_ORIGIN);
|
|
6279
|
+
target.searchParams.set('__absolute_target', HMR_TARGET);
|
|
6280
|
+
setIndexUri(target.href);
|
|
6281
|
+
return;
|
|
6282
|
+
}
|
|
6283
|
+
void materializeAbsoluteWebBundle().then(uri => setIndexUri(uri + '?absolutePath=' + encodeURIComponent(pathname)));
|
|
6284
|
+
}, [pathname]);
|
|
6246
6285
|
useEffect(() => {
|
|
6247
6286
|
const subscription = BackHandler.addEventListener('hardwareBackPress', () => {
|
|
6248
6287
|
if (!canGoBack) return false;
|
|
@@ -6257,6 +6296,9 @@ export function AbsoluteWebHost() {
|
|
|
6257
6296
|
if (new TextEncoder().encode(source).byteLength > MAX_MESSAGE_BYTES) throw new Error('Expo bridge response exceeds 64 KiB.');
|
|
6258
6297
|
webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
|
|
6259
6298
|
};
|
|
6299
|
+
const hasOrigin = (source: string, origin: string) => {
|
|
6300
|
+
try { return new URL(source).origin === origin; } catch { return false; }
|
|
6301
|
+
};
|
|
6260
6302
|
const onMessage = async (event: WebViewMessageEvent) => {
|
|
6261
6303
|
const source = event.nativeEvent.data;
|
|
6262
6304
|
if (new TextEncoder().encode(source).byteLength > MAX_MESSAGE_BYTES) return;
|
|
@@ -6298,12 +6340,12 @@ export function AbsoluteWebHost() {
|
|
|
6298
6340
|
onMessage={onMessage}
|
|
6299
6341
|
onNavigationStateChange={state => setCanGoBack(state.canGoBack)}
|
|
6300
6342
|
onShouldStartLoadWithRequest={request => {
|
|
6301
|
-
if (request.url.startsWith('file:') || request.url
|
|
6343
|
+
if (request.url.startsWith('file:') || hasOrigin(request.url, PRODUCTION_ORIGIN) || DEV_ORIGIN && hasOrigin(request.url, DEV_ORIGIN)) return true;
|
|
6302
6344
|
void Linking.openURL(request.url);
|
|
6303
6345
|
return false;
|
|
6304
6346
|
}}
|
|
6305
6347
|
ref={webView}
|
|
6306
|
-
source={{ uri: indexUri
|
|
6348
|
+
source={{ uri: indexUri }}
|
|
6307
6349
|
style={styles.web}
|
|
6308
6350
|
/>;
|
|
6309
6351
|
}
|
|
@@ -6352,6 +6394,10 @@ var writeManagedFile = async (path, source, force) => {
|
|
|
6352
6394
|
};
|
|
6353
6395
|
var jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
6354
6396
|
`;
|
|
6397
|
+
var emptyWebAssetsSource = `${EXPO_GENERATED_HEADER}export const materializeAbsoluteWebBundle = async () => {
|
|
6398
|
+
throw new Error('The embedded AbsoluteJS bundle is unavailable. Run absolute prepare before a production Expo build.');
|
|
6399
|
+
};
|
|
6400
|
+
`;
|
|
6355
6401
|
var writeAbsoluteExpoProject = async (config, options) => {
|
|
6356
6402
|
if (config.engine !== "expo")
|
|
6357
6403
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
@@ -6403,6 +6449,10 @@ node_modules/
|
|
|
6403
6449
|
webHostSource(config)
|
|
6404
6450
|
]
|
|
6405
6451
|
]);
|
|
6452
|
+
const webAssetsPath = join14(project, "src", "generated", "webAssets.ts");
|
|
6453
|
+
if (!await exists3(webAssetsPath)) {
|
|
6454
|
+
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
6455
|
+
}
|
|
6406
6456
|
if (!config.expoNativeRoutes["/"]) {
|
|
6407
6457
|
files.set(join14(project, "app", "index.tsx"), webRouteSource);
|
|
6408
6458
|
}
|
|
@@ -6902,9 +6952,269 @@ var parseAbsoluteExpoBridgeMessage = (source) => {
|
|
|
6902
6952
|
return parseEvent(parsed);
|
|
6903
6953
|
throw new TypeError("Expo bridge message kind is unsupported.");
|
|
6904
6954
|
};
|
|
6955
|
+
// src/mobile/expoDevController.ts
|
|
6956
|
+
import { spawn } from "child_process";
|
|
6957
|
+
import { access as access10 } from "fs/promises";
|
|
6958
|
+
import { join as join16 } from "path";
|
|
6959
|
+
var METRO_READY_TIMEOUT_MS = 60000;
|
|
6960
|
+
var PROCESS_CLOSE_TIMEOUT_MS = 2000;
|
|
6961
|
+
var commandEnvironment = (options) => ({
|
|
6962
|
+
ABSOLUTE_EXPO_DEVELOPMENT: "1",
|
|
6963
|
+
...options.androidOrigin ? { EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN: options.androidOrigin } : {},
|
|
6964
|
+
...options.iosOrigin ? { EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN: options.iosOrigin } : {}
|
|
6965
|
+
});
|
|
6966
|
+
var absoluteExpoExecutable = async (project) => {
|
|
6967
|
+
const executable = join16(project, "node_modules", ".bin", "expo");
|
|
6968
|
+
try {
|
|
6969
|
+
await access10(executable);
|
|
6970
|
+
return executable;
|
|
6971
|
+
} catch {
|
|
6972
|
+
throw new TypeError("Expo dependencies are not installed in the generated shell. Run `absolute mobile init --yes`.");
|
|
6973
|
+
}
|
|
6974
|
+
};
|
|
6975
|
+
var planAbsoluteExpoDevSession = (config, options) => {
|
|
6976
|
+
if (config.engine !== "expo")
|
|
6977
|
+
throw new TypeError("The Expo development controller requires Expo.");
|
|
6978
|
+
if (options.platforms.length === 0)
|
|
6979
|
+
throw new TypeError("Expo development requires a local target platform.");
|
|
6980
|
+
const env = commandEnvironment(options);
|
|
6981
|
+
const metro = {
|
|
6982
|
+
args: [
|
|
6983
|
+
"start",
|
|
6984
|
+
"--dev-client",
|
|
6985
|
+
"--host",
|
|
6986
|
+
"localhost",
|
|
6987
|
+
"--port",
|
|
6988
|
+
String(options.metroPort)
|
|
6989
|
+
],
|
|
6990
|
+
env,
|
|
6991
|
+
role: "metro"
|
|
6992
|
+
};
|
|
6993
|
+
const prepare = {
|
|
6994
|
+
args: [
|
|
6995
|
+
"prebuild",
|
|
6996
|
+
"--clean",
|
|
6997
|
+
"--no-install",
|
|
6998
|
+
"--platform",
|
|
6999
|
+
options.platforms.length === 2 ? "all" : options.platforms[0] ?? "all"
|
|
7000
|
+
],
|
|
7001
|
+
env,
|
|
7002
|
+
role: "native-prepare"
|
|
7003
|
+
};
|
|
7004
|
+
const native = options.platforms.map((platform) => {
|
|
7005
|
+
const device = platform === "android" ? options.androidDevice : options.iosDevice;
|
|
7006
|
+
const command = {
|
|
7007
|
+
args: [
|
|
7008
|
+
`run:${platform}`,
|
|
7009
|
+
"--no-bundler",
|
|
7010
|
+
"--port",
|
|
7011
|
+
String(options.metroPort),
|
|
7012
|
+
...device ? ["--device", device] : []
|
|
7013
|
+
],
|
|
7014
|
+
env,
|
|
7015
|
+
platform,
|
|
7016
|
+
role: "native-build"
|
|
7017
|
+
};
|
|
7018
|
+
return command;
|
|
7019
|
+
});
|
|
7020
|
+
return {
|
|
7021
|
+
commands: [prepare, metro, ...native],
|
|
7022
|
+
metroPort: options.metroPort,
|
|
7023
|
+
project: config.nativeProjectDirectory
|
|
7024
|
+
};
|
|
7025
|
+
};
|
|
7026
|
+
var abortError = () => new DOMException("Expo development aborted.", "AbortError");
|
|
7027
|
+
var forwardLines = (process2, onLine) => {
|
|
7028
|
+
const attach = (stream) => {
|
|
7029
|
+
if (!stream)
|
|
7030
|
+
return;
|
|
7031
|
+
let buffered = "";
|
|
7032
|
+
stream.on("data", (chunk) => {
|
|
7033
|
+
buffered += chunk.toString("utf8");
|
|
7034
|
+
let newline = buffered.indexOf(`
|
|
7035
|
+
`);
|
|
7036
|
+
while (newline >= 0) {
|
|
7037
|
+
onLine(buffered.slice(0, newline).replace(/\r$/u, ""));
|
|
7038
|
+
buffered = buffered.slice(newline + 1);
|
|
7039
|
+
newline = buffered.indexOf(`
|
|
7040
|
+
`);
|
|
7041
|
+
}
|
|
7042
|
+
});
|
|
7043
|
+
stream.on("end", () => {
|
|
7044
|
+
if (buffered)
|
|
7045
|
+
onLine(buffered);
|
|
7046
|
+
});
|
|
7047
|
+
};
|
|
7048
|
+
attach(process2.stdout);
|
|
7049
|
+
attach(process2.stderr);
|
|
7050
|
+
};
|
|
7051
|
+
var stopProcess = async (process2) => {
|
|
7052
|
+
if (process2.exitCode !== null || process2.killed)
|
|
7053
|
+
return;
|
|
7054
|
+
process2.kill("SIGTERM");
|
|
7055
|
+
await Promise.race([
|
|
7056
|
+
new Promise((resolve14) => process2.once("exit", () => resolve14())),
|
|
7057
|
+
new Promise((resolve14) => setTimeout(resolve14, PROCESS_CLOSE_TIMEOUT_MS))
|
|
7058
|
+
]);
|
|
7059
|
+
if (process2.exitCode === null)
|
|
7060
|
+
process2.kill("SIGKILL");
|
|
7061
|
+
};
|
|
7062
|
+
var waitForExit = (process2) => new Promise((resolve14) => {
|
|
7063
|
+
if (process2.exitCode !== null) {
|
|
7064
|
+
resolve14(process2.exitCode);
|
|
7065
|
+
return;
|
|
7066
|
+
}
|
|
7067
|
+
process2.once("exit", (code) => resolve14(code ?? 1));
|
|
7068
|
+
});
|
|
7069
|
+
var startAbsoluteExpoDevSession = async (options) => {
|
|
7070
|
+
const plan = planAbsoluteExpoDevSession(options.config, options);
|
|
7071
|
+
const executable = options.executable ?? await absoluteExpoExecutable(plan.project);
|
|
7072
|
+
const run = options.spawnProcess ?? spawn;
|
|
7073
|
+
const log = options.log ?? (() => {
|
|
7074
|
+
return;
|
|
7075
|
+
});
|
|
7076
|
+
const timings = {};
|
|
7077
|
+
const setState = (state) => {
|
|
7078
|
+
options.onStateChange?.(state);
|
|
7079
|
+
};
|
|
7080
|
+
if (options.signal?.aborted)
|
|
7081
|
+
throw abortError();
|
|
7082
|
+
const prepareCommand = plan.commands.find((command) => command.role === "native-prepare");
|
|
7083
|
+
const metroCommand = plan.commands.find((command) => command.role === "metro");
|
|
7084
|
+
const nativeCommands = plan.commands.filter((command) => command.role === "native-build");
|
|
7085
|
+
if (!prepareCommand)
|
|
7086
|
+
throw new TypeError("Expo native preparation command is missing.");
|
|
7087
|
+
if (!metroCommand)
|
|
7088
|
+
throw new TypeError("Expo Metro command is missing.");
|
|
7089
|
+
setState("preparing-native");
|
|
7090
|
+
const prepareStarted = performance.now();
|
|
7091
|
+
const prepareProcess = run(executable, prepareCommand.args, {
|
|
7092
|
+
cwd: plan.project,
|
|
7093
|
+
env: { ...process.env, ...prepareCommand.env },
|
|
7094
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7095
|
+
});
|
|
7096
|
+
forwardLines(prepareProcess, (line) => {
|
|
7097
|
+
if (line)
|
|
7098
|
+
log(`[prebuild] ${line}`);
|
|
7099
|
+
});
|
|
7100
|
+
const abortPrepare = () => void stopProcess(prepareProcess);
|
|
7101
|
+
options.signal?.addEventListener("abort", abortPrepare, { once: true });
|
|
7102
|
+
const prepareExit = await waitForExit(prepareProcess);
|
|
7103
|
+
options.signal?.removeEventListener("abort", abortPrepare);
|
|
7104
|
+
if (options.signal?.aborted)
|
|
7105
|
+
throw abortError();
|
|
7106
|
+
if (prepareExit !== 0) {
|
|
7107
|
+
setState("failed");
|
|
7108
|
+
throw new Error(`Expo native preparation exited with status ${prepareExit}.`);
|
|
7109
|
+
}
|
|
7110
|
+
const prepareMs = performance.now() - prepareStarted;
|
|
7111
|
+
timings["preparing-native"] = prepareMs;
|
|
7112
|
+
options.onPhaseTiming?.({
|
|
7113
|
+
durationMs: prepareMs,
|
|
7114
|
+
phase: "preparing-native"
|
|
7115
|
+
});
|
|
7116
|
+
setState("starting-metro");
|
|
7117
|
+
const metroStarted = performance.now();
|
|
7118
|
+
const metro = run(executable, metroCommand.args, {
|
|
7119
|
+
cwd: plan.project,
|
|
7120
|
+
env: { ...process.env, ...metroCommand.env },
|
|
7121
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7122
|
+
});
|
|
7123
|
+
let metroReady = false;
|
|
7124
|
+
let resolveMetro;
|
|
7125
|
+
const metroPromise = new Promise((resolve14, reject) => {
|
|
7126
|
+
const timeout = setTimeout(() => {
|
|
7127
|
+
reject(new Error("Expo Metro did not become ready within 60 seconds."));
|
|
7128
|
+
}, METRO_READY_TIMEOUT_MS);
|
|
7129
|
+
resolveMetro = () => {
|
|
7130
|
+
clearTimeout(timeout);
|
|
7131
|
+
resolve14();
|
|
7132
|
+
};
|
|
7133
|
+
metro.once("exit", (code) => {
|
|
7134
|
+
if (!metroReady) {
|
|
7135
|
+
clearTimeout(timeout);
|
|
7136
|
+
reject(new Error(`Expo Metro exited with status ${code ?? 1}.`));
|
|
7137
|
+
}
|
|
7138
|
+
});
|
|
7139
|
+
});
|
|
7140
|
+
forwardLines(metro, (line) => {
|
|
7141
|
+
if (line)
|
|
7142
|
+
log(`[metro] ${line}`);
|
|
7143
|
+
if (!metroReady && /(?:Waiting on|Metro waiting on|Dev server ready)/iu.test(line)) {
|
|
7144
|
+
metroReady = true;
|
|
7145
|
+
resolveMetro?.();
|
|
7146
|
+
}
|
|
7147
|
+
});
|
|
7148
|
+
const abort = () => void stopProcess(metro);
|
|
7149
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
7150
|
+
const runNativeCommand = async (command) => {
|
|
7151
|
+
if (options.signal?.aborted)
|
|
7152
|
+
throw abortError();
|
|
7153
|
+
const { platform } = command;
|
|
7154
|
+
if (!platform)
|
|
7155
|
+
throw new TypeError("Expo native build command is missing a platform.");
|
|
7156
|
+
const state = platform === "android" ? "building-android" : "building-ios";
|
|
7157
|
+
setState(state);
|
|
7158
|
+
const started = performance.now();
|
|
7159
|
+
const child = run(executable, command.args, {
|
|
7160
|
+
cwd: plan.project,
|
|
7161
|
+
env: { ...process.env, ...command.env },
|
|
7162
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
7163
|
+
});
|
|
7164
|
+
forwardLines(child, (line) => {
|
|
7165
|
+
if (line)
|
|
7166
|
+
log(`[${platform}] ${line}`);
|
|
7167
|
+
});
|
|
7168
|
+
const abortChild = () => void stopProcess(child);
|
|
7169
|
+
options.signal?.addEventListener("abort", abortChild, { once: true });
|
|
7170
|
+
const exitCode = await waitForExit(child);
|
|
7171
|
+
options.signal?.removeEventListener("abort", abortChild);
|
|
7172
|
+
if (options.signal?.aborted)
|
|
7173
|
+
throw abortError();
|
|
7174
|
+
if (exitCode !== 0) {
|
|
7175
|
+
throw new Error(`Expo ${platform} development build exited with status ${exitCode}.`);
|
|
7176
|
+
}
|
|
7177
|
+
const durationMs = performance.now() - started;
|
|
7178
|
+
timings[state] = durationMs;
|
|
7179
|
+
options.onPhaseTiming?.({ durationMs, phase: state });
|
|
7180
|
+
};
|
|
7181
|
+
const runNativeCommands = async (commands) => {
|
|
7182
|
+
const [command, ...remaining] = commands;
|
|
7183
|
+
if (!command)
|
|
7184
|
+
return;
|
|
7185
|
+
await runNativeCommand(command);
|
|
7186
|
+
await runNativeCommands(remaining);
|
|
7187
|
+
};
|
|
7188
|
+
try {
|
|
7189
|
+
await metroPromise;
|
|
7190
|
+
const metroMs = performance.now() - metroStarted;
|
|
7191
|
+
timings["starting-metro"] = metroMs;
|
|
7192
|
+
options.onPhaseTiming?.({
|
|
7193
|
+
durationMs: metroMs,
|
|
7194
|
+
phase: "starting-metro"
|
|
7195
|
+
});
|
|
7196
|
+
await runNativeCommands(nativeCommands);
|
|
7197
|
+
setState("ready");
|
|
7198
|
+
return {
|
|
7199
|
+
metroPort: plan.metroPort,
|
|
7200
|
+
platforms: options.platforms,
|
|
7201
|
+
timings,
|
|
7202
|
+
close: async () => {
|
|
7203
|
+
options.signal?.removeEventListener("abort", abort);
|
|
7204
|
+
await stopProcess(metro);
|
|
7205
|
+
setState("closed");
|
|
7206
|
+
}
|
|
7207
|
+
};
|
|
7208
|
+
} catch (error) {
|
|
7209
|
+
options.signal?.removeEventListener("abort", abort);
|
|
7210
|
+
await stopProcess(metro);
|
|
7211
|
+
setState("failed");
|
|
7212
|
+
throw error;
|
|
7213
|
+
}
|
|
7214
|
+
};
|
|
6905
7215
|
// src/mobile/ciWorkflow.ts
|
|
6906
7216
|
import { existsSync as existsSync3 } from "fs";
|
|
6907
|
-
import { access as
|
|
7217
|
+
import { access as access11, mkdir as mkdir12, readFile as readFile16, writeFile as writeFile13 } from "fs/promises";
|
|
6908
7218
|
import { dirname as dirname11, extname as extname4, relative as relative11, resolve as resolve14, sep as sep6 } from "path";
|
|
6909
7219
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1;
|
|
6910
7220
|
var SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
|
|
@@ -6926,7 +7236,7 @@ var RESERVED_SECRET_NAMES = new Set([
|
|
|
6926
7236
|
]);
|
|
6927
7237
|
var exists4 = async (path) => {
|
|
6928
7238
|
try {
|
|
6929
|
-
await
|
|
7239
|
+
await access11(path);
|
|
6930
7240
|
return true;
|
|
6931
7241
|
} catch {
|
|
6932
7242
|
return false;
|
|
@@ -6969,7 +7279,7 @@ var normalizeSecretEnvironment = (values = []) => {
|
|
|
6969
7279
|
};
|
|
6970
7280
|
var customSecretEnvironment = (names, indentation = CI_ENV_INDENTATION) => names.map((name) => `${" ".repeat(indentation)}${name}: \${{ secrets.${name} }}`).join(`
|
|
6971
7281
|
`);
|
|
6972
|
-
var
|
|
7282
|
+
var commandEnvironment2 = (options) => ` ABSOLUTE_CONFIG_PATH: ${yamlString(options.configPath ?? "")}
|
|
6973
7283
|
ABSOLUTE_REGISTRY_MODULE: ${yamlString(options.registryModule)}
|
|
6974
7284
|
ABSOLUTE_SERVER_ENTRY: ${yamlString(options.serverEntry)}`;
|
|
6975
7285
|
var appendConfigArgument = `if [[ -n "$ABSOLUTE_CONFIG_PATH" ]]; then
|
|
@@ -7128,7 +7438,7 @@ var androidJob = (options) => {
|
|
|
7128
7438
|
ABSOLUTE_ANDROID_KEY_PASSWORD: \${{ secrets.ABSOLUTE_ANDROID_KEY_PASSWORD }}
|
|
7129
7439
|
ABSOLUTE_ANDROID_KEYSTORE_PATH: \${{ runner.temp }}/absolute-release.jks${publishEnvironment}${custom ? `
|
|
7130
7440
|
${custom}` : ""}
|
|
7131
|
-
${
|
|
7441
|
+
${commandEnvironment2({ configPath: undefined, registryModule: "", serverEntry: "" })}
|
|
7132
7442
|
steps:
|
|
7133
7443
|
${installSteps}
|
|
7134
7444
|
- name: Provision Android signing
|
|
@@ -7227,7 +7537,7 @@ var iosJob = (options) => {
|
|
|
7227
7537
|
ABSOLUTE_IOS_KEYCHAIN_PASSWORD: \${{ secrets.ABSOLUTE_IOS_KEYCHAIN_PASSWORD }}${publishEnvironment}${custom ? `
|
|
7228
7538
|
${custom}` : ""}
|
|
7229
7539
|
ABSOLUTE_IOS_DEVELOPMENT_TEAM: \${{ secrets.ABSOLUTE_IOS_DEVELOPMENT_TEAM }}
|
|
7230
|
-
${
|
|
7540
|
+
${commandEnvironment2({ configPath: undefined, registryModule: "", serverEntry: "" })}
|
|
7231
7541
|
steps:
|
|
7232
7542
|
${installSteps}
|
|
7233
7543
|
- name: Provision iOS signing
|
|
@@ -7321,7 +7631,7 @@ var createAbsoluteMobileGithubWorkflow = (options) => {
|
|
|
7321
7631
|
const serverEntry = projectPath(options.projectRoot, options.serverEntry ?? "server.ts", "mobile ci github server entry");
|
|
7322
7632
|
const configPath = options.configPath ? projectPath(options.projectRoot, options.configPath, "mobile ci github --config") : undefined;
|
|
7323
7633
|
const registryModule = projectPath(options.projectRoot, options.registryModule ?? "mobile.release.ts", "mobile ci github --registry", { allowMissing: !includePublishing });
|
|
7324
|
-
const environment =
|
|
7634
|
+
const environment = commandEnvironment2({
|
|
7325
7635
|
configPath,
|
|
7326
7636
|
registryModule,
|
|
7327
7637
|
serverEntry
|
|
@@ -7613,7 +7923,7 @@ var createAbsoluteMobilePreviewPlugin = (mobile) => {
|
|
|
7613
7923
|
};
|
|
7614
7924
|
// src/mobile/nativeDeepLinks.ts
|
|
7615
7925
|
import { readFile as readFile17, rename as rename12, writeFile as writeFile14 } from "fs/promises";
|
|
7616
|
-
import { join as
|
|
7926
|
+
import { join as join19 } from "path";
|
|
7617
7927
|
var START_MARKER = "<!-- absolutejs:deep-links:start -->";
|
|
7618
7928
|
var END_MARKER = "<!-- absolutejs:deep-links:end -->";
|
|
7619
7929
|
var IOS_ENTITLEMENTS = "App/AbsoluteJS.entitlements";
|
|
@@ -7670,7 +7980,7 @@ ${hosts}
|
|
|
7670
7980
|
`;
|
|
7671
7981
|
};
|
|
7672
7982
|
var configureAndroid = async (config) => {
|
|
7673
|
-
const path =
|
|
7983
|
+
const path = join19(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
7674
7984
|
const source = await readFile17(path, "utf8");
|
|
7675
7985
|
const mainActivity = source.indexOf('android:name=".MainActivity"');
|
|
7676
7986
|
if (mainActivity === NOT_FOUND) {
|
|
@@ -7696,7 +8006,7 @@ var iosSchemeRegion = (scheme) => ` ${START_MARKER}
|
|
|
7696
8006
|
${END_MARKER}
|
|
7697
8007
|
`;
|
|
7698
8008
|
var configureIosInfo = async (config) => {
|
|
7699
|
-
const path =
|
|
8009
|
+
const path = join19(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
7700
8010
|
const source = await readFile17(path, "utf8");
|
|
7701
8011
|
const region = config.deepLinkScheme ? iosSchemeRegion(config.deepLinkScheme) : ` ${START_MARKER}
|
|
7702
8012
|
${END_MARKER}
|
|
@@ -7720,7 +8030,7 @@ ${domains}
|
|
|
7720
8030
|
`;
|
|
7721
8031
|
};
|
|
7722
8032
|
var configureIosEntitlements = async (config) => {
|
|
7723
|
-
const path =
|
|
8033
|
+
const path = join19(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
7724
8034
|
let current = "";
|
|
7725
8035
|
try {
|
|
7726
8036
|
current = await readFile17(path, "utf8");
|
|
@@ -7738,7 +8048,7 @@ var configureIosEntitlements = async (config) => {
|
|
|
7738
8048
|
return true;
|
|
7739
8049
|
};
|
|
7740
8050
|
var configureIosProject = async (config) => {
|
|
7741
|
-
const path =
|
|
8051
|
+
const path = join19(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
7742
8052
|
const source = await readFile17(path, "utf8");
|
|
7743
8053
|
const declarations = [
|
|
7744
8054
|
...source.matchAll(/CODE_SIGN_ENTITLEMENTS = ([^;]+);/g)
|
|
@@ -7779,7 +8089,7 @@ var applyAbsoluteNativeDeepLinks = async (config, platforms = config.platforms)
|
|
|
7779
8089
|
// src/mobile/nativeDeviceCapabilities.ts
|
|
7780
8090
|
init_deviceCapabilities();
|
|
7781
8091
|
import { readFile as readFile18, rename as rename13, writeFile as writeFile15 } from "fs/promises";
|
|
7782
|
-
import { join as
|
|
8092
|
+
import { join as join20 } from "path";
|
|
7783
8093
|
var START_MARKER2 = "<!-- absolutejs:device-capabilities:start -->";
|
|
7784
8094
|
var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
7785
8095
|
var NOT_FOUND2 = -1;
|
|
@@ -7929,7 +8239,7 @@ var writeIosPrivacyManifest = async (path, current, source) => {
|
|
|
7929
8239
|
var configureIosPrivacyProject = async (config, requirements) => {
|
|
7930
8240
|
if (requirements.iosPrivacyAccessedApis.length === 0)
|
|
7931
8241
|
return false;
|
|
7932
|
-
const projectPath2 =
|
|
8242
|
+
const projectPath2 = join20(config.nativeProjectDirectory, "ios/App/App.xcodeproj/project.pbxproj");
|
|
7933
8243
|
const project = await readFile18(projectPath2, "utf8");
|
|
7934
8244
|
return writeChangedFile2(projectPath2, addIosPrivacyProjectReference(project));
|
|
7935
8245
|
};
|
|
@@ -7982,7 +8292,7 @@ ${next.slice(index)}`;
|
|
|
7982
8292
|
return next;
|
|
7983
8293
|
};
|
|
7984
8294
|
var configureIos2 = async (config, plan) => {
|
|
7985
|
-
const path =
|
|
8295
|
+
const path = join20(config.nativeProjectDirectory, "ios/App/App/Info.plist");
|
|
7986
8296
|
const source = await readFile18(path, "utf8");
|
|
7987
8297
|
const requirements = absoluteDeviceNativeRequirements(plan);
|
|
7988
8298
|
const existingSystemBars = source.match(/<key>UIViewControllerBasedStatusBarAppearance<\/key>\s*<(true|false)\s*\/>/u);
|
|
@@ -8003,7 +8313,7 @@ ${content}
|
|
|
8003
8313
|
${END_MARKER2}
|
|
8004
8314
|
` : "";
|
|
8005
8315
|
const infoChanged = await writeChangedFile2(path, managed(source, region, source.lastIndexOf("</dict>")));
|
|
8006
|
-
const privacyPath =
|
|
8316
|
+
const privacyPath = join20(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
8007
8317
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
8008
8318
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
8009
8319
|
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
@@ -8014,7 +8324,7 @@ ${content}
|
|
|
8014
8324
|
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
8015
8325
|
};
|
|
8016
8326
|
var configureIosPushNotifications = async (config, enabled) => {
|
|
8017
|
-
const entitlementsPath =
|
|
8327
|
+
const entitlementsPath = join20(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
8018
8328
|
const entitlements = await optionalSource(entitlementsPath);
|
|
8019
8329
|
if (entitlements === null && !enabled)
|
|
8020
8330
|
return false;
|
|
@@ -8026,7 +8336,7 @@ var configureIosPushNotifications = async (config, enabled) => {
|
|
|
8026
8336
|
<!-- ${PUSH_END_MARKER} -->
|
|
8027
8337
|
` : "";
|
|
8028
8338
|
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
8029
|
-
const delegatePath =
|
|
8339
|
+
const delegatePath = join20(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
8030
8340
|
const delegate = await optionalSource(delegatePath);
|
|
8031
8341
|
if (delegate === null && !enabled)
|
|
8032
8342
|
return false;
|
|
@@ -8075,7 +8385,7 @@ var replacePushRegion = (source, region, insertion) => {
|
|
|
8075
8385
|
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
8076
8386
|
};
|
|
8077
8387
|
var configureAndroid2 = async (config, plan) => {
|
|
8078
|
-
const path =
|
|
8388
|
+
const path = join20(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
8079
8389
|
const source = await readFile18(path, "utf8");
|
|
8080
8390
|
const permissions = absoluteDeviceNativeRequirements(plan).androidPermissions;
|
|
8081
8391
|
const content = permissions.map((permission) => ` <uses-permission android:name="${escapeXml2(permission)}" />`).join(`
|
|
@@ -8111,7 +8421,7 @@ ${content}
|
|
|
8111
8421
|
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
8112
8422
|
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
8113
8423
|
writeChangedFile2(path, nextManifest),
|
|
8114
|
-
writeOptionalChangedFile(
|
|
8424
|
+
writeOptionalChangedFile(join20(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
8115
8425
|
]);
|
|
8116
8426
|
return manifestChanged || firebaseChanged;
|
|
8117
8427
|
};
|
|
@@ -8125,7 +8435,7 @@ var applyAbsoluteNativeDeviceCapabilities = async (projectRoot, config, platform
|
|
|
8125
8435
|
};
|
|
8126
8436
|
};
|
|
8127
8437
|
// src/mobile/releasePublisher.ts
|
|
8128
|
-
import { access as
|
|
8438
|
+
import { access as access12 } from "fs/promises";
|
|
8129
8439
|
import { isAbsolute as isAbsolute6, relative as relative12, resolve as resolve15, sep as sep7 } from "path";
|
|
8130
8440
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
8131
8441
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
@@ -8162,7 +8472,7 @@ var publisherModulePath = (projectRoot, requested) => {
|
|
|
8162
8472
|
};
|
|
8163
8473
|
var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath) => {
|
|
8164
8474
|
const modulePath = publisherModulePath(projectRoot, requestedModulePath);
|
|
8165
|
-
await
|
|
8475
|
+
await access12(modulePath).catch(() => {
|
|
8166
8476
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
8167
8477
|
});
|
|
8168
8478
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
@@ -8972,6 +9282,7 @@ export {
|
|
|
8972
9282
|
startAbsoluteIosTcpRelay,
|
|
8973
9283
|
startAbsoluteIosDevSession,
|
|
8974
9284
|
startAbsoluteIosCaEnrollmentServer,
|
|
9285
|
+
startAbsoluteExpoDevSession,
|
|
8975
9286
|
serializeAbsoluteMobileAuthEnvironment,
|
|
8976
9287
|
runWithAbsoluteMobileProducer,
|
|
8977
9288
|
runAbsoluteAndroidUpgradeConformance,
|
|
@@ -8994,6 +9305,7 @@ export {
|
|
|
8994
9305
|
prepareAbsoluteIosRelease,
|
|
8995
9306
|
prepareAbsoluteIosDevProject,
|
|
8996
9307
|
prepareAbsoluteAndroidRelease,
|
|
9308
|
+
planAbsoluteExpoDevSession,
|
|
8997
9309
|
parseIosSimulators,
|
|
8998
9310
|
parseIosRuntimes,
|
|
8999
9311
|
parseIosDeviceTypes,
|
|
@@ -9075,6 +9387,7 @@ export {
|
|
|
9075
9387
|
absoluteRemoteMacSshBase,
|
|
9076
9388
|
absoluteMobilePreviewDocument,
|
|
9077
9389
|
absoluteIosDeviceAcceptanceCommands,
|
|
9390
|
+
absoluteExpoExecutable,
|
|
9078
9391
|
absoluteDeviceNativeRequirements,
|
|
9079
9392
|
MOBILE_PAGE_REQUEST_HEADERS,
|
|
9080
9393
|
AbsoluteMobilePageProtocolError,
|
|
@@ -9104,5 +9417,5 @@ export {
|
|
|
9104
9417
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
9105
9418
|
};
|
|
9106
9419
|
|
|
9107
|
-
//# debugId=
|
|
9420
|
+
//# debugId=DD3370D585C0D59B64756E2164756E21
|
|
9108
9421
|
//# sourceMappingURL=index.js.map
|