@absolutejs/absolute 0.20.0-beta.46 → 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 +354 -104
- package/dist/index.js +79 -5
- package/dist/index.js.map +4 -4
- package/dist/mobile/browser.js +38 -1
- package/dist/mobile/browser.js.map +3 -3
- package/dist/mobile/index.js +336 -43
- package/dist/mobile/index.js.map +6 -6
- package/dist/mobile/remoteMacAgentEntry.js +292 -144
- package/dist/mobile/shellExpoAuth.js +3 -3
- package/dist/mobile/shellExpoDevices.js +3 -3
- 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/types/build.d.ts +4 -1
- 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/cli/index.js
CHANGED
|
@@ -718,7 +718,7 @@ var init_portScan = () => {};
|
|
|
718
718
|
|
|
719
719
|
// src/mobile/config.ts
|
|
720
720
|
import { resolve as resolve2 } from "path";
|
|
721
|
-
var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, HOSTNAME_PATTERN, resolveProjectPath = (projectRoot, value, field) => {
|
|
721
|
+
var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field) => {
|
|
722
722
|
const root = resolve2(projectRoot);
|
|
723
723
|
const path = resolve2(root, value);
|
|
724
724
|
if (path !== root && !path.startsWith(`${root}/`)) {
|
|
@@ -791,11 +791,31 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
791
791
|
}
|
|
792
792
|
return value.match(/.{2}/g)?.join(":") ?? value;
|
|
793
793
|
}))
|
|
794
|
-
].sort(),
|
|
794
|
+
].sort(), validateExpoNativeRouteSegment = (path, segment, index, count, parameters) => {
|
|
795
|
+
if (segment === "*" && (index !== count - 1 || count === 1)) {
|
|
796
|
+
throw new TypeError(`mobile.routes.native route ${path} must use * once, as the final segment after a static or parameterized prefix.`);
|
|
797
|
+
}
|
|
798
|
+
if (segment === "*")
|
|
799
|
+
return;
|
|
800
|
+
if (!segment.startsWith(":") && (segment.includes("*") || segment.includes(":"))) {
|
|
801
|
+
throw new TypeError(`mobile.routes.native route ${path} contains invalid segment ${segment}.`);
|
|
802
|
+
}
|
|
803
|
+
if (!segment.startsWith(":"))
|
|
804
|
+
return;
|
|
805
|
+
const name = segment.slice(1);
|
|
806
|
+
if (!/^[A-Za-z][A-Za-z0-9_]*$/u.test(name)) {
|
|
807
|
+
throw new TypeError(`mobile.routes.native route ${path} has invalid parameter ${segment}.`);
|
|
808
|
+
}
|
|
809
|
+
if (parameters.has(name)) {
|
|
810
|
+
throw new TypeError(`mobile.routes.native route ${path} repeats parameter ${segment}.`);
|
|
811
|
+
}
|
|
812
|
+
parameters.add(name);
|
|
813
|
+
}, normalizeExpoNativeRoutes = (config, projectRoot) => {
|
|
795
814
|
if (config.engine !== "expo")
|
|
796
815
|
return {};
|
|
797
816
|
const routes = config.routes?.native ?? {};
|
|
798
817
|
const normalized = {};
|
|
818
|
+
const ownership = new Map;
|
|
799
819
|
for (const [route, module] of Object.entries(routes)) {
|
|
800
820
|
const path = normalizeEntry(route);
|
|
801
821
|
if (path.includes("?") || path.includes("#") || path !== "/" && path.endsWith("/")) {
|
|
@@ -804,9 +824,18 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
|
|
|
804
824
|
if (path === "/__absolute/native") {
|
|
805
825
|
throw new TypeError("mobile.routes.native reserves /__absolute/native for the Expo diagnostic screen.");
|
|
806
826
|
}
|
|
807
|
-
|
|
808
|
-
|
|
827
|
+
const segments = path.split("/").filter(Boolean);
|
|
828
|
+
if (segments[0] && EXPO_RESERVED_ROUTE_PREFIXES.has(segments[0])) {
|
|
829
|
+
throw new TypeError(`mobile.routes.native route ${path} conflicts with an Expo Router or Metro reserved path.`);
|
|
830
|
+
}
|
|
831
|
+
const parameters = new Set;
|
|
832
|
+
segments.forEach((segment, index) => validateExpoNativeRouteSegment(path, segment, index, segments.length, parameters));
|
|
833
|
+
const signature = segments.map((segment) => segment.startsWith(":") ? ":" : segment).join("/");
|
|
834
|
+
const existing = ownership.get(signature);
|
|
835
|
+
if (existing) {
|
|
836
|
+
throw new TypeError(`mobile.routes.native routes ${existing} and ${path} claim the same Expo route pattern.`);
|
|
809
837
|
}
|
|
838
|
+
ownership.set(signature, path);
|
|
810
839
|
normalized[path] = resolveProjectPath(projectRoot, requireText(module, `mobile.routes.native[${path}]`), `mobile.routes.native[${path}]`);
|
|
811
840
|
}
|
|
812
841
|
return Object.fromEntries(Object.entries(normalized).sort(([left], [right]) => left.localeCompare(right)));
|
|
@@ -845,6 +874,16 @@ var init_config = __esm(() => {
|
|
|
845
874
|
APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
|
|
846
875
|
CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
|
|
847
876
|
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])?))*$/;
|
|
877
|
+
EXPO_RESERVED_ROUTE_PREFIXES = new Set([
|
|
878
|
+
"_expo",
|
|
879
|
+
"_flight",
|
|
880
|
+
"_sitemap",
|
|
881
|
+
"assets",
|
|
882
|
+
"expo-dev-plugins",
|
|
883
|
+
"inspector",
|
|
884
|
+
"manifest",
|
|
885
|
+
"public"
|
|
886
|
+
]);
|
|
848
887
|
});
|
|
849
888
|
|
|
850
889
|
// src/mobile/nativeAuth.ts
|
|
@@ -1600,7 +1639,7 @@ import {
|
|
|
1600
1639
|
writeFile
|
|
1601
1640
|
} from "fs/promises";
|
|
1602
1641
|
import { createHash } from "crypto";
|
|
1603
|
-
import { basename as basename2, dirname as dirname4, join as join8, relative as relative2, resolve as resolve5 } from "path";
|
|
1642
|
+
import { basename as basename2, dirname as dirname4, join as join8, relative as relative2, resolve as resolve5, sep } from "path";
|
|
1604
1643
|
var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1605
1644
|
`, EXPO_ASSET_EXTENSION = ".absasset", EXPO_PROJECT_MARKER = ".absolutejs-expo-project", exists = async (path) => {
|
|
1606
1645
|
try {
|
|
@@ -1609,17 +1648,61 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1609
1648
|
} catch {
|
|
1610
1649
|
return false;
|
|
1611
1650
|
}
|
|
1651
|
+
}, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifestString = (value, field) => {
|
|
1652
|
+
if (typeof value !== "string" || !value) {
|
|
1653
|
+
throw new TypeError(`AbsoluteJS mobile manifest ${field} is invalid.`);
|
|
1654
|
+
}
|
|
1655
|
+
return value;
|
|
1656
|
+
}, expoNativeDataManifest = (value) => {
|
|
1657
|
+
if (!isRecord(value) || !Array.isArray(value.pages) || !Array.isArray(value.routes)) {
|
|
1658
|
+
throw new TypeError("AbsoluteJS mobile manifest is invalid.");
|
|
1659
|
+
}
|
|
1660
|
+
const pages = value.pages.map((page) => {
|
|
1661
|
+
if (!isRecord(page))
|
|
1662
|
+
throw new TypeError("AbsoluteJS mobile manifest page is invalid.");
|
|
1663
|
+
return {
|
|
1664
|
+
bundleHash: requireManifestString(page.bundleHash, "page.bundleHash"),
|
|
1665
|
+
contract: requireManifestString(page.contract, "page.contract"),
|
|
1666
|
+
pageId: requireManifestString(page.pageId, "page.pageId")
|
|
1667
|
+
};
|
|
1668
|
+
});
|
|
1669
|
+
const routes = value.routes.flatMap((route) => {
|
|
1670
|
+
if (!isRecord(route) || typeof route.method !== "string") {
|
|
1671
|
+
throw new TypeError("AbsoluteJS mobile manifest route is invalid.");
|
|
1672
|
+
}
|
|
1673
|
+
if (route.method !== "GET")
|
|
1674
|
+
return [];
|
|
1675
|
+
return [
|
|
1676
|
+
{
|
|
1677
|
+
method: "GET",
|
|
1678
|
+
pageId: requireManifestString(route.pageId, "route.pageId"),
|
|
1679
|
+
pattern: requireManifestString(route.pattern, "route.pattern")
|
|
1680
|
+
}
|
|
1681
|
+
];
|
|
1682
|
+
});
|
|
1683
|
+
return {
|
|
1684
|
+
appBuild: requireManifestString(value.appBuild, "appBuild"),
|
|
1685
|
+
pages,
|
|
1686
|
+
productionOrigin: requireManifestString(value.productionOrigin, "productionOrigin"),
|
|
1687
|
+
routes,
|
|
1688
|
+
runtime: requireManifestString(value.runtime, "runtime")
|
|
1689
|
+
};
|
|
1612
1690
|
}, portableRelative = (from, destination) => {
|
|
1613
1691
|
const value = relative2(from, destination).replaceAll("\\", "/");
|
|
1614
1692
|
return value.startsWith(".") ? value : `./${value}`;
|
|
1615
|
-
}, routeSegments = (route) =>
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1693
|
+
}, routeSegments = (route) => {
|
|
1694
|
+
const segments = route.split("/").filter(Boolean);
|
|
1695
|
+
return segments.map((segment, index) => {
|
|
1696
|
+
if (segment.startsWith(":"))
|
|
1697
|
+
return `[${segment.slice(1)}]`;
|
|
1698
|
+
if (segment === "*" && index === segments.length - 1)
|
|
1699
|
+
return "[...absoluteWildcard]";
|
|
1700
|
+
if (segment === "." || segment === ".." || !/^[A-Za-z0-9._~-]+$/u.test(segment)) {
|
|
1701
|
+
throw new TypeError(`Expo native route ${route} contains an unsupported segment ${segment}.`);
|
|
1702
|
+
}
|
|
1703
|
+
return segment;
|
|
1704
|
+
});
|
|
1705
|
+
}, routeFile = (project, route) => join8(project, "app", ...routeSegments(route), "index.tsx"), packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
1623
1706
|
const separator = spec.lastIndexOf("@");
|
|
1624
1707
|
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
1625
1708
|
})), expoPackage = (auth, sync, devices) => ({
|
|
@@ -2005,6 +2088,7 @@ export const createAbsoluteExpoSyncBridge = async (
|
|
|
2005
2088
|
"/__absolute/native",
|
|
2006
2089
|
...Object.keys(config.expoNativeRoutes)
|
|
2007
2090
|
];
|
|
2091
|
+
const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
|
|
2008
2092
|
return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
|
|
2009
2093
|
import { router, usePathname } from 'expo-router';
|
|
2010
2094
|
import { useEffect, useRef, useState } from 'react';
|
|
@@ -2019,7 +2103,7 @@ ${sync ? "import { createAbsoluteExpoSyncBridge, startAbsoluteExpoSync } from '.
|
|
|
2019
2103
|
const BRIDGE_FORMAT = 3;
|
|
2020
2104
|
const MAX_MESSAGE_BYTES = 64 * 1024;
|
|
2021
2105
|
const MAX_HTTP_BODY_BYTES = 48 * 1024;
|
|
2022
|
-
const
|
|
2106
|
+
const NATIVE_ROUTE_PATTERNS = ${JSON.stringify(nativeRoutePatterns)};
|
|
2023
2107
|
const PRODUCTION_ORIGIN = ${JSON.stringify(config.productionOrigin)};
|
|
2024
2108
|
const DEV_ORIGIN = Platform.OS === 'android'
|
|
2025
2109
|
? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
|
|
@@ -2028,6 +2112,19 @@ const HMR_TARGET = Platform.OS === 'android' ? 'expo-android' : 'expo-ios';
|
|
|
2028
2112
|
const AUTH_ENABLED = ${auth ? "true" : "false"};
|
|
2029
2113
|
const SYNC_ENABLED = ${sync ? "true" : "false"};
|
|
2030
2114
|
|
|
2115
|
+
const isNativeRoute = (pathname: string) => {
|
|
2116
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
2117
|
+
return NATIVE_ROUTE_PATTERNS.some(pattern => {
|
|
2118
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
2119
|
+
const expected = pattern[index]!;
|
|
2120
|
+
if (expected === '*') return segments.length > index;
|
|
2121
|
+
if (segments[index] === undefined) return false;
|
|
2122
|
+
if (!expected.startsWith(':') && expected !== segments[index]) return false;
|
|
2123
|
+
}
|
|
2124
|
+
return segments.length === pattern.length;
|
|
2125
|
+
});
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2031
2128
|
const bridgeBootstrap = (path: string) => {
|
|
2032
2129
|
const initialPath = DEV_ORIGIN
|
|
2033
2130
|
? 'location.pathname + location.search + location.hash'
|
|
@@ -2103,7 +2200,7 @@ const bridgeBootstrap = (path: string) => {
|
|
|
2103
2200
|
const anchor = event.target instanceof Element ? event.target.closest('a[href]') : null;
|
|
2104
2201
|
if (!anchor) return;
|
|
2105
2202
|
const url = new URL(anchor.href, location.href);
|
|
2106
|
-
if (
|
|
2203
|
+
if (!isNativeRoute(url.pathname)) return;
|
|
2107
2204
|
event.preventDefault();
|
|
2108
2205
|
send({ format: 3, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
|
|
2109
2206
|
}, true);
|
|
@@ -2226,7 +2323,7 @@ export function AbsoluteWebHost() {
|
|
|
2226
2323
|
if (message.kind === 'event' && (message.event === 'navigation' || message.event === 'ready')) {
|
|
2227
2324
|
const target = new URL(message.path, PRODUCTION_ORIGIN);
|
|
2228
2325
|
if (target.origin !== PRODUCTION_ORIGIN) return;
|
|
2229
|
-
if (
|
|
2326
|
+
if (isNativeRoute(target.pathname)) router.push(message.path as never);
|
|
2230
2327
|
else activeWebPath.current = message.path;
|
|
2231
2328
|
return;
|
|
2232
2329
|
}
|
|
@@ -2282,7 +2379,133 @@ export function AbsoluteWebHost() {
|
|
|
2282
2379
|
|
|
2283
2380
|
const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, justifyContent: 'center' }, web: { flex: 1 } });
|
|
2284
2381
|
`;
|
|
2285
|
-
}, webRouteSource, catchAllRouteSource,
|
|
2382
|
+
}, webRouteSource, catchAllRouteSource, nativeRouteRuntimeSource = (auth) => `${EXPO_GENERATED_HEADER}import { useLocalSearchParams, usePathname } from 'expo-router';
|
|
2383
|
+
import { type ComponentType, useEffect, useMemo, useState } from 'react';
|
|
2384
|
+
import { ActivityIndicator, Platform, Pressable, StyleSheet, Text, View } from 'react-native';
|
|
2385
|
+
import { ABSOLUTE_MOBILE_MANIFEST } from './webAssets';
|
|
2386
|
+
${auth ? "import { absoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
2387
|
+
|
|
2388
|
+
const PAGE_MEDIA_TYPE = 'application/vnd.absolute.page+json';
|
|
2389
|
+
const NATIVE_DATA_MEDIA_TYPE = 'application/vnd.absolute.native-route+json';
|
|
2390
|
+
const PROTOCOL = 1;
|
|
2391
|
+
const MAX_DATA_BYTES = 1024 * 1024;
|
|
2392
|
+
const DEV_ORIGIN = Platform.OS === 'android'
|
|
2393
|
+
? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
|
|
2394
|
+
: process.env.EXPO_PUBLIC_ABSOLUTE_DEV_IOS_ORIGIN;
|
|
2395
|
+
|
|
2396
|
+
type RouteParams = Record<string, string | string[] | undefined>;
|
|
2397
|
+
type NativeRouteProps<PageProps extends object, Params extends object> = {
|
|
2398
|
+
pageProps: Readonly<PageProps>;
|
|
2399
|
+
params: Readonly<Params>;
|
|
2400
|
+
reload: () => void;
|
|
2401
|
+
};
|
|
2402
|
+
type NativeRouteState<PageProps> =
|
|
2403
|
+
| { kind: 'loading' }
|
|
2404
|
+
| { kind: 'ready'; pageProps: PageProps }
|
|
2405
|
+
| { kind: 'error' };
|
|
2406
|
+
|
|
2407
|
+
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
2408
|
+
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
2409
|
+
const routeSegmentPattern = (segment: string) => {
|
|
2410
|
+
if (segment === '*') return '.*';
|
|
2411
|
+
if (segment.startsWith(':') && segment.endsWith('?')) return '[^/]*';
|
|
2412
|
+
if (segment.startsWith(':')) return '[^/]+';
|
|
2413
|
+
return segment.replace(/[.*+?^\${}()|[\\]\\\\]/g, '\\\\$&');
|
|
2414
|
+
};
|
|
2415
|
+
const matchesRoute = (pattern: string, pathname: string) =>
|
|
2416
|
+
new RegExp('^' + pattern.split('/').map(routeSegmentPattern).join('/') + '/?$').test(pathname);
|
|
2417
|
+
const requestPathFor = (pathname: string, params: RouteParams, pattern: string) => {
|
|
2418
|
+
const pathNames = new Set(pattern.split('/').filter(segment => segment.startsWith(':')).map(segment => segment.replace(/^:/, '').replace(/\\?$/, '')));
|
|
2419
|
+
if (pattern.endsWith('/*')) pathNames.add('absoluteWildcard');
|
|
2420
|
+
const query = new URLSearchParams();
|
|
2421
|
+
for (const [name, value] of Object.entries(params).sort(([left], [right]) => left.localeCompare(right))) {
|
|
2422
|
+
if (pathNames.has(name) || name === '#' || value === undefined) continue;
|
|
2423
|
+
for (const item of Array.isArray(value) ? value : [value]) query.append(name, item);
|
|
2424
|
+
}
|
|
2425
|
+
const search = query.toString();
|
|
2426
|
+
return pathname + (search ? '?' + search : '');
|
|
2427
|
+
};
|
|
2428
|
+
const productionPage = (pathname: string) => {
|
|
2429
|
+
if (!ABSOLUTE_MOBILE_MANIFEST) throw new Error('AbsoluteJS native route data is not prepared for production.');
|
|
2430
|
+
const route = ABSOLUTE_MOBILE_MANIFEST.routes.find(candidate => candidate.method === 'GET' && matchesRoute(candidate.pattern, pathname));
|
|
2431
|
+
if (!route) throw new Error('No trusted AbsoluteJS page route owns this native URL.');
|
|
2432
|
+
const page = ABSOLUTE_MOBILE_MANIFEST.pages.find(candidate => candidate.pageId === route.pageId);
|
|
2433
|
+
if (!page) throw new Error('The embedded AbsoluteJS page contract is incomplete.');
|
|
2434
|
+
return page;
|
|
2435
|
+
};
|
|
2436
|
+
const createDataRequest = (path: string) => {
|
|
2437
|
+
const development = typeof DEV_ORIGIN === 'string' && DEV_ORIGIN.length > 0;
|
|
2438
|
+
const origin = development ? DEV_ORIGIN : ABSOLUTE_MOBILE_MANIFEST?.productionOrigin;
|
|
2439
|
+
if (!origin) throw new Error('AbsoluteJS native route data has no trusted server origin.');
|
|
2440
|
+
const url = new URL(path, origin);
|
|
2441
|
+
if (url.origin !== new URL(origin).origin) throw new Error('AbsoluteJS native route data left its trusted origin.');
|
|
2442
|
+
const headers = new Headers();
|
|
2443
|
+
headers.set('accept', development ? NATIVE_DATA_MEDIA_TYPE : PAGE_MEDIA_TYPE);
|
|
2444
|
+
headers.set('x-absolute-mobile-protocol', String(PROTOCOL));
|
|
2445
|
+
let page: ReturnType<typeof productionPage> | undefined;
|
|
2446
|
+
if (!development) {
|
|
2447
|
+
page = productionPage(url.pathname);
|
|
2448
|
+
headers.set('x-absolute-mobile-app-build', ABSOLUTE_MOBILE_MANIFEST!.appBuild);
|
|
2449
|
+
headers.set('x-absolute-mobile-page-bundle', page.bundleHash);
|
|
2450
|
+
headers.set('x-absolute-mobile-page-contracts', page.contract);
|
|
2451
|
+
headers.set('x-absolute-mobile-page-id', page.pageId);
|
|
2452
|
+
headers.set('x-absolute-mobile-runtime', ABSOLUTE_MOBILE_MANIFEST!.runtime);
|
|
2453
|
+
}
|
|
2454
|
+
return { page, request: new Request(url, { headers, method: 'GET' }) };
|
|
2455
|
+
};
|
|
2456
|
+
const requestData = async <PageProps extends object>(path: string, signal: AbortSignal) => {
|
|
2457
|
+
const { page, request } = createDataRequest(path);
|
|
2458
|
+
const response = await ${auth ? "absoluteExpoAuth.fetchOptional" : "fetch"}(request, { redirect: 'manual', signal });
|
|
2459
|
+
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.');
|
|
2460
|
+
const source = await response.text();
|
|
2461
|
+
if (new TextEncoder().encode(source).byteLength > MAX_DATA_BYTES) throw new Error('AbsoluteJS native route data exceeded 1 MiB.');
|
|
2462
|
+
let envelope: unknown;
|
|
2463
|
+
try { envelope = JSON.parse(source); } catch { throw new Error('The server did not return an AbsoluteJS page envelope.'); }
|
|
2464
|
+
if (!isRecord(envelope) || envelope.protocol !== PROTOCOL || !isRecord(envelope.response)) throw new Error('The server returned an invalid AbsoluteJS page envelope.');
|
|
2465
|
+
const result = envelope.response;
|
|
2466
|
+
if (result.kind === 'upgrade-required') throw new Error('This app version must be updated before opening this screen.');
|
|
2467
|
+
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.');
|
|
2468
|
+
if (page && (result.pageId !== page.pageId || result.contract !== page.contract)) throw new Error('The server returned a different page contract than this app contains.');
|
|
2469
|
+
return result.props as PageProps;
|
|
2470
|
+
};
|
|
2471
|
+
|
|
2472
|
+
export const createAbsoluteNativeRoute = <
|
|
2473
|
+
PageProps extends object,
|
|
2474
|
+
Params extends object = RouteParams
|
|
2475
|
+
>(Component: ComponentType<NativeRouteProps<PageProps, Params>>, pattern: string) => {
|
|
2476
|
+
function AbsoluteNativeRouteScreen() {
|
|
2477
|
+
const pathname = usePathname() || '/';
|
|
2478
|
+
const params = useLocalSearchParams() as RouteParams;
|
|
2479
|
+
const parameterKey = JSON.stringify(params);
|
|
2480
|
+
const requestPath = useMemo(() => requestPathFor(pathname, params, pattern), [parameterKey, pathname]);
|
|
2481
|
+
const [revision, setRevision] = useState(0);
|
|
2482
|
+
const [state, setState] = useState<NativeRouteState<PageProps>>({ kind: 'loading' });
|
|
2483
|
+
useEffect(() => {
|
|
2484
|
+
const controller = new AbortController();
|
|
2485
|
+
setState({ kind: 'loading' });
|
|
2486
|
+
void requestData<PageProps>(requestPath, controller.signal).then(
|
|
2487
|
+
pageProps => { if (!controller.signal.aborted) setState({ kind: 'ready', pageProps }); },
|
|
2488
|
+
() => { if (!controller.signal.aborted) setState({ kind: 'error' }); }
|
|
2489
|
+
);
|
|
2490
|
+
return () => controller.abort();
|
|
2491
|
+
}, [requestPath, revision]);
|
|
2492
|
+
const reload = () => setRevision(value => value + 1);
|
|
2493
|
+
if (state.kind === 'loading') return <View style={styles.center}><ActivityIndicator accessibilityLabel="Loading screen" /></View>;
|
|
2494
|
+
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>;
|
|
2495
|
+
return <Component pageProps={state.pageProps} params={params as Params} reload={reload} />;
|
|
2496
|
+
}
|
|
2497
|
+
return AbsoluteNativeRouteScreen;
|
|
2498
|
+
};
|
|
2499
|
+
|
|
2500
|
+
const styles = StyleSheet.create({
|
|
2501
|
+
button: { backgroundColor: '#e2e8f0', borderRadius: 10, paddingHorizontal: 16, paddingVertical: 12 },
|
|
2502
|
+
center: { alignItems: 'center', flex: 1, gap: 16, justifyContent: 'center', padding: 24 },
|
|
2503
|
+
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
2504
|
+
});
|
|
2505
|
+
`, nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative(dirname4(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
2506
|
+
import { createAbsoluteNativeRoute } from ${JSON.stringify(portableRelative(dirname4(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
2507
|
+
|
|
2508
|
+
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
2286
2509
|
`, expoTsConfig = (projectRoot, project, auth, sync) => ({
|
|
2287
2510
|
compilerOptions: {
|
|
2288
2511
|
paths: {
|
|
@@ -2332,7 +2555,25 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
2332
2555
|
await writeFile(temporary, source, { flag: "wx" });
|
|
2333
2556
|
await rename(temporary, path);
|
|
2334
2557
|
return true;
|
|
2558
|
+
}, pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
2559
|
+
const appDirectory = join8(project, "app");
|
|
2560
|
+
if (!await exists(appDirectory))
|
|
2561
|
+
return 0;
|
|
2562
|
+
const files = await walkFiles(appDirectory);
|
|
2563
|
+
const stale = (await Promise.all(files.map(async (path) => ({
|
|
2564
|
+
managed: path.endsWith(".tsx") && (await readFile(path, "utf8")).startsWith(EXPO_GENERATED_HEADER),
|
|
2565
|
+
path
|
|
2566
|
+
})))).filter(({ managed, path }) => managed && !expected.has(path));
|
|
2567
|
+
await Promise.all(stale.map(({ path }) => rm(path, { force: true })));
|
|
2568
|
+
return stale.length;
|
|
2335
2569
|
}, jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
2570
|
+
`, nativeDataManifestTypeSource = `type AbsoluteMobileManifest = {
|
|
2571
|
+
appBuild: string;
|
|
2572
|
+
pages: readonly { bundleHash: string; contract: string; pageId: string }[];
|
|
2573
|
+
productionOrigin: string;
|
|
2574
|
+
routes: readonly { method: 'GET'; pageId: string; pattern: string }[];
|
|
2575
|
+
runtime: string;
|
|
2576
|
+
};
|
|
2336
2577
|
`, emptyWebAssetsSource, writeAbsoluteExpoProject = async (config, options) => {
|
|
2337
2578
|
if (config.engine !== "expo")
|
|
2338
2579
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
@@ -2402,6 +2643,10 @@ node_modules/
|
|
|
2402
2643
|
join8(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
2403
2644
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
2404
2645
|
],
|
|
2646
|
+
[
|
|
2647
|
+
join8(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
2648
|
+
nativeRouteRuntimeSource(authEnabled)
|
|
2649
|
+
],
|
|
2405
2650
|
[
|
|
2406
2651
|
join8(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
2407
2652
|
webHostSource(config, auth, syncEnabled)
|
|
@@ -2421,12 +2666,14 @@ node_modules/
|
|
|
2421
2666
|
files.set(join8(project, "app", "index.tsx"), webRouteSource);
|
|
2422
2667
|
}
|
|
2423
2668
|
files.set(join8(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
2669
|
+
const nativeRouteRuntime = join8(project, "src", "generated", "AbsoluteNativeRoute.tsx");
|
|
2424
2670
|
for (const [route, module] of routeModules) {
|
|
2425
2671
|
const wrapper = route === "/" ? join8(project, "app", "index.tsx") : routeFile(project, route);
|
|
2426
|
-
files.set(wrapper, nativeWrapperSource(wrapper, module));
|
|
2672
|
+
files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
|
|
2427
2673
|
}
|
|
2674
|
+
const removed = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join8(project, "app")}${sep}`))));
|
|
2428
2675
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
2429
|
-
const changed = changes.filter(Boolean).length;
|
|
2676
|
+
const changed = removed + changes.filter(Boolean).length;
|
|
2430
2677
|
return { changed, path: project, written: [...files.keys()] };
|
|
2431
2678
|
}, walkFiles = async (root, directory = root) => {
|
|
2432
2679
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
@@ -2461,11 +2708,13 @@ node_modules/
|
|
|
2461
2708
|
await rename(backup, destination);
|
|
2462
2709
|
throw error;
|
|
2463
2710
|
}
|
|
2464
|
-
}, assetModuleSource = (assets, bundleId) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
|
|
2711
|
+
}, assetModuleSource = (assets, bundleId, manifest) => `${EXPO_GENERATED_HEADER}import { Asset } from 'expo-asset';
|
|
2465
2712
|
import { Directory, File, Paths } from 'expo-file-system';
|
|
2466
2713
|
|
|
2714
|
+
${nativeDataManifestTypeSource}
|
|
2467
2715
|
declare const require: (path: string) => number;
|
|
2468
2716
|
const BUNDLE_ID = ${JSON.stringify(bundleId)};
|
|
2717
|
+
export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest = ${JSON.stringify(manifest)};
|
|
2469
2718
|
const ASSETS = [
|
|
2470
2719
|
${assets.map(({ asset, path }) => ` { module: require(${JSON.stringify(asset)}), path: ${JSON.stringify(path)} }`).join(`,
|
|
2471
2720
|
`)}
|
|
@@ -2498,9 +2747,8 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2498
2747
|
}
|
|
2499
2748
|
const manifestPath = join8(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
2500
2749
|
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
2501
|
-
const
|
|
2502
|
-
|
|
2503
|
-
throw new TypeError("AbsoluteJS mobile manifest has no appBuild.");
|
|
2750
|
+
const nativeDataManifest = expoNativeDataManifest(manifest);
|
|
2751
|
+
const { appBuild } = nativeDataManifest;
|
|
2504
2752
|
const files = await walkFiles(config.bundleDirectory);
|
|
2505
2753
|
const bundleHash = createHash("sha256");
|
|
2506
2754
|
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile(file), file })));
|
|
@@ -2530,7 +2778,7 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2530
2778
|
throw error;
|
|
2531
2779
|
}
|
|
2532
2780
|
const generated = join8(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
2533
|
-
await writeManagedFile(generated, assetModuleSource(assets, bundleId), true);
|
|
2781
|
+
await writeManagedFile(generated, assetModuleSource(assets, bundleId, nativeDataManifest), true);
|
|
2534
2782
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
2535
2783
|
};
|
|
2536
2784
|
var init_expoProject = __esm(() => {
|
|
@@ -2627,9 +2875,11 @@ export default AbsoluteWebHost;
|
|
|
2627
2875
|
|
|
2628
2876
|
export default AbsoluteWebHost;
|
|
2629
2877
|
`;
|
|
2630
|
-
emptyWebAssetsSource = `${EXPO_GENERATED_HEADER}
|
|
2878
|
+
emptyWebAssetsSource = `${EXPO_GENERATED_HEADER}${nativeDataManifestTypeSource}
|
|
2879
|
+
export const materializeAbsoluteWebBundle = async () => {
|
|
2631
2880
|
throw new Error('The embedded AbsoluteJS bundle is unavailable. Run absolute prepare before a production Expo build.');
|
|
2632
2881
|
};
|
|
2882
|
+
export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest | undefined = undefined;
|
|
2633
2883
|
`;
|
|
2634
2884
|
});
|
|
2635
2885
|
|
|
@@ -3142,7 +3392,7 @@ import {
|
|
|
3142
3392
|
join as join11,
|
|
3143
3393
|
relative as relative4,
|
|
3144
3394
|
resolve as resolve8,
|
|
3145
|
-
sep,
|
|
3395
|
+
sep as sep2,
|
|
3146
3396
|
win32
|
|
3147
3397
|
} from "path";
|
|
3148
3398
|
var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_FORMAT = 1, NATIVE_CACHE_FORMAT = 1, HASH_RADIX = 16, EXECUTABLE_MODE_MASK = 73, NATIVE_PUBLIC_PATH_SEGMENTS = 5, CAPACITOR_PROJECT_DIRECTORY_PATTERN, ANDROID_TIMING_PHASES, androidTimingSummary = (timings, physicalDevice = false) => ANDROID_TIMING_PHASES.map(([phase, label]) => {
|
|
@@ -3324,12 +3574,12 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3324
3574
|
const resolvedRoot = resolve8(root);
|
|
3325
3575
|
const resolvedPath = resolve8(path);
|
|
3326
3576
|
const relativePath = relative4(resolvedRoot, resolvedPath);
|
|
3327
|
-
return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${
|
|
3328
|
-
},
|
|
3329
|
-
if (!
|
|
3577
|
+
return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${sep2}`) && !isAbsolute(relativePath);
|
|
3578
|
+
}, isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), nativeCachePath = (projectRoot) => join11(projectRoot, ".absolutejs", "mobile", "cache", "android-debug.json"), parseNativeCache = (value) => {
|
|
3579
|
+
if (!isRecord2(value))
|
|
3330
3580
|
return null;
|
|
3331
3581
|
const { appId, fingerprint, format, installations } = value;
|
|
3332
|
-
if (format !== NATIVE_CACHE_FORMAT || typeof appId !== "string" || typeof fingerprint !== "string" || !
|
|
3582
|
+
if (format !== NATIVE_CACHE_FORMAT || typeof appId !== "string" || typeof fingerprint !== "string" || !isRecord2(installations) || !Object.values(installations).every((identity) => typeof identity === "string")) {
|
|
3333
3583
|
return null;
|
|
3334
3584
|
}
|
|
3335
3585
|
return {
|
|
@@ -3368,7 +3618,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3368
3618
|
}
|
|
3369
3619
|
return { dependencies, settings };
|
|
3370
3620
|
}, shouldIgnoreNativePath = (relativePath, ignorePublicBundle) => {
|
|
3371
|
-
const parts = relativePath.split(
|
|
3621
|
+
const parts = relativePath.split(sep2);
|
|
3372
3622
|
if (parts.includes(".gradle") || parts.includes("build") || parts.includes(".absolutejs-dependencies")) {
|
|
3373
3623
|
return true;
|
|
3374
3624
|
}
|
|
@@ -3377,7 +3627,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3377
3627
|
const relativePath = relative4(root, path);
|
|
3378
3628
|
if (shouldIgnoreNativePath(relativePath, ignorePublicBundle))
|
|
3379
3629
|
return [];
|
|
3380
|
-
const identity = `${label}:${relativePath.split(
|
|
3630
|
+
const identity = `${label}:${relativePath.split(sep2).join("/")}\x00`;
|
|
3381
3631
|
if (isDirectory) {
|
|
3382
3632
|
return collectNativeDirectory(root, label, path, ignorePublicBundle);
|
|
3383
3633
|
}
|
|
@@ -3434,7 +3684,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3434
3684
|
if ((manifestBackupPath !== undefined || nativeManifestPath !== undefined) && (typeof manifestBackupPath !== "string" || typeof nativeManifestPath !== "string")) {
|
|
3435
3685
|
return null;
|
|
3436
3686
|
}
|
|
3437
|
-
if (projectedFiles !== undefined && (!Array.isArray(projectedFiles) || !projectedFiles.every((file) =>
|
|
3687
|
+
if (projectedFiles !== undefined && (!Array.isArray(projectedFiles) || !projectedFiles.every((file) => isRecord2(file) && typeof file.path === "string" && (file.backupPath === undefined || typeof file.backupPath === "string")))) {
|
|
3438
3688
|
return null;
|
|
3439
3689
|
}
|
|
3440
3690
|
return {
|
|
@@ -3520,7 +3770,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3520
3770
|
const source = await readFile4(nativeConfigPath, "utf8");
|
|
3521
3771
|
const manifestSource = await readFile4(nativeManifestPath, "utf8");
|
|
3522
3772
|
const parsed = JSON.parse(source);
|
|
3523
|
-
if (!
|
|
3773
|
+
if (!isRecord2(parsed)) {
|
|
3524
3774
|
throw new Error(`Invalid Capacitor native config at ${nativeConfigPath}.`);
|
|
3525
3775
|
}
|
|
3526
3776
|
await mkdir2(paths.root, { recursive: true });
|
|
@@ -4442,7 +4692,7 @@ import {
|
|
|
4442
4692
|
stat,
|
|
4443
4693
|
writeFile as writeFile4
|
|
4444
4694
|
} from "fs/promises";
|
|
4445
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join13, relative as relative5, resolve as resolve9, sep as
|
|
4695
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join13, relative as relative5, resolve as resolve9, sep as sep3 } from "path";
|
|
4446
4696
|
var developmentTeamArgument = (value) => {
|
|
4447
4697
|
if (value === undefined)
|
|
4448
4698
|
return;
|
|
@@ -4450,8 +4700,8 @@ var developmentTeamArgument = (value) => {
|
|
|
4450
4700
|
if (!/^[A-Z0-9]{10}$/u.test(team))
|
|
4451
4701
|
throw new TypeError("iOS development team must contain ten letters or digits.");
|
|
4452
4702
|
return `DEVELOPMENT_TEAM=${team}`;
|
|
4453
|
-
},
|
|
4454
|
-
if (!
|
|
4703
|
+
}, isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifest = (value) => {
|
|
4704
|
+
if (!isRecord3(value) || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.runtime !== "string") {
|
|
4455
4705
|
throw new TypeError("Invalid embedded AbsoluteJS mobile manifest.");
|
|
4456
4706
|
}
|
|
4457
4707
|
return {
|
|
@@ -4524,7 +4774,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4524
4774
|
const root = resolve9(projectRoot);
|
|
4525
4775
|
const output = resolve9(root, requested ?? ".absolutejs/mobile/releases/ios");
|
|
4526
4776
|
const projectRelative = relative5(root, output);
|
|
4527
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
4777
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep3}`) || isAbsolute2(projectRelative)) {
|
|
4528
4778
|
throw new TypeError("mobile build --outdir must remain inside the project.");
|
|
4529
4779
|
}
|
|
4530
4780
|
return output;
|
|
@@ -4560,7 +4810,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4560
4810
|
const destination = join13(releaseRoot, "App.ipa");
|
|
4561
4811
|
if (await pathExists3(releaseRoot)) {
|
|
4562
4812
|
const value = JSON.parse(await readFile6(join13(releaseRoot, "release.json"), "utf8"));
|
|
4563
|
-
if (!
|
|
4813
|
+
if (!isRecord3(value) || value.artifact !== "App.ipa" || Object.entries(metadata).some(([key, expected]) => Reflect.get(value, key) !== expected)) {
|
|
4564
4814
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
|
|
4565
4815
|
}
|
|
4566
4816
|
const [bytes, sha256] = await Promise.all([
|
|
@@ -4720,8 +4970,8 @@ import {
|
|
|
4720
4970
|
writeFile as writeFile5
|
|
4721
4971
|
} from "fs/promises";
|
|
4722
4972
|
import { isIP as isIP2 } from "net";
|
|
4723
|
-
import { dirname as dirname7, isAbsolute as isAbsolute3, join as join14, relative as relative6, resolve as resolve10, sep as
|
|
4724
|
-
var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000, BOOT_POLL_MS = 1000, DEV_JOURNAL_FORMAT2 = 1, NATIVE_CACHE_FORMAT2 = 1,
|
|
4973
|
+
import { dirname as dirname7, isAbsolute as isAbsolute3, join as join14, relative as relative6, resolve as resolve10, sep as sep4 } from "path";
|
|
4974
|
+
var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000, BOOT_POLL_MS = 1000, DEV_JOURNAL_FORMAT2 = 1, NATIVE_CACHE_FORMAT2 = 1, isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), pathExists4 = async (path) => {
|
|
4725
4975
|
try {
|
|
4726
4976
|
await access7(path);
|
|
4727
4977
|
return true;
|
|
@@ -4855,7 +5105,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4855
5105
|
}, parseJson = (source, label) => {
|
|
4856
5106
|
try {
|
|
4857
5107
|
const parsed = JSON.parse(source);
|
|
4858
|
-
if (
|
|
5108
|
+
if (isRecord4(parsed))
|
|
4859
5109
|
return parsed;
|
|
4860
5110
|
} catch {}
|
|
4861
5111
|
throw new Error(`Invalid ${label} JSON from simctl.`);
|
|
@@ -4865,7 +5115,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4865
5115
|
if (!Array.isArray(types))
|
|
4866
5116
|
return [];
|
|
4867
5117
|
return types.flatMap((type) => {
|
|
4868
|
-
if (!
|
|
5118
|
+
if (!isRecord4(type))
|
|
4869
5119
|
return [];
|
|
4870
5120
|
const { identifier } = type;
|
|
4871
5121
|
const { name } = type;
|
|
@@ -4877,7 +5127,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4877
5127
|
if (!Array.isArray(runtimes))
|
|
4878
5128
|
return [];
|
|
4879
5129
|
return runtimes.flatMap((runtime) => {
|
|
4880
|
-
if (!
|
|
5130
|
+
if (!isRecord4(runtime))
|
|
4881
5131
|
return [];
|
|
4882
5132
|
const { identifier } = runtime;
|
|
4883
5133
|
const { name } = runtime;
|
|
@@ -4896,13 +5146,13 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4896
5146
|
}, parseIosSimulators = (source) => {
|
|
4897
5147
|
const parsed = parseJson(source, "device");
|
|
4898
5148
|
const { devices } = parsed;
|
|
4899
|
-
if (!
|
|
5149
|
+
if (!isRecord4(devices))
|
|
4900
5150
|
return [];
|
|
4901
5151
|
return Object.entries(devices).flatMap(([runtime, values]) => {
|
|
4902
5152
|
if (!Array.isArray(values))
|
|
4903
5153
|
return [];
|
|
4904
5154
|
return values.flatMap((device) => {
|
|
4905
|
-
if (!
|
|
5155
|
+
if (!isRecord4(device))
|
|
4906
5156
|
return [];
|
|
4907
5157
|
const { name } = device;
|
|
4908
5158
|
const { state } = device;
|
|
@@ -4947,9 +5197,9 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4947
5197
|
};
|
|
4948
5198
|
}, nativeCachePath2 = (projectRoot) => join14(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json"), isInside2 = (root, path) => {
|
|
4949
5199
|
const value = relative6(resolve10(root), resolve10(path));
|
|
4950
|
-
return value === "" || !value.startsWith(`..${
|
|
5200
|
+
return value === "" || !value.startsWith(`..${sep4}`) && value !== ".." && !isAbsolute3(value);
|
|
4951
5201
|
}, parseJournal2 = (value) => {
|
|
4952
|
-
if (!
|
|
5202
|
+
if (!isRecord4(value) || value.format !== DEV_JOURNAL_FORMAT2)
|
|
4953
5203
|
return null;
|
|
4954
5204
|
const { configBackupPath } = value;
|
|
4955
5205
|
const { infoBackupPath } = value;
|
|
@@ -5009,7 +5259,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
5009
5259
|
readFile7(infoPath, "utf8")
|
|
5010
5260
|
]);
|
|
5011
5261
|
const parsed = JSON.parse(configSource);
|
|
5012
|
-
if (!
|
|
5262
|
+
if (!isRecord4(parsed))
|
|
5013
5263
|
throw new Error(`Invalid Capacitor native config at ${nativeConfigPath}.`);
|
|
5014
5264
|
await mkdir5(paths.root, { recursive: true });
|
|
5015
5265
|
await Promise.all([
|
|
@@ -5032,7 +5282,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
5032
5282
|
developmentUrl.searchParams.set("__absolute_target", "capacitor-ios");
|
|
5033
5283
|
const existingServer = parsed.server;
|
|
5034
5284
|
parsed.server = {
|
|
5035
|
-
...
|
|
5285
|
+
...isRecord4(existingServer) ? existingServer : {},
|
|
5036
5286
|
cleartext: !https,
|
|
5037
5287
|
url: developmentUrl.href
|
|
5038
5288
|
};
|
|
@@ -5042,10 +5292,10 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
5042
5292
|
writeFile5(infoPath, iosDevelopmentInfoPlist(infoSource, !https))
|
|
5043
5293
|
]);
|
|
5044
5294
|
}, parseNativeCache2 = (value) => {
|
|
5045
|
-
if (!
|
|
5295
|
+
if (!isRecord4(value))
|
|
5046
5296
|
return null;
|
|
5047
5297
|
const { appId, fingerprint, format, installations } = value;
|
|
5048
|
-
if (format !== NATIVE_CACHE_FORMAT2 || typeof appId !== "string" || typeof fingerprint !== "string" || !
|
|
5298
|
+
if (format !== NATIVE_CACHE_FORMAT2 || typeof appId !== "string" || typeof fingerprint !== "string" || !isRecord4(installations) || !Object.values(installations).every((identity) => typeof identity === "string"))
|
|
5049
5299
|
return null;
|
|
5050
5300
|
return {
|
|
5051
5301
|
appId,
|
|
@@ -5624,7 +5874,7 @@ import {
|
|
|
5624
5874
|
posix,
|
|
5625
5875
|
relative as relative7,
|
|
5626
5876
|
resolve as resolvePath,
|
|
5627
|
-
sep as
|
|
5877
|
+
sep as sep5
|
|
5628
5878
|
} from "path";
|
|
5629
5879
|
var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TIMEOUT_MS = 2000, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () => join15(homedir4(), ".absolutejs", "mobile", "remote-macs.json"), emptyStore = () => ({
|
|
5630
5880
|
format: PROFILE_FORMAT,
|
|
@@ -5884,7 +6134,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5884
6134
|
const bytes = await Bun.file(path).arrayBuffer();
|
|
5885
6135
|
const sha256 = createHash6("sha256").update(new Uint8Array(bytes)).digest("hex");
|
|
5886
6136
|
return { bytes: bytes.byteLength, path, sha256 };
|
|
5887
|
-
}, portableRelativePath = (root, path) => relative7(root, path).split(
|
|
6137
|
+
}, portableRelativePath = (root, path) => relative7(root, path).split(sep5).join(posix.sep), portableMobileConfig = (project) => ({
|
|
5888
6138
|
appId: project.config.appId,
|
|
5889
6139
|
appName: project.config.appName,
|
|
5890
6140
|
bundleDirectory: portableRelativePath(project.projectRoot, project.config.bundleDirectory),
|
|
@@ -7300,23 +7550,23 @@ var stripStringsAndComments = (source) => {
|
|
|
7300
7550
|
var toIslandFrameworkSegment = (framework) => framework[0]?.toUpperCase() + framework.slice(1), getIslandManifestKey = (framework, component2) => `Island${toIslandFrameworkSegment(framework)}${component2}`;
|
|
7301
7551
|
|
|
7302
7552
|
// src/core/islands.ts
|
|
7303
|
-
var
|
|
7553
|
+
var isRecord5 = (value) => typeof value === "object" && value !== null, getIslandBuildReference = (component2) => {
|
|
7304
7554
|
if (!isIslandComponentDefinition(component2))
|
|
7305
7555
|
return null;
|
|
7306
7556
|
return {
|
|
7307
7557
|
export: component2.export,
|
|
7308
7558
|
source: component2.source
|
|
7309
7559
|
};
|
|
7310
|
-
}, isIslandComponentDefinition = (value) =>
|
|
7560
|
+
}, isIslandComponentDefinition = (value) => isRecord5(value) && ("component" in value) && ("source" in value) && typeof value.source === "string";
|
|
7311
7561
|
var init_islands = () => {};
|
|
7312
7562
|
|
|
7313
7563
|
// src/build/islandEntries.ts
|
|
7314
7564
|
import { dirname as dirname10, extname as extname2, join as join19, relative as relative10, resolve as resolve14 } from "path";
|
|
7315
7565
|
import ts2 from "typescript";
|
|
7316
|
-
var frameworks,
|
|
7317
|
-
if (
|
|
7566
|
+
var frameworks, isRecord6 = (value) => typeof value === "object" && value !== null, resolveRegistryExport = (mod) => {
|
|
7567
|
+
if (isRecord6(mod.islandRegistry))
|
|
7318
7568
|
return mod.islandRegistry;
|
|
7319
|
-
if (
|
|
7569
|
+
if (isRecord6(mod.default))
|
|
7320
7570
|
return mod.default;
|
|
7321
7571
|
throw new Error("Island registry module must export `islandRegistry` or a default registry object.");
|
|
7322
7572
|
}, hasSvelteImport = (source) => /from\s+['"][^'"]+\.svelte['"]/.test(source), resolveIslandSourcePath = (registryPath, sourcePath) => {
|
|
@@ -7466,7 +7716,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7466
7716
|
const registry2 = resolveRegistryExport(registryModule);
|
|
7467
7717
|
const definitions = frameworks.flatMap((framework) => {
|
|
7468
7718
|
const frameworkRegistry = registry2[framework];
|
|
7469
|
-
if (!
|
|
7719
|
+
if (!isRecord6(frameworkRegistry))
|
|
7470
7720
|
return [];
|
|
7471
7721
|
return Object.entries(frameworkRegistry).map(([component2, value]) => ({
|
|
7472
7722
|
buildReference: getIslandBuildReference(value),
|
|
@@ -7476,7 +7726,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7476
7726
|
});
|
|
7477
7727
|
return {
|
|
7478
7728
|
definitions,
|
|
7479
|
-
hasNamedExport:
|
|
7729
|
+
hasNamedExport: isRecord6(registryModule.islandRegistry),
|
|
7480
7730
|
registry: registry2
|
|
7481
7731
|
};
|
|
7482
7732
|
}, loadIslandRegistryBuildInfo = async (registryPath) => {
|
|
@@ -7776,8 +8026,8 @@ var init_bunStringRawUnicodePlugin = __esm(() => {
|
|
|
7776
8026
|
});
|
|
7777
8027
|
|
|
7778
8028
|
// src/mobile/buildMetadata.ts
|
|
7779
|
-
var ABSOLUTE_MOBILE_ROUTE_DETAIL = "x-absolute-mobile", frameworks2,
|
|
7780
|
-
if (!
|
|
8029
|
+
var ABSOLUTE_MOBILE_ROUTE_DETAIL = "x-absolute-mobile", frameworks2, isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isPageFramework = (value) => typeof value === "string" && frameworks2.has(value), parseAbsoluteMobileBuildPageMetadata = (value) => {
|
|
8030
|
+
if (!isRecord7(value))
|
|
7781
8031
|
return;
|
|
7782
8032
|
if (typeof value.bundleKey !== "string" || typeof value.contract !== "string" || !isPageFramework(value.framework) || typeof value.pageId !== "string" || typeof value.propsSchemaHash !== "string") {
|
|
7783
8033
|
return;
|
|
@@ -8597,14 +8847,14 @@ import {
|
|
|
8597
8847
|
writeFile as writeFile9
|
|
8598
8848
|
} from "fs/promises";
|
|
8599
8849
|
import { dirname as dirname13, join as join22, resolve as resolvePath3 } from "path";
|
|
8600
|
-
var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE = "artifact.json", BUNDLE_ID_PATTERN,
|
|
8850
|
+
var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE = "artifact.json", BUNDLE_ID_PATTERN, isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, bundleIdFor = (currentReleaseId, releases) => {
|
|
8601
8851
|
const identity = JSON.stringify({
|
|
8602
8852
|
currentReleaseId,
|
|
8603
8853
|
releases: releases.map(({ releaseId }) => releaseId)
|
|
8604
8854
|
});
|
|
8605
8855
|
return `amb_${createHash11("sha256").update(identity).digest("hex")}`;
|
|
8606
8856
|
}, parseBundleIndex = (value) => {
|
|
8607
|
-
if (!
|
|
8857
|
+
if (!isRecord8(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
|
|
8608
8858
|
throw new TypeError("Invalid materialized mobile compatibility bundle.");
|
|
8609
8859
|
}
|
|
8610
8860
|
const releases = value.releases.map(parseAbsoluteMobileCompatibilityArtifact);
|
|
@@ -10910,8 +11160,8 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
|
|
|
10910
11160
|
`);
|
|
10911
11161
|
renameSync2(temporary, path);
|
|
10912
11162
|
return proof;
|
|
10913
|
-
},
|
|
10914
|
-
if (!
|
|
11163
|
+
}, isRecord9 = (value) => value !== null && typeof value === "object", isLintProofAttestation = (value) => {
|
|
11164
|
+
if (!isRecord9(value))
|
|
10915
11165
|
return false;
|
|
10916
11166
|
return Reflect.get(value, "algorithm") === "ed25519" && typeof Reflect.get(value, "keyId") === "string" && typeof Reflect.get(value, "signature") === "string";
|
|
10917
11167
|
}, isLintProof = (value) => {
|
|
@@ -12298,7 +12548,7 @@ var init_mem = __esm(() => {
|
|
|
12298
12548
|
});
|
|
12299
12549
|
|
|
12300
12550
|
// src/cli/config/guards.ts
|
|
12301
|
-
var
|
|
12551
|
+
var isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12302
12552
|
|
|
12303
12553
|
// src/cli/config/schema/fromType.ts
|
|
12304
12554
|
import ts6 from "typescript";
|
|
@@ -12361,7 +12611,7 @@ var VIRTUAL_NAME = "__absolute_type_introspect__.ts", MAX_DEPTH = 6, isFramework
|
|
|
12361
12611
|
}, readDiskCache = (cwd, typeName, signature, specifier) => {
|
|
12362
12612
|
try {
|
|
12363
12613
|
const cached = JSON.parse(readFileSync21(cacheFile(cwd, typeName, specifier), "utf-8"));
|
|
12364
|
-
if (
|
|
12614
|
+
if (isRecord10(cached) && cached.signature === signature && Array.isArray(cached.fields)) {
|
|
12365
12615
|
return cached.fields;
|
|
12366
12616
|
}
|
|
12367
12617
|
} catch {}
|
|
@@ -12768,11 +13018,11 @@ var init_frameworks = __esm(() => {
|
|
|
12768
13018
|
|
|
12769
13019
|
// src/cli/generate/context.ts
|
|
12770
13020
|
import { dirname as dirname17, isAbsolute as isAbsolute5, join as join29, relative as relative16, resolve as resolve27 } from "path";
|
|
12771
|
-
var asString = (value) => typeof value === "string" ? value : undefined,
|
|
13021
|
+
var asString = (value) => typeof value === "string" ? value : undefined, isRecord11 = (value) => typeof value === "object" && value !== null, resolveDir = (cwd, value) => isAbsolute5(value) ? value : resolve27(cwd, value), resolveStylesDir = (cwd, config) => {
|
|
12772
13022
|
const styles = config.stylesConfig;
|
|
12773
13023
|
if (typeof styles === "string")
|
|
12774
13024
|
return resolveDir(cwd, styles);
|
|
12775
|
-
if (
|
|
13025
|
+
if (isRecord11(styles)) {
|
|
12776
13026
|
const indexes = asString(styles.indexes);
|
|
12777
13027
|
if (indexes)
|
|
12778
13028
|
return resolveDir(cwd, indexes);
|
|
@@ -12783,7 +13033,7 @@ var asString = (value) => typeof value === "string" ? value : undefined, isRecor
|
|
|
12783
13033
|
return dir ? dirname17(dir) : resolve27(project.cwd, "src/frontend");
|
|
12784
13034
|
}, resolveProject = async (cwd, configOverride) => {
|
|
12785
13035
|
const loaded = await loadConfig(configOverride);
|
|
12786
|
-
const config =
|
|
13036
|
+
const config = isRecord11(loaded) ? loaded : {};
|
|
12787
13037
|
const frameworkDirs = {};
|
|
12788
13038
|
for (const key of FRAMEWORK_KEYS2) {
|
|
12789
13039
|
const dir = asString(config[frameworks6[key].configDirKey]);
|
|
@@ -13763,7 +14013,7 @@ ${value.map((item) => `${pad}${serializeValue(item, level + 1, indent)}`).join(`
|
|
|
13763
14013
|
`)}
|
|
13764
14014
|
${indent.repeat(level)}]`;
|
|
13765
14015
|
}
|
|
13766
|
-
if (
|
|
14016
|
+
if (isRecord10(value)) {
|
|
13767
14017
|
const keys = Object.keys(value);
|
|
13768
14018
|
if (keys.length === 0)
|
|
13769
14019
|
return "{}";
|
|
@@ -13976,18 +14226,18 @@ var init_catalog = __esm(() => {
|
|
|
13976
14226
|
// src/cli/integrations/addPlugin.ts
|
|
13977
14227
|
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "fs";
|
|
13978
14228
|
import { join as join35 } from "path";
|
|
13979
|
-
var
|
|
14229
|
+
var isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
|
|
13980
14230
|
const path = join35(cwd, "package.json");
|
|
13981
14231
|
if (!existsSync27(path))
|
|
13982
14232
|
return null;
|
|
13983
14233
|
try {
|
|
13984
14234
|
const parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
13985
|
-
return
|
|
14235
|
+
return isRecord12(parsed) ? parsed : null;
|
|
13986
14236
|
} catch {
|
|
13987
14237
|
return null;
|
|
13988
14238
|
}
|
|
13989
14239
|
}, addGroupKeys = (group, names) => {
|
|
13990
|
-
if (!
|
|
14240
|
+
if (!isRecord12(group))
|
|
13991
14241
|
return;
|
|
13992
14242
|
for (const name of Object.keys(group))
|
|
13993
14243
|
names.add(name);
|
|
@@ -14580,12 +14830,12 @@ var init_resolveAuthSettings = __esm(() => {
|
|
|
14580
14830
|
import ts13 from "typescript";
|
|
14581
14831
|
import { existsSync as existsSync29, readdirSync as readdirSync6, readFileSync as readFileSync29 } from "fs";
|
|
14582
14832
|
import { join as join36, relative as relative19, resolve as resolve29 } from "path";
|
|
14583
|
-
var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS,
|
|
14833
|
+
var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson2 = (path) => {
|
|
14584
14834
|
if (!existsSync29(path))
|
|
14585
14835
|
return null;
|
|
14586
14836
|
try {
|
|
14587
14837
|
const parsed = JSON.parse(readFileSync29(path, "utf-8"));
|
|
14588
|
-
return
|
|
14838
|
+
return isRecord13(parsed) ? parsed : null;
|
|
14589
14839
|
} catch {
|
|
14590
14840
|
return null;
|
|
14591
14841
|
}
|
|
@@ -14598,7 +14848,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
|
|
|
14598
14848
|
return null;
|
|
14599
14849
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
14600
14850
|
const group = pkg[field];
|
|
14601
|
-
if (!
|
|
14851
|
+
if (!isRecord13(group))
|
|
14602
14852
|
continue;
|
|
14603
14853
|
const version2 = group[AUTH_PACKAGE2];
|
|
14604
14854
|
if (typeof version2 === "string")
|
|
@@ -15887,17 +16137,17 @@ import {
|
|
|
15887
16137
|
writeFileSync as writeFileSync19
|
|
15888
16138
|
} from "fs";
|
|
15889
16139
|
import { createRequire } from "module";
|
|
15890
|
-
import { dirname as dirname25, join as join43, resolve as resolve32, sep as
|
|
16140
|
+
import { dirname as dirname25, join as join43, resolve as resolve32, sep as sep6 } from "path";
|
|
15891
16141
|
var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
15892
16142
|
try {
|
|
15893
16143
|
const parsed = JSON.parse(readFileSync35(path, "utf-8"));
|
|
15894
|
-
return
|
|
16144
|
+
return isRecord10(parsed) ? parsed : null;
|
|
15895
16145
|
} catch {
|
|
15896
16146
|
return null;
|
|
15897
16147
|
}
|
|
15898
16148
|
}, dependencyRecord = (manifest, field) => {
|
|
15899
16149
|
const value = Reflect.get(manifest, field);
|
|
15900
|
-
return
|
|
16150
|
+
return isRecord10(value) ? value : {};
|
|
15901
16151
|
}, dependencyNames2 = (manifest) => [
|
|
15902
16152
|
...new Set(DEPENDENCY_FIELDS.flatMap((field) => Object.keys(dependencyRecord(manifest, field))))
|
|
15903
16153
|
], declaresPackage = (manifest, name) => DEPENDENCY_FIELDS.some((field) => Object.hasOwn(dependencyRecord(manifest, field), name)), manifestName = (manifest, fallback) => {
|
|
@@ -16028,7 +16278,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
16028
16278
|
if (!manifest)
|
|
16029
16279
|
return [];
|
|
16030
16280
|
const existing = Reflect.get(manifest, "overrides");
|
|
16031
|
-
const overrides =
|
|
16281
|
+
const overrides = isRecord10(existing) ? existing : {};
|
|
16032
16282
|
const changes = [];
|
|
16033
16283
|
const rootName = manifestName(manifest, "<workspace>");
|
|
16034
16284
|
for (const duplicate of duplicates) {
|
|
@@ -16047,8 +16297,8 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
16047
16297
|
}, removeDuplicateTypeGraphPackages = (report) => {
|
|
16048
16298
|
const manifest = readManifest(join43(report.installRoot, "package.json")) ?? {};
|
|
16049
16299
|
const rootName = manifestName(manifest, "<workspace>");
|
|
16050
|
-
const installPrefix = `${realpathSync2(report.installRoot)}${
|
|
16051
|
-
const nodeModulesSegment = `${
|
|
16300
|
+
const installPrefix = `${realpathSync2(report.installRoot)}${sep6}`;
|
|
16301
|
+
const nodeModulesSegment = `${sep6}node_modules${sep6}`;
|
|
16052
16302
|
const removed = [];
|
|
16053
16303
|
const stalePaths = duplicateTypeGraphPackages(report).flatMap((duplicate) => {
|
|
16054
16304
|
const selected = preferredIdentity(duplicate, rootName);
|
|
@@ -16975,7 +17225,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
16975
17225
|
if (!encoded)
|
|
16976
17226
|
return;
|
|
16977
17227
|
const map = JSON.parse(Buffer.from(encoded, "base64").toString("utf-8"));
|
|
16978
|
-
if (!
|
|
17228
|
+
if (!isRecord10(map))
|
|
16979
17229
|
return;
|
|
16980
17230
|
if (!Array.isArray(map.sources))
|
|
16981
17231
|
return;
|
|
@@ -17226,7 +17476,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17226
17476
|
}, pickExportEntry = (value) => {
|
|
17227
17477
|
if (typeof value === "string")
|
|
17228
17478
|
return value;
|
|
17229
|
-
if (!
|
|
17479
|
+
if (!isRecord10(value))
|
|
17230
17480
|
return;
|
|
17231
17481
|
for (const key of ["bun", "node", "import", "module", "default"]) {
|
|
17232
17482
|
const entry = pickExportEntry(value[key]);
|
|
@@ -19916,9 +20166,9 @@ import {
|
|
|
19916
20166
|
stat as stat3,
|
|
19917
20167
|
writeFile as writeFile15
|
|
19918
20168
|
} from "fs/promises";
|
|
19919
|
-
import { dirname as dirname31, isAbsolute as isAbsolute7, join as join53, relative as relative27, resolve as resolve40, sep as
|
|
19920
|
-
var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1,
|
|
19921
|
-
if (!
|
|
20169
|
+
import { dirname as dirname31, isAbsolute as isAbsolute7, join as join53, relative as relative27, resolve as resolve40, sep as sep7 } from "path";
|
|
20170
|
+
var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord14 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifest2 = (value) => {
|
|
20171
|
+
if (!isRecord14(value) || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.runtime !== "string") {
|
|
19922
20172
|
throw new TypeError("Invalid embedded AbsoluteJS mobile manifest.");
|
|
19923
20173
|
}
|
|
19924
20174
|
return {
|
|
@@ -19984,7 +20234,7 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
|
|
|
19984
20234
|
const root = resolve40(projectRoot);
|
|
19985
20235
|
const output = resolve40(root, requested ?? ".absolutejs/mobile/releases/android");
|
|
19986
20236
|
const projectRelative = relative27(root, output);
|
|
19987
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
20237
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep7}`) || isAbsolute7(projectRelative)) {
|
|
19988
20238
|
throw new TypeError("mobile build --outdir must remain inside the project.");
|
|
19989
20239
|
}
|
|
19990
20240
|
return output;
|
|
@@ -20021,7 +20271,7 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
|
|
|
20021
20271
|
});
|
|
20022
20272
|
}
|
|
20023
20273
|
}, requireManifestIdentity = (value, expected) => {
|
|
20024
|
-
if (!
|
|
20274
|
+
if (!isRecord14(value)) {
|
|
20025
20275
|
throw new TypeError("Existing Android release metadata is invalid.");
|
|
20026
20276
|
}
|
|
20027
20277
|
const { artifact } = value;
|
|
@@ -20570,7 +20820,7 @@ var init_androidTestReport = __esm(() => {
|
|
|
20570
20820
|
|
|
20571
20821
|
// src/mobile/releasePublisher.ts
|
|
20572
20822
|
import { access as access13 } from "fs/promises";
|
|
20573
|
-
import { isAbsolute as isAbsolute8, relative as relative28, resolve as resolve41, sep as
|
|
20823
|
+
import { isAbsolute as isAbsolute8, relative as relative28, resolve as resolve41, sep as sep8 } from "path";
|
|
20574
20824
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
20575
20825
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
20576
20826
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -20591,11 +20841,11 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
|
20591
20841
|
throw new TypeError("Google Play publisher returned an invalid Android versionCode.");
|
|
20592
20842
|
}
|
|
20593
20843
|
return versionCode;
|
|
20594
|
-
},
|
|
20844
|
+
}, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), isPublisher = (value) => isRecord15(value) && typeof value.publish === "function", publisherModulePath = (projectRoot, requested) => {
|
|
20595
20845
|
const root = resolve41(projectRoot);
|
|
20596
20846
|
const path = resolve41(root, requested);
|
|
20597
20847
|
const projectRelative = relative28(root, path);
|
|
20598
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
20848
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep8}`) || isAbsolute8(projectRelative)) {
|
|
20599
20849
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
20600
20850
|
}
|
|
20601
20851
|
return path;
|
|
@@ -20605,7 +20855,7 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
|
20605
20855
|
throw new TypeError(`Native release registry module does not exist: ${modulePath}`);
|
|
20606
20856
|
});
|
|
20607
20857
|
const loaded = await import(pathToFileURL2(modulePath).href);
|
|
20608
|
-
const publisher =
|
|
20858
|
+
const publisher = isRecord15(loaded) ? loaded.default ?? loaded.registry : undefined;
|
|
20609
20859
|
if (!isPublisher(publisher)) {
|
|
20610
20860
|
throw new TypeError("Native release registry module must default-export a registry with publish(options).");
|
|
20611
20861
|
}
|
|
@@ -20812,7 +21062,7 @@ var init_mobileInspect = __esm(() => {
|
|
|
20812
21062
|
// src/mobile/ciWorkflow.ts
|
|
20813
21063
|
import { existsSync as existsSync43 } from "fs";
|
|
20814
21064
|
import { access as access15, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile17 } from "fs/promises";
|
|
20815
|
-
import { dirname as dirname32, extname as extname9, relative as relative30, resolve as resolve43, sep as
|
|
21065
|
+
import { dirname as dirname32, extname as extname9, relative as relative30, resolve as resolve43, sep as sep9 } from "path";
|
|
20816
21066
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTATION = 6, RESERVED_SECRET_NAMES, exists4 = async (path) => {
|
|
20817
21067
|
try {
|
|
20818
21068
|
await access15(path);
|
|
@@ -20824,7 +21074,7 @@ var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTAT
|
|
|
20824
21074
|
const root = resolve43(projectRoot);
|
|
20825
21075
|
const path = resolve43(root, value);
|
|
20826
21076
|
const portable = relative30(root, path).replaceAll("\\", "/");
|
|
20827
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
21077
|
+
if (portable === ".." || portable.startsWith(`..${sep9}`) || portable.startsWith("../") || portable === "") {
|
|
20828
21078
|
throw new TypeError(`${field} must remain inside the project root.`);
|
|
20829
21079
|
}
|
|
20830
21080
|
if (/\r|\n/u.test(portable) || portable.startsWith("-"))
|
|
@@ -20837,7 +21087,7 @@ var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTAT
|
|
|
20837
21087
|
const workflows = resolve43(root, ".github/workflows");
|
|
20838
21088
|
const path = resolve43(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
20839
21089
|
const portable = relative30(workflows, path);
|
|
20840
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
21090
|
+
if (portable === ".." || portable.startsWith(`..${sep9}`) || extname9(path) !== ".yml" && extname9(path) !== ".yaml") {
|
|
20841
21091
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
20842
21092
|
}
|
|
20843
21093
|
return path;
|
|
@@ -21295,14 +21545,14 @@ __export(exports_mobile, {
|
|
|
21295
21545
|
import { access as access16, mkdir as mkdir16, readFile as readFile24, writeFile as writeFile18 } from "fs/promises";
|
|
21296
21546
|
import { join as join56, relative as relative31, resolve as resolve44 } from "path";
|
|
21297
21547
|
import { createInterface } from "readline/promises";
|
|
21298
|
-
var NOT_FOUND4 = -1,
|
|
21548
|
+
var NOT_FOUND4 = -1, isRecord16 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, packageNameFromSpec = (spec) => spec.slice(0, spec.lastIndexOf("@")), directProjectPackages = async (projectRoot) => {
|
|
21299
21549
|
const manifest = JSON.parse(await readFile24(join56(projectRoot, "package.json"), "utf8"));
|
|
21300
|
-
if (!
|
|
21550
|
+
if (!isRecord16(manifest))
|
|
21301
21551
|
throw new TypeError("Application package.json must contain an object.");
|
|
21302
21552
|
const names = new Set;
|
|
21303
21553
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
21304
21554
|
const dependencies = Reflect.get(manifest, field);
|
|
21305
|
-
if (
|
|
21555
|
+
if (isRecord16(dependencies))
|
|
21306
21556
|
for (const name of Object.keys(dependencies))
|
|
21307
21557
|
names.add(name);
|
|
21308
21558
|
}
|
|
@@ -21310,7 +21560,7 @@ var NOT_FOUND4 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
21310
21560
|
}, resolvedPackageVersion = async (projectRoot, packageName) => {
|
|
21311
21561
|
try {
|
|
21312
21562
|
const manifest = JSON.parse(await readFile24(join56(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
|
|
21313
|
-
return
|
|
21563
|
+
return isRecord16(manifest) && typeof manifest.version === "string" ? manifest.version : undefined;
|
|
21314
21564
|
} catch {
|
|
21315
21565
|
return;
|
|
21316
21566
|
}
|
|
@@ -22403,7 +22653,7 @@ Emulator setup verification:`);
|
|
|
22403
22653
|
return;
|
|
22404
22654
|
});
|
|
22405
22655
|
const status2 = response?.ok ? await response.json().catch(() => null) : null;
|
|
22406
|
-
const targets =
|
|
22656
|
+
const targets = isRecord16(status2) && isRecord16(status2.connectedTargets) ? status2.connectedTargets : undefined;
|
|
22407
22657
|
if (targets && typeof targets["capacitor-ios"] === "number" && targets["capacitor-ios"] > 0)
|
|
22408
22658
|
return;
|
|
22409
22659
|
await Bun.sleep(100);
|