@absolutejs/absolute 0.20.0-beta.47 → 0.20.0-beta.48
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/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/index.js +36 -1
- package/dist/angular/index.js.map +3 -3
- package/dist/angular/server.js +36 -1
- package/dist/angular/server.js.map +3 -3
- package/dist/cli/config/server.js +36 -0
- package/dist/cli/index.js +247 -67
- package/dist/index.js +36 -1
- package/dist/index.js.map +3 -3
- package/dist/mobile/browser.js +38 -1
- package/dist/mobile/browser.js.map +3 -3
- package/dist/mobile/index.js +243 -21
- package/dist/mobile/index.js.map +5 -5
- package/dist/mobile/remoteMacAgentEntry.js +232 -97
- package/dist/react/index.js +36 -1
- package/dist/react/index.js.map +3 -3
- package/dist/react/server.js +36 -1
- package/dist/react/server.js.map +3 -3
- package/dist/src/mobile/index.d.ts +1 -0
- package/dist/src/mobile/nativeRoute.d.ts +13 -0
- package/dist/src/mobile/pageProtocol.d.ts +2 -0
- package/dist/svelte/index.js +36 -1
- package/dist/svelte/index.js.map +3 -3
- package/dist/svelte/server.js +36 -1
- package/dist/svelte/server.js.map +3 -3
- package/dist/vue/index.js +36 -1
- package/dist/vue/index.js.map +3 -3
- package/dist/vue/server.js +36 -1
- package/dist/vue/server.js.map +3 -3
- package/package.json +1 -1
package/dist/mobile/index.js
CHANGED
|
@@ -5231,6 +5231,7 @@ var getCurrentAbsoluteMobileProducerContext = () => {
|
|
|
5231
5231
|
// src/mobile/pageProtocol.ts
|
|
5232
5232
|
var ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE = "application/vnd.absolute.page+json";
|
|
5233
5233
|
var ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION = 1;
|
|
5234
|
+
var ABSOLUTE_NATIVE_ROUTE_DATA_MEDIA_TYPE = "application/vnd.absolute.native-route+json";
|
|
5234
5235
|
var BAD_REQUEST_STATUS = 400;
|
|
5235
5236
|
var OK_STATUS = 200;
|
|
5236
5237
|
var SERVER_ERROR_STATUS = 500;
|
|
@@ -5249,6 +5250,11 @@ var acceptsAbsoluteMobilePage = (request) => {
|
|
|
5249
5250
|
return false;
|
|
5250
5251
|
return (request.headers.get("accept") ?? "").split(",").some((value) => parseMediaType(value) === ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE);
|
|
5251
5252
|
};
|
|
5253
|
+
var acceptsAbsoluteNativeRouteData = (request) => {
|
|
5254
|
+
if (!request)
|
|
5255
|
+
return false;
|
|
5256
|
+
return (request.headers.get("accept") ?? "").split(",").some((value) => parseMediaType(value) === ABSOLUTE_NATIVE_ROUTE_DATA_MEDIA_TYPE);
|
|
5257
|
+
};
|
|
5252
5258
|
var readRequiredHeader = (request, name) => {
|
|
5253
5259
|
const value = request.headers.get(name)?.trim();
|
|
5254
5260
|
return value ? value : undefined;
|
|
@@ -5379,6 +5385,32 @@ var finalizeArchivedMobilePage = (context, input) => {
|
|
|
5379
5385
|
return createAbsoluteMobilePageErrorResponse(page.pageId);
|
|
5380
5386
|
}
|
|
5381
5387
|
};
|
|
5388
|
+
var finalizeAbsoluteNativeRouteDevelopmentPage = (input) => {
|
|
5389
|
+
if (false) {}
|
|
5390
|
+
if (input.request?.method !== "GET") {
|
|
5391
|
+
return createAbsoluteMobileInvalidRequestResponse("Native-route data requests must use GET.");
|
|
5392
|
+
}
|
|
5393
|
+
if (input.request.headers.get(MOBILE_PAGE_REQUEST_HEADERS.protocol) !== String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)) {
|
|
5394
|
+
return createAbsoluteMobileInvalidRequestResponse(`Native-route data requires protocol ${ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION}.`);
|
|
5395
|
+
}
|
|
5396
|
+
const [representation] = input.compatibility.representations;
|
|
5397
|
+
if (!representation) {
|
|
5398
|
+
return createAbsoluteMobilePageErrorResponse(input.compatibility.pageId);
|
|
5399
|
+
}
|
|
5400
|
+
try {
|
|
5401
|
+
return envelopeResponse({
|
|
5402
|
+
contract: representation.contract,
|
|
5403
|
+
framework: input.compatibility.framework,
|
|
5404
|
+
kind: "page",
|
|
5405
|
+
pageId: input.compatibility.pageId,
|
|
5406
|
+
props: normalizeJsonValue(representation.mapProps(input.props)),
|
|
5407
|
+
status: input.status ?? OK_STATUS
|
|
5408
|
+
}, input.status ?? OK_STATUS);
|
|
5409
|
+
} catch (error) {
|
|
5410
|
+
console.error(`[Mobile] Failed to produce development native route ${input.compatibility.pageId}:`, error);
|
|
5411
|
+
return createAbsoluteMobilePageErrorResponse(input.compatibility.pageId);
|
|
5412
|
+
}
|
|
5413
|
+
};
|
|
5382
5414
|
var createAbsoluteMobileInvalidRequestResponse = (message) => envelopeResponse({ kind: "invalid-request", message }, BAD_REQUEST_STATUS);
|
|
5383
5415
|
var createAbsoluteMobilePageErrorResponse = (pageId) => envelopeResponse({
|
|
5384
5416
|
code: "representation-failed",
|
|
@@ -5388,6 +5420,9 @@ var createAbsoluteMobilePageErrorResponse = (pageId) => envelopeResponse({
|
|
|
5388
5420
|
}, SERVER_ERROR_STATUS);
|
|
5389
5421
|
var createAbsoluteMobileUpgradeResponse = (result) => envelopeResponse(result, UPGRADE_REQUIRED_STATUS);
|
|
5390
5422
|
var finalizeAbsoluteMobilePage = (input) => {
|
|
5423
|
+
if (acceptsAbsoluteNativeRouteData(input.request)) {
|
|
5424
|
+
return finalizeAbsoluteNativeRouteDevelopmentPage(input);
|
|
5425
|
+
}
|
|
5391
5426
|
const parsed = parseAbsoluteMobilePageRequest(input.request);
|
|
5392
5427
|
if (parsed.kind === "not-mobile")
|
|
5393
5428
|
return;
|
|
@@ -6179,6 +6214,48 @@ var exists3 = async (path) => {
|
|
|
6179
6214
|
return false;
|
|
6180
6215
|
}
|
|
6181
6216
|
};
|
|
6217
|
+
var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6218
|
+
var requireManifestString = (value, field2) => {
|
|
6219
|
+
if (typeof value !== "string" || !value) {
|
|
6220
|
+
throw new TypeError(`AbsoluteJS mobile manifest ${field2} is invalid.`);
|
|
6221
|
+
}
|
|
6222
|
+
return value;
|
|
6223
|
+
};
|
|
6224
|
+
var expoNativeDataManifest = (value) => {
|
|
6225
|
+
if (!isRecord8(value) || !Array.isArray(value.pages) || !Array.isArray(value.routes)) {
|
|
6226
|
+
throw new TypeError("AbsoluteJS mobile manifest is invalid.");
|
|
6227
|
+
}
|
|
6228
|
+
const pages = value.pages.map((page) => {
|
|
6229
|
+
if (!isRecord8(page))
|
|
6230
|
+
throw new TypeError("AbsoluteJS mobile manifest page is invalid.");
|
|
6231
|
+
return {
|
|
6232
|
+
bundleHash: requireManifestString(page.bundleHash, "page.bundleHash"),
|
|
6233
|
+
contract: requireManifestString(page.contract, "page.contract"),
|
|
6234
|
+
pageId: requireManifestString(page.pageId, "page.pageId")
|
|
6235
|
+
};
|
|
6236
|
+
});
|
|
6237
|
+
const routes = value.routes.flatMap((route) => {
|
|
6238
|
+
if (!isRecord8(route) || typeof route.method !== "string") {
|
|
6239
|
+
throw new TypeError("AbsoluteJS mobile manifest route is invalid.");
|
|
6240
|
+
}
|
|
6241
|
+
if (route.method !== "GET")
|
|
6242
|
+
return [];
|
|
6243
|
+
return [
|
|
6244
|
+
{
|
|
6245
|
+
method: "GET",
|
|
6246
|
+
pageId: requireManifestString(route.pageId, "route.pageId"),
|
|
6247
|
+
pattern: requireManifestString(route.pattern, "route.pattern")
|
|
6248
|
+
}
|
|
6249
|
+
];
|
|
6250
|
+
});
|
|
6251
|
+
return {
|
|
6252
|
+
appBuild: requireManifestString(value.appBuild, "appBuild"),
|
|
6253
|
+
pages,
|
|
6254
|
+
productionOrigin: requireManifestString(value.productionOrigin, "productionOrigin"),
|
|
6255
|
+
routes,
|
|
6256
|
+
runtime: requireManifestString(value.runtime, "runtime")
|
|
6257
|
+
};
|
|
6258
|
+
};
|
|
6182
6259
|
var portableRelative2 = (from, destination) => {
|
|
6183
6260
|
const value = relative10(from, destination).replaceAll("\\", "/");
|
|
6184
6261
|
return value.startsWith(".") ? value : `./${value}`;
|
|
@@ -6973,7 +7050,134 @@ var catchAllRouteSource = `${EXPO_GENERATED_HEADER}import { AbsoluteWebHost } fr
|
|
|
6973
7050
|
|
|
6974
7051
|
export default AbsoluteWebHost;
|
|
6975
7052
|
`;
|
|
6976
|
-
var
|
|
7053
|
+
var nativeRouteRuntimeSource = (auth) => `${EXPO_GENERATED_HEADER}import { useLocalSearchParams, usePathname } from 'expo-router';
|
|
7054
|
+
import { type ComponentType, useEffect, useMemo, useState } from 'react';
|
|
7055
|
+
import { ActivityIndicator, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
|
|
7056
|
+
import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
|
|
7057
|
+
${auth ? "import { absoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
7058
|
+
|
|
7059
|
+
const PAGE_MEDIA_TYPE = 'application/vnd.absolute.page+json';
|
|
7060
|
+
const NATIVE_DATA_MEDIA_TYPE = 'application/vnd.absolute.native-route+json';
|
|
7061
|
+
const PROTOCOL = 1;
|
|
7062
|
+
const MAX_DATA_BYTES = 1024 * 1024;
|
|
7063
|
+
const DEV_ORIGIN = Platform.OS === 'android'
|
|
7064
|
+
? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
|
|
7065
|
+
: process.env.EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN;
|
|
7066
|
+
|
|
7067
|
+
type RouteParams = Record<string, string | string[] | undefined>;
|
|
7068
|
+
type NativeRouteProps<PageProps extends object, Params extends object> = {
|
|
7069
|
+
pageProps: Readonly<PageProps>;
|
|
7070
|
+
params: Readonly<Params>;
|
|
7071
|
+
reload: () => void;
|
|
7072
|
+
};
|
|
7073
|
+
type NativeRouteState<PageProps> =
|
|
7074
|
+
| { kind: 'loading' }
|
|
7075
|
+
| { kind: 'ready'; pageProps: PageProps }
|
|
7076
|
+
| { kind: 'error' };
|
|
7077
|
+
|
|
7078
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
7079
|
+
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
7080
|
+
const routeSegmentPattern = (segment: string) => {
|
|
7081
|
+
if (segment === '*') return '.*';
|
|
7082
|
+
if (segment.startsWith(':') && segment.endsWith('?')) return '[^/]*';
|
|
7083
|
+
if (segment.startsWith(':')) return '[^/]+';
|
|
7084
|
+
return segment.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&');
|
|
7085
|
+
};
|
|
7086
|
+
const matchesRoute = (pattern: string, pathname: string) =>
|
|
7087
|
+
new RegExp('^' + pattern.split('/').map(routeSegmentPattern).join('/') + '/?$').test(pathname);
|
|
7088
|
+
const requestPathFor = (pathname: string, params: RouteParams, pattern: string) => {
|
|
7089
|
+
const pathNames = new Set(pattern.split('/').filter(segment => segment.startsWith(':')).map(segment => segment.replace(/^:/, '').replace(/\\?$/, '')));
|
|
7090
|
+
if (pattern.endsWith('/*')) pathNames.add('absoluteWildcard');
|
|
7091
|
+
const query = new URLSearchParams();
|
|
7092
|
+
for (const [name, value] of Object.entries(params).sort(([left], [right]) => left.localeCompare(right))) {
|
|
7093
|
+
if (pathNames.has(name) || name === '#' || value === undefined) continue;
|
|
7094
|
+
for (const item of Array.isArray(value) ? value : [value]) query.append(name, item);
|
|
7095
|
+
}
|
|
7096
|
+
const search = query.toString();
|
|
7097
|
+
return pathname + (search ? '?' + search : '');
|
|
7098
|
+
};
|
|
7099
|
+
const productionPage = (pathname: string) => {
|
|
7100
|
+
if (!ABSOLUTE_MOBILE_MANIFEST) throw new Error('AbsoluteJS native route data is not prepared for production.');
|
|
7101
|
+
const route = ABSOLUTE_MOBILE_MANIFEST.routes.find(candidate => candidate.method === 'GET' && matchesRoute(candidate.pattern, pathname));
|
|
7102
|
+
if (!route) throw new Error('No trusted AbsoluteJS page route owns this native URL.');
|
|
7103
|
+
const page = ABSOLUTE_MOBILE_MANIFEST.pages.find(candidate => candidate.pageId === route.pageId);
|
|
7104
|
+
if (!page) throw new Error('The embedded AbsoluteJS page contract is incomplete.');
|
|
7105
|
+
return page;
|
|
7106
|
+
};
|
|
7107
|
+
const createDataRequest = (path: string) => {
|
|
7108
|
+
const development = typeof DEV_ORIGIN === 'string' && DEV_ORIGIN.length > 0;
|
|
7109
|
+
const origin = development ? DEV_ORIGIN : ABSOLUTE_MOBILE_MANIFEST?.productionOrigin;
|
|
7110
|
+
if (!origin) throw new Error('AbsoluteJS native route data has no trusted server origin.');
|
|
7111
|
+
const url = new URL(path, origin);
|
|
7112
|
+
if (url.origin !== new URL(origin).origin) throw new Error('AbsoluteJS native route data left its trusted origin.');
|
|
7113
|
+
const headers = new Headers();
|
|
7114
|
+
headers.set('accept', development ? NATIVE_DATA_MEDIA_TYPE : PAGE_MEDIA_TYPE);
|
|
7115
|
+
headers.set('x-absolute-mobile-protocol', String(PROTOCOL));
|
|
7116
|
+
let page: ReturnType<typeof productionPage> | undefined;
|
|
7117
|
+
if (!development) {
|
|
7118
|
+
page = productionPage(url.pathname);
|
|
7119
|
+
headers.set('x-absolute-mobile-app-build', ABSOLUTE_MOBILE_MANIFEST!.appBuild);
|
|
7120
|
+
headers.set('x-absolute-mobile-page-bundle', page.bundleHash);
|
|
7121
|
+
headers.set('x-absolute-mobile-page-contracts', page.contract);
|
|
7122
|
+
headers.set('x-absolute-mobile-page-id', page.pageId);
|
|
7123
|
+
headers.set('x-absolute-mobile-runtime', ABSOLUTE_MOBILE_MANIFEST!.runtime);
|
|
7124
|
+
}
|
|
7125
|
+
return { page, request: new Request(url, { headers, method: 'GET' }) };
|
|
7126
|
+
};
|
|
7127
|
+
const requestData = async <PageProps extends object>(path: string, signal: AbortSignal) => {
|
|
7128
|
+
const { page, request } = createDataRequest(path);
|
|
7129
|
+
const response = await ${auth ? "absoluteExpoAuth.fetchOptional" : "fetch"}(request, { redirect: 'manual', signal });
|
|
7130
|
+
if (new URL(response.url || request.url).origin !== new URL(request.url).origin || response.status >= 300 && response.status < 400) throw new Error('AbsoluteJS native route data redirected outside its contract.');
|
|
7131
|
+
const source = await response.text();
|
|
7132
|
+
if (new TextEncoder().encode(source).byteLength > MAX_DATA_BYTES) throw new Error('AbsoluteJS native route data exceeded 1 MiB.');
|
|
7133
|
+
let envelope: unknown;
|
|
7134
|
+
try { envelope = JSON.parse(source); } catch { throw new Error('The server did not return an AbsoluteJS page envelope.'); }
|
|
7135
|
+
if (!isRecord(envelope) || envelope.protocol !== PROTOCOL || !isRecord(envelope.response)) throw new Error('The server returned an invalid AbsoluteJS page envelope.');
|
|
7136
|
+
const result = envelope.response;
|
|
7137
|
+
if (result.kind === 'upgrade-required') throw new Error('This app version must be updated before opening this screen.');
|
|
7138
|
+
if (result.kind !== 'page' || !isRecord(result.props) || typeof result.pageId !== 'string' || typeof result.contract !== 'string') throw new Error('The server did not produce native route page props.');
|
|
7139
|
+
if (page && (result.pageId !== page.pageId || result.contract !== page.contract)) throw new Error('The server returned a different page contract than this app contains.');
|
|
7140
|
+
return result.props as PageProps;
|
|
7141
|
+
};
|
|
7142
|
+
|
|
7143
|
+
export const createAbsoluteNativeRoute = <
|
|
7144
|
+
PageProps extends object,
|
|
7145
|
+
Params extends object = RouteParams
|
|
7146
|
+
>(Component: ComponentType<NativeRouteProps<PageProps, Params>>, pattern: string) => {
|
|
7147
|
+
function AbsoluteNativeRouteScreen() {
|
|
7148
|
+
const pathname = usePathname() || '/';
|
|
7149
|
+
const params = useLocalSearchParams() as RouteParams;
|
|
7150
|
+
const parameterKey = JSON.stringify(params);
|
|
7151
|
+
const requestPath = useMemo(() => requestPathFor(pathname, params, pattern), [parameterKey, pathname]);
|
|
7152
|
+
const [revision, setRevision] = useState(0);
|
|
7153
|
+
const [state, setState] = useState<NativeRouteState<PageProps>>({ kind: 'loading' });
|
|
7154
|
+
useEffect(() => {
|
|
7155
|
+
const controller = new AbortController();
|
|
7156
|
+
setState({ kind: 'loading' });
|
|
7157
|
+
void requestData<PageProps>(requestPath, controller.signal).then(
|
|
7158
|
+
pageProps => { if (!controller.signal.aborted) setState({ kind: 'ready', pageProps }); },
|
|
7159
|
+
() => { if (!controller.signal.aborted) setState({ kind: 'error' }); }
|
|
7160
|
+
);
|
|
7161
|
+
return () => controller.abort();
|
|
7162
|
+
}, [requestPath, revision]);
|
|
7163
|
+
const reload = () => setRevision(value => value + 1);
|
|
7164
|
+
if (state.kind === 'loading') return <View style={styles.center}><ActivityIndicator accessibilityLabel="Loading screen" /></View>;
|
|
7165
|
+
if (state.kind === 'error') return <View style={styles.center}><Text accessibilityRole="alert" style={styles.error}>This screen could not load.</Text><Pressable accessibilityRole="button" onPress={reload} style={styles.button}><Text>Try again</Text></Pressable></View>;
|
|
7166
|
+
return <Component pageProps={state.pageProps} params={params as Params} reload={reload} />;
|
|
7167
|
+
}
|
|
7168
|
+
return AbsoluteNativeRouteScreen;
|
|
7169
|
+
};
|
|
7170
|
+
|
|
7171
|
+
const styles = StyleSheet.create({
|
|
7172
|
+
button: { backgroundColor: '#e2e8f0', borderRadius: 10, paddingHorizontal: 16, paddingVertical: 12 },
|
|
7173
|
+
center: { alignItems: 'center', flex: 1, gap: 16, justifyContent: 'center', padding: 24 },
|
|
7174
|
+
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
7175
|
+
});
|
|
7176
|
+
`;
|
|
7177
|
+
var nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname10(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
7178
|
+
import { createAbsoluteNativeRoute } from ${JSON.stringify(portableRelative2(dirname10(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
7179
|
+
|
|
7180
|
+
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
6977
7181
|
`;
|
|
6978
7182
|
var expoTsConfig = (projectRoot, project, auth, sync) => ({
|
|
6979
7183
|
compilerOptions: {
|
|
@@ -7040,9 +7244,19 @@ var pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
|
7040
7244
|
};
|
|
7041
7245
|
var jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
7042
7246
|
`;
|
|
7043
|
-
var
|
|
7247
|
+
var nativeDataManifestTypeSource = `type AbsoluteMobileManifest = {
|
|
7248
|
+
appBuild: string;
|
|
7249
|
+
pages: readonly { bundleHash: string; contract: string; pageId: string }[];
|
|
7250
|
+
productionOrigin: string;
|
|
7251
|
+
routes: readonly { method: 'GET'; pageId: string; pattern: string }[];
|
|
7252
|
+
runtime: string;
|
|
7253
|
+
};
|
|
7254
|
+
`;
|
|
7255
|
+
var emptyWebAssetsSource = `${EXPO_GENERATED_HEADER}${nativeDataManifestTypeSource}
|
|
7256
|
+
export const materializeAbsoluteWebBundle = async () => {
|
|
7044
7257
|
throw new Error('The embedded AbsoluteJS bundle is unavailable. Run absolute prepare before a production Expo build.');
|
|
7045
7258
|
};
|
|
7259
|
+
export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest | undefined = undefined;
|
|
7046
7260
|
`;
|
|
7047
7261
|
var writeAbsoluteExpoProject = async (config, options) => {
|
|
7048
7262
|
if (config.engine !== "expo")
|
|
@@ -7113,6 +7327,10 @@ node_modules/
|
|
|
7113
7327
|
join14(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
7114
7328
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
7115
7329
|
],
|
|
7330
|
+
[
|
|
7331
|
+
join14(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
7332
|
+
nativeRouteRuntimeSource(authEnabled)
|
|
7333
|
+
],
|
|
7116
7334
|
[
|
|
7117
7335
|
join14(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
7118
7336
|
webHostSource(config, auth, syncEnabled)
|
|
@@ -7132,9 +7350,10 @@ node_modules/
|
|
|
7132
7350
|
files.set(join14(project, "app", "index.tsx"), webRouteSource);
|
|
7133
7351
|
}
|
|
7134
7352
|
files.set(join14(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
7353
|
+
const nativeRouteRuntime = join14(project, "src", "generated", "AbsoluteNativeRoute.tsx");
|
|
7135
7354
|
for (const [route, module] of routeModules) {
|
|
7136
7355
|
const wrapper = route === "/" ? join14(project, "app", "index.tsx") : routeFile(project, route);
|
|
7137
|
-
files.set(wrapper, nativeWrapperSource(wrapper, module));
|
|
7356
|
+
files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
|
|
7138
7357
|
}
|
|
7139
7358
|
const removed = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join14(project, "app")}${sep6}`))));
|
|
7140
7359
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
@@ -7177,11 +7396,13 @@ var installStagedDirectory = async (staging, destination) => {
|
|
|
7177
7396
|
throw error;
|
|
7178
7397
|
}
|
|
7179
7398
|
};
|
|
7180
|
-
var assetModuleSource = (assets, bundleId) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
|
|
7399
|
+
var assetModuleSource = (assets, bundleId, manifest) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
|
|
7181
7400
|
import { Directory, File, Paths } from 'expo-file-system';
|
|
7182
7401
|
|
|
7402
|
+
${nativeDataManifestTypeSource}
|
|
7183
7403
|
declare const require: (path: string) => number;
|
|
7184
7404
|
const BUNDLE_ID = ${JSON.stringify(bundleId)};
|
|
7405
|
+
export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest = ${JSON.stringify(manifest)};
|
|
7185
7406
|
const ASSETS = [
|
|
7186
7407
|
${assets.map(({ asset, path }) => ` { module: require(${JSON.stringify(asset)}), path: ${JSON.stringify(path)} }`).join(`,
|
|
7187
7408
|
`)}
|
|
@@ -7215,9 +7436,8 @@ var syncAbsoluteExpoWebAssets = async (config) => {
|
|
|
7215
7436
|
}
|
|
7216
7437
|
const manifestPath = join14(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
7217
7438
|
const manifest = JSON.parse(await readFile14(manifestPath, "utf8"));
|
|
7218
|
-
const
|
|
7219
|
-
|
|
7220
|
-
throw new TypeError("AbsoluteJS mobile manifest has no appBuild.");
|
|
7439
|
+
const nativeDataManifest = expoNativeDataManifest(manifest);
|
|
7440
|
+
const { appBuild } = nativeDataManifest;
|
|
7221
7441
|
const files = await walkFiles(config.bundleDirectory);
|
|
7222
7442
|
const bundleHash = createHash10("sha256");
|
|
7223
7443
|
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile14(file), file })));
|
|
@@ -7247,7 +7467,7 @@ var syncAbsoluteExpoWebAssets = async (config) => {
|
|
|
7247
7467
|
throw error;
|
|
7248
7468
|
}
|
|
7249
7469
|
const generated = join14(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
7250
|
-
await writeManagedFile(generated, assetModuleSource(assets, bundleId), true);
|
|
7470
|
+
await writeManagedFile(generated, assetModuleSource(assets, bundleId, nativeDataManifest), true);
|
|
7251
7471
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
7252
7472
|
};
|
|
7253
7473
|
|
|
@@ -7564,7 +7784,7 @@ var ABSOLUTE_EXPO_BRIDGE_METHODS = [
|
|
|
7564
7784
|
"sync.socket.open",
|
|
7565
7785
|
"sync.socket.sendChunk"
|
|
7566
7786
|
];
|
|
7567
|
-
var
|
|
7787
|
+
var isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
7568
7788
|
var validId = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,80}$/u.test(value);
|
|
7569
7789
|
var validPath = (value) => typeof value === "string" && value.startsWith("/") && !value.startsWith("//") && value.length <= 4096;
|
|
7570
7790
|
var parseRequest = (value) => {
|
|
@@ -7574,7 +7794,7 @@ var parseRequest = (value) => {
|
|
|
7574
7794
|
if (!method) {
|
|
7575
7795
|
throw new TypeError("Expo bridge method is not allowed.");
|
|
7576
7796
|
}
|
|
7577
|
-
if (!
|
|
7797
|
+
if (!isRecord9(value.params))
|
|
7578
7798
|
throw new TypeError("Expo bridge request params must be an object.");
|
|
7579
7799
|
if (typeof value.path !== "string" || !validPath(value.path))
|
|
7580
7800
|
throw new TypeError("Expo bridge request path is invalid.");
|
|
@@ -7610,7 +7830,7 @@ var parseRequest = (value) => {
|
|
|
7610
7830
|
throw new TypeError("Expo bridge HTTP body exceeds 48 KiB.");
|
|
7611
7831
|
if ((value.params.method === "GET" || value.params.method === "DELETE") && value.params.body !== undefined)
|
|
7612
7832
|
throw new TypeError("Expo bridge HTTP method cannot contain a body.");
|
|
7613
|
-
if (!
|
|
7833
|
+
if (!isRecord9(value.params.headers))
|
|
7614
7834
|
throw new TypeError("Expo bridge HTTP headers must be an object.");
|
|
7615
7835
|
const headersAllowed = Object.entries(value.params.headers).every(([name, header]) => typeof header === "string" && (name.toLowerCase() === "accept" || name.toLowerCase() === "content-type" || name.toLowerCase().startsWith("x-absolute-mobile-")));
|
|
7616
7836
|
if (!headersAllowed) {
|
|
@@ -7636,13 +7856,13 @@ var parseResponse = (value) => {
|
|
|
7636
7856
|
if (typeof value.id !== "string" || !validId(value.id))
|
|
7637
7857
|
throw new TypeError("Expo bridge response id is invalid.");
|
|
7638
7858
|
if (value.error !== undefined) {
|
|
7639
|
-
if (!
|
|
7859
|
+
if (!isRecord9(value.error) || typeof value.error.code !== "string" || typeof value.error.message !== "string") {
|
|
7640
7860
|
throw new TypeError("Expo bridge response error is invalid.");
|
|
7641
7861
|
}
|
|
7642
7862
|
if (value.result !== undefined)
|
|
7643
7863
|
throw new TypeError("Expo bridge response cannot contain result and error.");
|
|
7644
7864
|
}
|
|
7645
|
-
if (
|
|
7865
|
+
if (isRecord9(value.error)) {
|
|
7646
7866
|
return {
|
|
7647
7867
|
error: {
|
|
7648
7868
|
code: String(value.error.code),
|
|
@@ -7666,7 +7886,7 @@ var parseEvent = (value) => {
|
|
|
7666
7886
|
}
|
|
7667
7887
|
if (typeof value.path !== "string" || !validPath(value.path))
|
|
7668
7888
|
throw new TypeError("Expo bridge event path is invalid.");
|
|
7669
|
-
if (value.payload !== undefined && !
|
|
7889
|
+
if (value.payload !== undefined && !isRecord9(value.payload)) {
|
|
7670
7890
|
throw new TypeError("Expo bridge event payload must be an object.");
|
|
7671
7891
|
}
|
|
7672
7892
|
return {
|
|
@@ -7700,7 +7920,7 @@ var parseAbsoluteExpoBridgeMessage = (source) => {
|
|
|
7700
7920
|
cause
|
|
7701
7921
|
});
|
|
7702
7922
|
}
|
|
7703
|
-
if (!
|
|
7923
|
+
if (!isRecord9(parsed) || parsed.format !== ABSOLUTE_EXPO_BRIDGE_FORMAT) {
|
|
7704
7924
|
throw new TypeError("Expo bridge message format is unsupported.");
|
|
7705
7925
|
}
|
|
7706
7926
|
if (parsed.kind === "request")
|
|
@@ -8698,7 +8918,7 @@ init_telemetryEvent();
|
|
|
8698
8918
|
import { Elysia as Elysia3 } from "elysia";
|
|
8699
8919
|
var ABSOLUTE_MOBILE_PREVIEW_PATH = "/__absolute/mobile-preview";
|
|
8700
8920
|
var escapeHtml2 = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
8701
|
-
var
|
|
8921
|
+
var isRecord10 = (value) => typeof value === "object" && value !== null;
|
|
8702
8922
|
var normalizeEntry2 = (entry) => {
|
|
8703
8923
|
const parsed = new URL(entry ?? "/", "https://absolute.invalid");
|
|
8704
8924
|
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
@@ -8749,7 +8969,7 @@ var createAbsoluteMobilePreviewPlugin = (mobile) => {
|
|
|
8749
8969
|
"X-Robots-Tag": "noindex, nofollow"
|
|
8750
8970
|
}
|
|
8751
8971
|
})).post("/__absolute/mobile-preview-telemetry", ({ body, status }) => {
|
|
8752
|
-
const value =
|
|
8972
|
+
const value = isRecord10(body) ? body : undefined;
|
|
8753
8973
|
const durationMs = value?.durationMs;
|
|
8754
8974
|
const platform2 = value?.platform;
|
|
8755
8975
|
if (typeof durationMs !== "number" || !Number.isFinite(durationMs) || durationMs < 0 || durationMs > 300000 || platform2 !== "android" && platform2 !== "ios") {
|
|
@@ -9306,8 +9526,8 @@ var prepareAbsoluteAndroidRelease = async (publisher, options) => {
|
|
|
9306
9526
|
}
|
|
9307
9527
|
return versionCode;
|
|
9308
9528
|
};
|
|
9309
|
-
var
|
|
9310
|
-
var isPublisher = (value) =>
|
|
9529
|
+
var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9530
|
+
var isPublisher = (value) => isRecord11(value) && typeof value.publish === "function";
|
|
9311
9531
|
var publisherModulePath = (projectRoot, requested) => {
|
|
9312
9532
|
const root = resolve15(projectRoot);
|
|
9313
9533
|
const path = resolve15(root, requested);
|
|
@@ -9323,7 +9543,7 @@ var loadAbsoluteNativeReleasePublisher = async (projectRoot, requestedModulePath
|
|
|
9323
9543
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
9324
9544
|
});
|
|
9325
9545
|
const loaded = await import(pathToFileURL3(modulePath).href);
|
|
9326
|
-
const publisher =
|
|
9546
|
+
const publisher = isRecord11(loaded) ? loaded.default ?? loaded.registry : undefined;
|
|
9327
9547
|
if (!isPublisher(publisher)) {
|
|
9328
9548
|
throw new TypeError("Native release registry module must default-export a registry with publish(options).");
|
|
9329
9549
|
}
|
|
@@ -10139,6 +10359,7 @@ export {
|
|
|
10139
10359
|
ABSOLUTE_MOBILE_TRANSFORM_PROTOCOL,
|
|
10140
10360
|
ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV,
|
|
10141
10361
|
ABSOLUTE_NATIVE_AUTH_SCOPES,
|
|
10362
|
+
ABSOLUTE_NATIVE_ROUTE_DATA_MEDIA_TYPE,
|
|
10142
10363
|
ABSOLUTE_REMOTE_MAC_EVENT_PREFIX,
|
|
10143
10364
|
ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION,
|
|
10144
10365
|
ABSOLUTE_SYNC_PACKAGE,
|
|
@@ -10153,6 +10374,7 @@ export {
|
|
|
10153
10374
|
absoluteRemoteMacSshBase,
|
|
10154
10375
|
absoluteRemoteProjectSyncCommands,
|
|
10155
10376
|
acceptsAbsoluteMobilePage,
|
|
10377
|
+
acceptsAbsoluteNativeRouteData,
|
|
10156
10378
|
activateAbsoluteMobilePage,
|
|
10157
10379
|
applyAbsoluteNativeDeepLinks,
|
|
10158
10380
|
applyAbsoluteNativeDeviceCapabilities,
|
|
@@ -10272,5 +10494,5 @@ export {
|
|
|
10272
10494
|
writeAbsoluteMobileGithubWorkflow
|
|
10273
10495
|
};
|
|
10274
10496
|
|
|
10275
|
-
//# debugId=
|
|
10497
|
+
//# debugId=4795A6FB7632A5BE64756E2164756E21
|
|
10276
10498
|
//# sourceMappingURL=index.js.map
|