@absolutejs/absolute 0.20.0-beta.45 → 0.20.0-beta.47
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/build.js +141 -123
- package/dist/build.js.map +3 -3
- package/dist/cli/index.js +1069 -803
- package/dist/index.js +208 -150
- package/dist/index.js.map +5 -5
- package/dist/mobile/index.js +419 -112
- package/dist/mobile/index.js.map +8 -8
- package/dist/mobile/remoteMacAgentEntry.js +609 -85
- package/dist/mobile/shellExpoAuth.js +20 -41
- package/dist/mobile/shellExpoDevices.js +20 -41
- package/dist/src/mobile/deviceCapabilities.d.ts +4 -2
- package/dist/src/mobile/expoBridge.d.ts +2 -2
- package/dist/src/mobile/shellExpoDevices.d.ts +2 -2
- package/dist/types/build.d.ts +4 -1
- package/package.json +2 -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
|
|
@@ -1314,6 +1353,279 @@ var init_syncSchema = __esm(() => {
|
|
|
1314
1353
|
init_client();
|
|
1315
1354
|
});
|
|
1316
1355
|
|
|
1356
|
+
// src/mobile/deviceCapabilities.ts
|
|
1357
|
+
import { existsSync as existsSync3, readFileSync as readFileSync7 } from "fs";
|
|
1358
|
+
import { extname, join as join7, relative, resolve as resolve4 } from "path";
|
|
1359
|
+
import { fileURLToPath } from "url";
|
|
1360
|
+
import ts from "typescript";
|
|
1361
|
+
var DEVICES_PACKAGE = "@absolutejs/devices", ADAPTERS, SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u"), providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u, providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo", ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
|
|
1362
|
+
const value = JSON.parse(readFileSync7(path, "utf8"));
|
|
1363
|
+
if (!object2(value))
|
|
1364
|
+
throw new TypeError(`${path} must contain an object.`);
|
|
1365
|
+
return value;
|
|
1366
|
+
}, text = (value, field) => {
|
|
1367
|
+
if (typeof value !== "string" || value.length === 0)
|
|
1368
|
+
throw new TypeError(`${field} must be a non-empty string.`);
|
|
1369
|
+
return value;
|
|
1370
|
+
}, androidPermissions = (value, field) => {
|
|
1371
|
+
if (value === undefined)
|
|
1372
|
+
return;
|
|
1373
|
+
if (!object2(value))
|
|
1374
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1375
|
+
const { permissions } = value;
|
|
1376
|
+
if (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string" && ANDROID_PERMISSION_PATTERN.test(permission)))
|
|
1377
|
+
throw new TypeError(`${field}.permissions must contain Android permission names.`);
|
|
1378
|
+
return [...permissions];
|
|
1379
|
+
}, iosPrivacyAccessedApis = (value, field) => {
|
|
1380
|
+
if (value === undefined)
|
|
1381
|
+
return;
|
|
1382
|
+
if (!object2(value))
|
|
1383
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1384
|
+
const privacy = {};
|
|
1385
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
1386
|
+
const reasons = value[api];
|
|
1387
|
+
if (reasons === undefined)
|
|
1388
|
+
continue;
|
|
1389
|
+
const supported = IOS_PRIVACY_ACCESSED_API_REASONS[api];
|
|
1390
|
+
if (!Array.isArray(reasons) || reasons.length === 0 || !reasons.every((reason) => typeof reason === "string" && supported.has(reason)))
|
|
1391
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
1392
|
+
privacy[api] = [...reasons];
|
|
1393
|
+
}
|
|
1394
|
+
if (Object.keys(value).some((api) => !IOS_PRIVACY_ACCESSED_APIS.some((known) => known === api)))
|
|
1395
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
1396
|
+
return privacy;
|
|
1397
|
+
}, iosNativeRequirements = (value, field) => {
|
|
1398
|
+
if (value === undefined)
|
|
1399
|
+
return;
|
|
1400
|
+
if (!object2(value))
|
|
1401
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1402
|
+
const {
|
|
1403
|
+
privacyAccessedApis,
|
|
1404
|
+
pushNotifications,
|
|
1405
|
+
systemBars,
|
|
1406
|
+
usageDescriptions
|
|
1407
|
+
} = value;
|
|
1408
|
+
if (pushNotifications !== undefined && pushNotifications !== true)
|
|
1409
|
+
throw new TypeError(`${field}.pushNotifications must be true.`);
|
|
1410
|
+
if (systemBars !== undefined && systemBars !== true)
|
|
1411
|
+
throw new TypeError(`${field}.systemBars must be true.`);
|
|
1412
|
+
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
1413
|
+
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
1414
|
+
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
1415
|
+
return {
|
|
1416
|
+
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
1417
|
+
...pushNotifications === true ? { pushNotifications: true } : {},
|
|
1418
|
+
...systemBars === true ? { systemBars: true } : {},
|
|
1419
|
+
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
1420
|
+
};
|
|
1421
|
+
}, parseProvider = (name, value, providerName) => {
|
|
1422
|
+
if (!IDENTIFIER_PATTERN.test(name))
|
|
1423
|
+
throw new TypeError("Device capability names must be identifiers.");
|
|
1424
|
+
if (!object2(value))
|
|
1425
|
+
throw new TypeError(`Device capability ${name} must be an object.`);
|
|
1426
|
+
const factory = text(value.factory, `${name}.factory`);
|
|
1427
|
+
const module = text(value.module, `${name}.module`);
|
|
1428
|
+
if (!IDENTIFIER_PATTERN.test(factory))
|
|
1429
|
+
throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
|
|
1430
|
+
if (!providerModulePattern(providerName).test(module))
|
|
1431
|
+
throw new TypeError(`${name}.module must be an official devices-${providerName} subpath.`);
|
|
1432
|
+
if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && providerPackagePattern(providerName).test(spec)))
|
|
1433
|
+
throw new TypeError(`${name}.packages must contain exact official ${providerLabel(providerName)} package versions.`);
|
|
1434
|
+
const { plugins } = value;
|
|
1435
|
+
if (plugins !== undefined && (!Array.isArray(plugins) || !plugins.every((plugin) => typeof plugin === "string" && /^expo-[a-z][a-z0-9-]*$/u.test(plugin))))
|
|
1436
|
+
throw new TypeError(`${name}.plugins must contain Expo config plugin names.`);
|
|
1437
|
+
let native;
|
|
1438
|
+
const { native: nativeMetadata } = value;
|
|
1439
|
+
if (nativeMetadata !== undefined) {
|
|
1440
|
+
if (!object2(nativeMetadata))
|
|
1441
|
+
throw new TypeError(`${name}.native must be an object.`);
|
|
1442
|
+
const { android, ios } = nativeMetadata;
|
|
1443
|
+
const permissions = androidPermissions(android, `${name}.native.android`);
|
|
1444
|
+
const iosRequirements = iosNativeRequirements(ios, `${name}.native.ios`);
|
|
1445
|
+
native = {
|
|
1446
|
+
...permissions === undefined ? {} : { android: { permissions } },
|
|
1447
|
+
...iosRequirements === undefined ? {} : { ios: iosRequirements }
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
return {
|
|
1451
|
+
factory,
|
|
1452
|
+
module,
|
|
1453
|
+
...native === undefined ? {} : { native },
|
|
1454
|
+
...plugins === undefined ? {} : { plugins: [...plugins] },
|
|
1455
|
+
packages: [...value.packages]
|
|
1456
|
+
};
|
|
1457
|
+
}, absoluteDeviceNativeRequirements = (plan) => {
|
|
1458
|
+
const privacy = plan.capabilities.reduce((requirements, name) => {
|
|
1459
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
1460
|
+
const reasons = plan.providers[name]?.native?.ios?.privacyAccessedApis?.[api] ?? [];
|
|
1461
|
+
if (reasons.length === 0)
|
|
1462
|
+
continue;
|
|
1463
|
+
const current = requirements[api] ?? new Set;
|
|
1464
|
+
for (const reason of reasons)
|
|
1465
|
+
current.add(reason);
|
|
1466
|
+
requirements[api] = current;
|
|
1467
|
+
}
|
|
1468
|
+
return requirements;
|
|
1469
|
+
}, {});
|
|
1470
|
+
return {
|
|
1471
|
+
androidPermissions: [
|
|
1472
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
|
|
1473
|
+
].sort(),
|
|
1474
|
+
iosPrivacyAccessedApis: IOS_PRIVACY_ACCESSED_APIS.flatMap((api) => {
|
|
1475
|
+
const reasons = privacy[api];
|
|
1476
|
+
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
1477
|
+
}),
|
|
1478
|
+
iosPushNotifications: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.pushNotifications === true),
|
|
1479
|
+
iosSystemBars: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.systemBars === true),
|
|
1480
|
+
iosUsageDescriptions: [
|
|
1481
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
1482
|
+
].sort()
|
|
1483
|
+
};
|
|
1484
|
+
}, loadAbsoluteDeviceCapabilityProviders = (projectRoot, provider = "capacitor") => {
|
|
1485
|
+
const adapter = ADAPTERS[provider];
|
|
1486
|
+
let path = join7(resolve4(projectRoot), "node_modules", adapter, "package.json");
|
|
1487
|
+
try {
|
|
1488
|
+
readFileSync7(path, "utf8");
|
|
1489
|
+
} catch {
|
|
1490
|
+
path = fileURLToPath(import.meta.resolve(`${adapter}/package.json`));
|
|
1491
|
+
}
|
|
1492
|
+
const manifest = readJson(path);
|
|
1493
|
+
const { absolutejs } = manifest;
|
|
1494
|
+
const devices = object2(absolutejs) ? absolutejs.devices : undefined;
|
|
1495
|
+
if (!object2(devices) || devices.format !== 1 || devices.provider !== provider || !object2(devices.capabilities))
|
|
1496
|
+
throw new TypeError(`${adapter} does not publish supported capability metadata.`);
|
|
1497
|
+
const entries = Object.entries(devices.capabilities).map(([name, capability]) => ({
|
|
1498
|
+
name,
|
|
1499
|
+
provider: parseProvider(name, capability, provider)
|
|
1500
|
+
}));
|
|
1501
|
+
return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider: capabilityProvider }) => [
|
|
1502
|
+
name,
|
|
1503
|
+
capabilityProvider
|
|
1504
|
+
]));
|
|
1505
|
+
}, isIgnored = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment)), importedCapabilities = (source, file) => {
|
|
1506
|
+
const names = new Set;
|
|
1507
|
+
const namespaces = new Set;
|
|
1508
|
+
const visit = (node) => {
|
|
1509
|
+
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
|
|
1510
|
+
const bindings = node.importClause?.namedBindings;
|
|
1511
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
1512
|
+
for (const element of bindings.elements)
|
|
1513
|
+
if (!element.isTypeOnly)
|
|
1514
|
+
names.add((element.propertyName ?? element.name).text);
|
|
1515
|
+
}
|
|
1516
|
+
if (bindings && ts.isNamespaceImport(bindings))
|
|
1517
|
+
namespaces.add(bindings.name.text);
|
|
1518
|
+
}
|
|
1519
|
+
if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
1520
|
+
for (const element of node.exportClause.elements)
|
|
1521
|
+
if (!element.isTypeOnly)
|
|
1522
|
+
names.add((element.propertyName ?? element.name).text);
|
|
1523
|
+
}
|
|
1524
|
+
if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && namespaces.has(node.expression.text))
|
|
1525
|
+
names.add(node.name.text);
|
|
1526
|
+
ts.forEachChild(node, visit);
|
|
1527
|
+
};
|
|
1528
|
+
const extension = extname(file).toLowerCase();
|
|
1529
|
+
const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
|
|
1530
|
+
for (const [index, script] of sources.entries())
|
|
1531
|
+
visit(ts.createSourceFile(`${file}#script-${index}`, script, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX));
|
|
1532
|
+
return names;
|
|
1533
|
+
}, assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
|
|
1534
|
+
const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
|
|
1535
|
+
const mismatched = plan.requiredPackages.filter((spec) => {
|
|
1536
|
+
const separator = spec.lastIndexOf("@");
|
|
1537
|
+
const packageName = spec.slice(0, separator);
|
|
1538
|
+
if (missing.includes(spec))
|
|
1539
|
+
return false;
|
|
1540
|
+
try {
|
|
1541
|
+
return readJson(join7(resolve4(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
|
|
1542
|
+
} catch {
|
|
1543
|
+
return true;
|
|
1544
|
+
}
|
|
1545
|
+
});
|
|
1546
|
+
const unmet = [...missing, ...mismatched];
|
|
1547
|
+
if (unmet.length > 0)
|
|
1548
|
+
throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
|
|
1549
|
+
}, directAbsoluteProjectPackages = (projectRoot) => {
|
|
1550
|
+
const manifest = readJson(join7(resolve4(projectRoot), "package.json"));
|
|
1551
|
+
const packages = new Set;
|
|
1552
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
1553
|
+
const dependencies = manifest[field];
|
|
1554
|
+
if (object2(dependencies))
|
|
1555
|
+
for (const name of Object.keys(dependencies))
|
|
1556
|
+
packages.add(name);
|
|
1557
|
+
}
|
|
1558
|
+
return packages;
|
|
1559
|
+
}, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
|
|
1560
|
+
const root = resolve4(projectRoot);
|
|
1561
|
+
if (!existsSync3(root))
|
|
1562
|
+
return [];
|
|
1563
|
+
const known = new Set(Object.keys(providers));
|
|
1564
|
+
const capabilities = new Set;
|
|
1565
|
+
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
1566
|
+
const portable = relative(root, resolve4(root, path)).replaceAll("\\", "/");
|
|
1567
|
+
if (isIgnored(portable))
|
|
1568
|
+
continue;
|
|
1569
|
+
const source = readFileSync7(resolve4(root, portable), "utf8");
|
|
1570
|
+
for (const name of importedCapabilities(source, portable))
|
|
1571
|
+
if (known.has(name))
|
|
1572
|
+
capabilities.add(name);
|
|
1573
|
+
}
|
|
1574
|
+
return [...capabilities].sort();
|
|
1575
|
+
}, missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
|
|
1576
|
+
const packageName = spec.slice(0, spec.lastIndexOf("@"));
|
|
1577
|
+
return !directPackages.has(packageName);
|
|
1578
|
+
}), resolveAbsoluteDeviceCapabilityPlan = (projectRoot, provider = "capacitor") => {
|
|
1579
|
+
const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot, provider);
|
|
1580
|
+
const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
|
|
1581
|
+
const providers = {};
|
|
1582
|
+
for (const name of capabilities) {
|
|
1583
|
+
const capabilityProvider = allProviders[name];
|
|
1584
|
+
if (capabilityProvider)
|
|
1585
|
+
providers[name] = capabilityProvider;
|
|
1586
|
+
}
|
|
1587
|
+
return {
|
|
1588
|
+
capabilities,
|
|
1589
|
+
providers,
|
|
1590
|
+
requiredPackages: [
|
|
1591
|
+
...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
|
|
1592
|
+
].sort()
|
|
1593
|
+
};
|
|
1594
|
+
};
|
|
1595
|
+
var init_deviceCapabilities = __esm(() => {
|
|
1596
|
+
ADAPTERS = {
|
|
1597
|
+
capacitor: "@absolutejs/devices-capacitor",
|
|
1598
|
+
expo: "@absolutejs/devices-expo"
|
|
1599
|
+
};
|
|
1600
|
+
SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
|
|
1601
|
+
IGNORED_DIRECTORIES = new Set([
|
|
1602
|
+
".absolutejs",
|
|
1603
|
+
".git",
|
|
1604
|
+
".test-builds",
|
|
1605
|
+
".test-shards",
|
|
1606
|
+
"build",
|
|
1607
|
+
"dist",
|
|
1608
|
+
"node_modules",
|
|
1609
|
+
"test",
|
|
1610
|
+
"tests"
|
|
1611
|
+
]);
|
|
1612
|
+
IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
|
|
1613
|
+
ANDROID_PERMISSION_PATTERN = /^android\.permission\.[A-Z][A-Z0-9_]*$/u;
|
|
1614
|
+
IOS_USAGE_DESCRIPTIONS = new Set([
|
|
1615
|
+
"camera",
|
|
1616
|
+
"location-always",
|
|
1617
|
+
"location-when-in-use",
|
|
1618
|
+
"photo-library",
|
|
1619
|
+
"photo-library-add"
|
|
1620
|
+
]);
|
|
1621
|
+
IOS_PRIVACY_ACCESSED_API_REASONS = {
|
|
1622
|
+
NSPrivacyAccessedAPICategoryFileTimestamp: new Set(["C617.1"])
|
|
1623
|
+
};
|
|
1624
|
+
IOS_PRIVACY_ACCESSED_APIS = [
|
|
1625
|
+
"NSPrivacyAccessedAPICategoryFileTimestamp"
|
|
1626
|
+
];
|
|
1627
|
+
});
|
|
1628
|
+
|
|
1317
1629
|
// src/mobile/expoProject.ts
|
|
1318
1630
|
import {
|
|
1319
1631
|
access,
|
|
@@ -1327,7 +1639,7 @@ import {
|
|
|
1327
1639
|
writeFile
|
|
1328
1640
|
} from "fs/promises";
|
|
1329
1641
|
import { createHash } from "crypto";
|
|
1330
|
-
import { basename as basename2, dirname as dirname4, join as
|
|
1642
|
+
import { basename as basename2, dirname as dirname4, join as join8, relative as relative2, resolve as resolve5, sep } from "path";
|
|
1331
1643
|
var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1332
1644
|
`, EXPO_ASSET_EXTENSION = ".absasset", EXPO_PROJECT_MARKER = ".absolutejs-expo-project", exists = async (path) => {
|
|
1333
1645
|
try {
|
|
@@ -1337,17 +1649,27 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1337
1649
|
return false;
|
|
1338
1650
|
}
|
|
1339
1651
|
}, portableRelative = (from, destination) => {
|
|
1340
|
-
const value =
|
|
1652
|
+
const value = relative2(from, destination).replaceAll("\\", "/");
|
|
1341
1653
|
return value.startsWith(".") ? value : `./${value}`;
|
|
1342
|
-
}, routeSegments = (route) =>
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1654
|
+
}, routeSegments = (route) => {
|
|
1655
|
+
const segments = route.split("/").filter(Boolean);
|
|
1656
|
+
return segments.map((segment, index) => {
|
|
1657
|
+
if (segment.startsWith(":"))
|
|
1658
|
+
return `[${segment.slice(1)}]`;
|
|
1659
|
+
if (segment === "*" && index === segments.length - 1)
|
|
1660
|
+
return "[...absoluteWildcard]";
|
|
1661
|
+
if (segment === "." || segment === ".." || !/^[A-Za-z0-9._~-]+$/u.test(segment)) {
|
|
1662
|
+
throw new TypeError(`Expo native route ${route} contains an unsupported segment ${segment}.`);
|
|
1663
|
+
}
|
|
1664
|
+
return segment;
|
|
1665
|
+
});
|
|
1666
|
+
}, routeFile = (project, route) => join8(project, "app", ...routeSegments(route), "index.tsx"), packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
1667
|
+
const separator = spec.lastIndexOf("@");
|
|
1668
|
+
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
1669
|
+
})), expoPackage = (auth, sync, devices) => ({
|
|
1350
1670
|
dependencies: {
|
|
1671
|
+
"@absolutejs/devices": "0.7.0",
|
|
1672
|
+
"@absolutejs/devices-expo": "0.0.2",
|
|
1351
1673
|
...auth ? {
|
|
1352
1674
|
"@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
|
|
1353
1675
|
[ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
|
|
@@ -1379,7 +1701,8 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1379
1701
|
"react-native": "0.86.3",
|
|
1380
1702
|
"react-native-safe-area-context": "~5.7.0",
|
|
1381
1703
|
"react-native-screens": "4.26.0",
|
|
1382
|
-
"react-native-webview": "13.16.1"
|
|
1704
|
+
"react-native-webview": "13.16.1",
|
|
1705
|
+
...packageDependencies(devices)
|
|
1383
1706
|
},
|
|
1384
1707
|
devDependencies: {
|
|
1385
1708
|
"@types/react": "~19.2.2",
|
|
@@ -1394,36 +1717,107 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1394
1717
|
start: "expo start --dev-client"
|
|
1395
1718
|
},
|
|
1396
1719
|
version: "0.0.0"
|
|
1397
|
-
}), expoAppConfig = (config, auth, sync) =>
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1720
|
+
}), expoAppConfig = (config, auth, sync, devices) => {
|
|
1721
|
+
const requirements = absoluteDeviceNativeRequirements(devices);
|
|
1722
|
+
const usageKey = (purpose) => {
|
|
1723
|
+
if (purpose === "camera")
|
|
1724
|
+
return "NSCameraUsageDescription";
|
|
1725
|
+
if (purpose === "photo-library")
|
|
1726
|
+
return "NSPhotoLibraryUsageDescription";
|
|
1727
|
+
if (purpose === "photo-library-add")
|
|
1728
|
+
return "NSPhotoLibraryAddUsageDescription";
|
|
1729
|
+
if (purpose === "location-always")
|
|
1730
|
+
return "NSLocationAlwaysAndWhenInUseUsageDescription";
|
|
1731
|
+
return "NSLocationWhenInUseUsageDescription";
|
|
1732
|
+
};
|
|
1733
|
+
const usageDescription = (purpose) => {
|
|
1734
|
+
if (purpose === "camera")
|
|
1735
|
+
return `${config.appName} uses your camera when you choose to take a photo.`;
|
|
1736
|
+
if (purpose === "photo-library")
|
|
1737
|
+
return `${config.appName} accesses your photo library only for photo actions you choose.`;
|
|
1738
|
+
if (purpose.startsWith("location-"))
|
|
1739
|
+
return `${config.appName} uses your location only while you use the app and request a location-based action.`;
|
|
1740
|
+
return `${config.appName} adds to your photo library only for photo actions you choose.`;
|
|
1741
|
+
};
|
|
1742
|
+
const descriptions = Object.fromEntries(requirements.iosUsageDescriptions.map((purpose) => [
|
|
1743
|
+
usageKey(purpose),
|
|
1744
|
+
usageDescription(purpose)
|
|
1745
|
+
]));
|
|
1746
|
+
const devicePlugins = [
|
|
1747
|
+
...new Set(devices.capabilities.flatMap((name) => devices.providers[name]?.plugins ?? []))
|
|
1748
|
+
];
|
|
1749
|
+
const configuredPlugins = devicePlugins.map((plugin) => {
|
|
1750
|
+
if (plugin === "expo-image-picker")
|
|
1751
|
+
return [
|
|
1752
|
+
plugin,
|
|
1753
|
+
{
|
|
1754
|
+
cameraPermission: descriptions.NSCameraUsageDescription,
|
|
1755
|
+
microphonePermission: false,
|
|
1756
|
+
photosPermission: descriptions.NSPhotoLibraryUsageDescription
|
|
1757
|
+
}
|
|
1758
|
+
];
|
|
1759
|
+
if (plugin === "expo-location")
|
|
1760
|
+
return [
|
|
1761
|
+
plugin,
|
|
1762
|
+
{
|
|
1763
|
+
locationWhenInUsePermission: descriptions.NSLocationWhenInUseUsageDescription
|
|
1764
|
+
}
|
|
1765
|
+
];
|
|
1766
|
+
return plugin;
|
|
1767
|
+
});
|
|
1768
|
+
return {
|
|
1769
|
+
expo: {
|
|
1770
|
+
android: {
|
|
1771
|
+
...devicePlugins.includes("expo-image-picker") ? {
|
|
1772
|
+
blockedPermissions: [
|
|
1773
|
+
"android.permission.READ_EXTERNAL_STORAGE",
|
|
1774
|
+
"android.permission.RECORD_AUDIO",
|
|
1775
|
+
"android.permission.WRITE_EXTERNAL_STORAGE"
|
|
1776
|
+
]
|
|
1777
|
+
} : {},
|
|
1778
|
+
intentFilters: config.deepLinkHosts.map((host2) => ({
|
|
1779
|
+
action: "VIEW",
|
|
1780
|
+
autoVerify: true,
|
|
1781
|
+
category: ["BROWSABLE", "DEFAULT"],
|
|
1782
|
+
data: [{ host: host2, pathPrefix: "/", scheme: "https" }]
|
|
1783
|
+
})),
|
|
1784
|
+
package: config.appId,
|
|
1785
|
+
permissions: requirements.androidPermissions
|
|
1786
|
+
},
|
|
1787
|
+
experiments: { typedRoutes: true },
|
|
1788
|
+
ios: {
|
|
1789
|
+
associatedDomains: config.deepLinkHosts.map((host2) => `applinks:${host2}`),
|
|
1790
|
+
bundleIdentifier: config.appId,
|
|
1791
|
+
infoPlist: descriptions,
|
|
1792
|
+
...requirements.iosPrivacyAccessedApis.length > 0 ? {
|
|
1793
|
+
privacyManifests: {
|
|
1794
|
+
NSPrivacyAccessedAPITypes: requirements.iosPrivacyAccessedApis.map(({ api, reasons }) => ({
|
|
1795
|
+
NSPrivacyAccessedAPIType: api,
|
|
1796
|
+
NSPrivacyAccessedAPITypeReasons: reasons
|
|
1797
|
+
}))
|
|
1798
|
+
}
|
|
1799
|
+
} : {},
|
|
1800
|
+
...config.iosVersion ? { buildNumber: config.iosVersion } : {}
|
|
1801
|
+
},
|
|
1802
|
+
name: config.appName,
|
|
1803
|
+
plugins: [
|
|
1804
|
+
"expo-router",
|
|
1805
|
+
["expo-dev-client", { launchMode: "most-recent" }],
|
|
1806
|
+
...auth ? ["expo-secure-store"] : [],
|
|
1807
|
+
...sync ? [
|
|
1808
|
+
"expo-sqlite",
|
|
1809
|
+
"expo-background-task",
|
|
1810
|
+
"expo-task-manager"
|
|
1811
|
+
] : [],
|
|
1812
|
+
...configuredPlugins
|
|
1813
|
+
],
|
|
1814
|
+
runtimeVersion: { policy: "appVersion" },
|
|
1815
|
+
scheme: config.deepLinkScheme,
|
|
1816
|
+
slug: config.appId.toLowerCase().replaceAll(".", "-"),
|
|
1817
|
+
version: config.iosVersion ?? "0.1.0"
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
}, expoDynamicAppConfig, expoDevelopmentCaPlugin, metroConfig = (projectRoot) => `${EXPO_GENERATED_HEADER}const { getDefaultConfig } = require('expo/metro-config');
|
|
1427
1821
|
const path = require('node:path');
|
|
1428
1822
|
|
|
1429
1823
|
const projectRoot = __dirname;
|
|
@@ -1438,6 +1832,7 @@ config.watchFolders = [appRoot];
|
|
|
1438
1832
|
|
|
1439
1833
|
module.exports = config;
|
|
1440
1834
|
`, layoutSource = (auth, sync) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
|
|
1835
|
+
import '../src/generated/AbsoluteDevices';
|
|
1441
1836
|
${auth ? `import { useEffect, useState } from 'react';
|
|
1442
1837
|
import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
|
|
1443
1838
|
${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
|
|
@@ -1452,7 +1847,76 @@ export default function AbsoluteLayout() {
|
|
|
1452
1847
|
if (!ready) return null;` : ""}
|
|
1453
1848
|
return <Stack screenOptions={{ headerShown: false }} />;
|
|
1454
1849
|
}
|
|
1455
|
-
`, nativeDiagnosticSource,
|
|
1850
|
+
`, nativeDiagnosticSource, devicesRuntimeSource = (config, plan, auth) => {
|
|
1851
|
+
const imports = plan.capabilities.map((name, index) => {
|
|
1852
|
+
const provider = plan.providers[name];
|
|
1853
|
+
if (!provider)
|
|
1854
|
+
throw new TypeError(`Missing Expo device capability provider ${name}.`);
|
|
1855
|
+
return `import { ${provider.factory} as absoluteExpoCapability${index} } from ${JSON.stringify(provider.module)};`;
|
|
1856
|
+
});
|
|
1857
|
+
const pushIndex = plan.capabilities.indexOf("pushNotifications");
|
|
1858
|
+
const push = pushIndex !== -1;
|
|
1859
|
+
if (push && !auth)
|
|
1860
|
+
throw new TypeError("Expo push notifications require the provisioned AbsoluteJS Auth runtime.");
|
|
1861
|
+
const entries = plan.capabilities.map((name, index) => `${JSON.stringify(name)}: absoluteExpoCapability${index}(${name === "pushNotifications" ? "absoluteExpoPushOptions" : ""})`).join(`,
|
|
1862
|
+
`);
|
|
1863
|
+
const pushSource = push ? `const INSTALLATION_KEY = 'absolutejs.push.installation-id';
|
|
1864
|
+
const requirePushResponse = async (response: Response, operation: string) => {
|
|
1865
|
+
if (!response.ok) throw new Error(\`AbsoluteJS native push \${operation} failed with HTTP \${response.status}.\`);
|
|
1866
|
+
return response.json() as Promise<Record<string, unknown>>;
|
|
1867
|
+
};
|
|
1868
|
+
const absoluteExpoPushOptions = {
|
|
1869
|
+
onRegistration: async (registration: { platform: 'apns' | 'fcm'; token: string }) => {
|
|
1870
|
+
const known = await absoluteExpoDevices.storage.get(INSTALLATION_KEY);
|
|
1871
|
+
const register = (installationId?: string | null) => absoluteExpoAuth.fetch('/auth/push', {
|
|
1872
|
+
body: JSON.stringify({ ...(installationId ? { installationId } : {}), platform: registration.platform, token: registration.token }),
|
|
1873
|
+
headers: { 'content-type': 'application/json' },
|
|
1874
|
+
method: 'POST'
|
|
1875
|
+
});
|
|
1876
|
+
let response = await register(known);
|
|
1877
|
+
const conflict = response.status === 409 && await response.clone().json().then(value => typeof value === 'object' && value !== null && Reflect.get(value, 'code') === 'installation-ownership').catch(() => false);
|
|
1878
|
+
if (known && conflict) {
|
|
1879
|
+
await absoluteExpoDevices.storage.remove(INSTALLATION_KEY);
|
|
1880
|
+
response = await register();
|
|
1881
|
+
}
|
|
1882
|
+
const result = await requirePushResponse(response, 'registration');
|
|
1883
|
+
if (typeof result.installationId !== 'string' || !result.installationId || result.installationId.length > 128) throw new Error('AbsoluteJS native push returned an invalid installation identity.');
|
|
1884
|
+
await absoluteExpoDevices.storage.set(INSTALLATION_KEY, result.installationId);
|
|
1885
|
+
},
|
|
1886
|
+
onUnregistration: async () => {
|
|
1887
|
+
const installationId = await absoluteExpoDevices.storage.get(INSTALLATION_KEY);
|
|
1888
|
+
if (!installationId) return;
|
|
1889
|
+
await requirePushResponse(await absoluteExpoAuth.fetch('/auth/push', {
|
|
1890
|
+
body: JSON.stringify({ installationId }),
|
|
1891
|
+
headers: { 'content-type': 'application/json' },
|
|
1892
|
+
method: 'DELETE'
|
|
1893
|
+
}), 'removal');
|
|
1894
|
+
await absoluteExpoDevices.storage.remove(INSTALLATION_KEY);
|
|
1895
|
+
}
|
|
1896
|
+
};` : "";
|
|
1897
|
+
return `${EXPO_GENERATED_HEADER}import { installDeviceAdapter } from '@absolutejs/devices/runtime';
|
|
1898
|
+
import { createExpoDeviceAdapter } from '@absolutejs/devices-expo';
|
|
1899
|
+
${push ? "import { absoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
1900
|
+
${imports.join(`
|
|
1901
|
+
`)}
|
|
1902
|
+
|
|
1903
|
+
${pushSource}
|
|
1904
|
+
|
|
1905
|
+
export const absoluteExpoDeviceCapabilities = ${JSON.stringify(plan.capabilities)} as const;
|
|
1906
|
+
export const absoluteExpoDevices = createExpoDeviceAdapter({
|
|
1907
|
+
storagePrefix: ${JSON.stringify(`absolutejs.${config.appId}.`)},
|
|
1908
|
+
${entries}
|
|
1909
|
+
});
|
|
1910
|
+
installDeviceAdapter(absoluteExpoDevices);
|
|
1911
|
+
export const beforeAbsoluteExpoDeviceSignOut = async () => {
|
|
1912
|
+
${push ? "await absoluteExpoDevices.pushNotifications?.disable();" : ""}
|
|
1913
|
+
};
|
|
1914
|
+
${push ? `absoluteExpoAuth.onPrincipalChange(principal => {
|
|
1915
|
+
if (!principal) return;
|
|
1916
|
+
void absoluteExpoDevices.pushNotifications?.queryPermission().then(permission => permission.state === 'granted' ? absoluteExpoDevices.pushNotifications?.enable() : undefined).catch(() => undefined);
|
|
1917
|
+
});` : ""}
|
|
1918
|
+
`;
|
|
1919
|
+
}, authRuntimeSource = (auth, appId) => {
|
|
1456
1920
|
const storageIdentity = createHash("sha256").update(appId).digest("hex").slice(0, 24);
|
|
1457
1921
|
return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
|
|
1458
1922
|
import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
|
|
@@ -1585,20 +2049,22 @@ export const createAbsoluteExpoSyncBridge = async (
|
|
|
1585
2049
|
"/__absolute/native",
|
|
1586
2050
|
...Object.keys(config.expoNativeRoutes)
|
|
1587
2051
|
];
|
|
1588
|
-
|
|
1589
|
-
import * as Linking from 'expo-linking';
|
|
2052
|
+
const nativeRoutePatterns = nativeRoutes.map((route) => route.split("/").filter(Boolean));
|
|
2053
|
+
return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
|
|
1590
2054
|
import { router, usePathname } from 'expo-router';
|
|
1591
2055
|
import { useEffect, useRef, useState } from 'react';
|
|
1592
2056
|
import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
|
|
1593
2057
|
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
1594
2058
|
import { materializeAbsoluteWebBundle } from './webAssets';
|
|
2059
|
+
import { createExpoDevicesBridgeHost } from '@absolutejs/devices-expo/bridge';
|
|
2060
|
+
import { absoluteExpoDevices, beforeAbsoluteExpoDeviceSignOut } from './AbsoluteDevices';
|
|
1595
2061
|
${auth ? "import { absoluteExpoAuth, getAbsoluteExpoAuthPrincipal, startAbsoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
1596
2062
|
${sync ? "import { createAbsoluteExpoSyncBridge, startAbsoluteExpoSync } from './AbsoluteSync';" : ""}
|
|
1597
2063
|
|
|
1598
2064
|
const BRIDGE_FORMAT = 3;
|
|
1599
2065
|
const MAX_MESSAGE_BYTES = 64 * 1024;
|
|
1600
2066
|
const MAX_HTTP_BODY_BYTES = 48 * 1024;
|
|
1601
|
-
const
|
|
2067
|
+
const NATIVE_ROUTE_PATTERNS = ${JSON.stringify(nativeRoutePatterns)};
|
|
1602
2068
|
const PRODUCTION_ORIGIN = ${JSON.stringify(config.productionOrigin)};
|
|
1603
2069
|
const DEV_ORIGIN = Platform.OS === 'android'
|
|
1604
2070
|
? process.env.EXPO_PUBLIC_ABSOLUTE_DEV_ANDROID_ORIGIN
|
|
@@ -1607,6 +2073,19 @@ const HMR_TARGET = Platform.OS === 'android' ? 'expo-android' : 'expo-ios';
|
|
|
1607
2073
|
const AUTH_ENABLED = ${auth ? "true" : "false"};
|
|
1608
2074
|
const SYNC_ENABLED = ${sync ? "true" : "false"};
|
|
1609
2075
|
|
|
2076
|
+
const isNativeRoute = (pathname: string) => {
|
|
2077
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
2078
|
+
return NATIVE_ROUTE_PATTERNS.some(pattern => {
|
|
2079
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
2080
|
+
const expected = pattern[index]!;
|
|
2081
|
+
if (expected === '*') return segments.length > index;
|
|
2082
|
+
if (segments[index] === undefined) return false;
|
|
2083
|
+
if (!expected.startsWith(':') && expected !== segments[index]) return false;
|
|
2084
|
+
}
|
|
2085
|
+
return segments.length === pattern.length;
|
|
2086
|
+
});
|
|
2087
|
+
};
|
|
2088
|
+
|
|
1610
2089
|
const bridgeBootstrap = (path: string) => {
|
|
1611
2090
|
const initialPath = DEV_ORIGIN
|
|
1612
2091
|
? 'location.pathname + location.search + location.hash'
|
|
@@ -1647,10 +2126,11 @@ const bridgeBootstrap = (path: string) => {
|
|
|
1647
2126
|
const id = 'web_' + Date.now().toString(36) + '_' + (++sequence).toString(36);
|
|
1648
2127
|
send({ format: 3, id, kind: 'request', method, params, path: currentPath });
|
|
1649
2128
|
return new Promise((resolve, reject) => {
|
|
2129
|
+
const interactive = method.startsWith('devices.camera.') || method.startsWith('devices.photos.') || method.startsWith('devices.documents.') || method.endsWith('.requestPermission');
|
|
1650
2130
|
const timer = setTimeout(() => {
|
|
1651
2131
|
pending.delete(id);
|
|
1652
2132
|
reject(new Error('Expo bridge request timed out.'));
|
|
1653
|
-
},
|
|
2133
|
+
}, interactive ? 5 * 60 * 1000 : 30 * 1000);
|
|
1654
2134
|
pending.set(id, { reject, resolve, timer });
|
|
1655
2135
|
});
|
|
1656
2136
|
},
|
|
@@ -1681,7 +2161,7 @@ const bridgeBootstrap = (path: string) => {
|
|
|
1681
2161
|
const anchor = event.target instanceof Element ? event.target.closest('a[href]') : null;
|
|
1682
2162
|
if (!anchor) return;
|
|
1683
2163
|
const url = new URL(anchor.href, location.href);
|
|
1684
|
-
if (
|
|
2164
|
+
if (!isNativeRoute(url.pathname)) return;
|
|
1685
2165
|
event.preventDefault();
|
|
1686
2166
|
send({ format: 3, kind: 'event', event: 'navigation', path: url.pathname + url.search + url.hash });
|
|
1687
2167
|
}, true);
|
|
@@ -1689,17 +2169,6 @@ const bridgeBootstrap = (path: string) => {
|
|
|
1689
2169
|
})(); true;\`;
|
|
1690
2170
|
};
|
|
1691
2171
|
|
|
1692
|
-
const impact = async (params: Record<string, unknown>) => {
|
|
1693
|
-
const style = params.style;
|
|
1694
|
-
if (style === 'selection') return Haptics.selectionAsync();
|
|
1695
|
-
if (style === 'success' || style === 'warning' || style === 'error') {
|
|
1696
|
-
const value = style === 'success' ? Haptics.NotificationFeedbackType.Success : style === 'warning' ? Haptics.NotificationFeedbackType.Warning : Haptics.NotificationFeedbackType.Error;
|
|
1697
|
-
return Haptics.notificationAsync(value);
|
|
1698
|
-
}
|
|
1699
|
-
const value = style === 'light' ? Haptics.ImpactFeedbackStyle.Light : style === 'heavy' ? Haptics.ImpactFeedbackStyle.Heavy : Haptics.ImpactFeedbackStyle.Medium;
|
|
1700
|
-
return Haptics.impactAsync(value);
|
|
1701
|
-
};
|
|
1702
|
-
|
|
1703
2172
|
const bridgeFetch = async (params: Record<string, unknown>) => {
|
|
1704
2173
|
if (typeof params.method !== 'string' || !['DELETE', 'GET', 'PATCH', 'POST', 'PUT'].includes(params.method) || typeof params.url !== 'string' || typeof params.headers !== 'object' || params.headers === null || Array.isArray(params.headers) || params.body !== undefined && typeof params.body !== 'string') throw new Error('Expo bridge HTTP request is invalid.');
|
|
1705
2174
|
const url = new URL(params.url);
|
|
@@ -1731,10 +2200,12 @@ const authStatus = async () => {
|
|
|
1731
2200
|
export function AbsoluteWebHost() {
|
|
1732
2201
|
const pathname = usePathname() || '/';
|
|
1733
2202
|
const webView = useRef<WebView>(null);
|
|
2203
|
+
const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
1734
2204
|
const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
1735
2205
|
const [indexUri, setIndexUri] = useState<string>();
|
|
1736
2206
|
const [canGoBack, setCanGoBack] = useState(false);
|
|
1737
2207
|
const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
|
|
2208
|
+
const [devicesReady, setDevicesReady] = useState(false);
|
|
1738
2209
|
const activeWebPath = useRef(pathname);
|
|
1739
2210
|
|
|
1740
2211
|
useEffect(() => {
|
|
@@ -1784,6 +2255,23 @@ export function AbsoluteWebHost() {
|
|
|
1784
2255
|
if (new TextEncoder().encode(source).byteLength > MAX_MESSAGE_BYTES) throw new Error('Expo bridge response exceeds 64 KiB.');
|
|
1785
2256
|
webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
|
|
1786
2257
|
};
|
|
2258
|
+
useEffect(() => {
|
|
2259
|
+
let active = true;
|
|
2260
|
+
void createExpoDevicesBridgeHost(absoluteExpoDevices, (event, payload) => {
|
|
2261
|
+
if (!active) return;
|
|
2262
|
+
respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
|
|
2263
|
+
}).then(host => {
|
|
2264
|
+
if (!active) return void host.close();
|
|
2265
|
+
devicesBridge.current = host;
|
|
2266
|
+
setDevicesReady(true);
|
|
2267
|
+
});
|
|
2268
|
+
return () => {
|
|
2269
|
+
active = false;
|
|
2270
|
+
const host = devicesBridge.current;
|
|
2271
|
+
devicesBridge.current = undefined;
|
|
2272
|
+
void host?.close();
|
|
2273
|
+
};
|
|
2274
|
+
}, []);
|
|
1787
2275
|
const hasOrigin = (source: string, origin: string) => {
|
|
1788
2276
|
try { return new URL(source).origin === origin; } catch { return false; }
|
|
1789
2277
|
};
|
|
@@ -1796,18 +2284,16 @@ export function AbsoluteWebHost() {
|
|
|
1796
2284
|
if (message.kind === 'event' && (message.event === 'navigation' || message.event === 'ready')) {
|
|
1797
2285
|
const target = new URL(message.path, PRODUCTION_ORIGIN);
|
|
1798
2286
|
if (target.origin !== PRODUCTION_ORIGIN) return;
|
|
1799
|
-
if (
|
|
2287
|
+
if (isNativeRoute(target.pathname)) router.push(message.path as never);
|
|
1800
2288
|
else activeWebPath.current = message.path;
|
|
1801
2289
|
return;
|
|
1802
2290
|
}
|
|
1803
2291
|
if (message.kind !== 'request' || typeof message.id !== 'string' || message.path !== activeWebPath.current) return;
|
|
1804
2292
|
try {
|
|
1805
2293
|
if (typeof message.params !== 'object' || message.params === null || Array.isArray(message.params)) throw new Error('Expo bridge method params are invalid.');
|
|
1806
|
-
if (message.method === '
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
await impact(message.params as Record<string, unknown>);
|
|
1810
|
-
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });
|
|
2294
|
+
if (typeof message.method === 'string' && message.method.startsWith('devices.')) {
|
|
2295
|
+
if (!devicesBridge.current) throw new Error('Expo devices bridge is unavailable.');
|
|
2296
|
+
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await devicesBridge.current.request(message.method, message.params as Record<string, unknown>) });
|
|
1811
2297
|
} else if (message.method === 'http.fetch') {
|
|
1812
2298
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await bridgeFetch(message.params as Record<string, unknown>) });
|
|
1813
2299
|
} else if (message.method === 'auth.signIn') {
|
|
@@ -1816,7 +2302,8 @@ export function AbsoluteWebHost() {
|
|
|
1816
2302
|
await absoluteExpoAuth.signIn({ authorizationParameters: { login_hint: params.email, ...(params.signup ? { screen_hint: 'signup' } : {}) } });
|
|
1817
2303
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });` : "throw new Error('Expo Auth is not configured.');"}
|
|
1818
2304
|
} else if (message.method === 'auth.signOut') {
|
|
1819
|
-
${auth ? `await
|
|
2305
|
+
${auth ? `await beforeAbsoluteExpoDeviceSignOut();
|
|
2306
|
+
await absoluteExpoAuth.signOut();
|
|
1820
2307
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });` : "throw new Error('Expo Auth is not configured.');"}
|
|
1821
2308
|
} else if (message.method === 'auth.status') {
|
|
1822
2309
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });
|
|
@@ -1831,7 +2318,7 @@ export function AbsoluteWebHost() {
|
|
|
1831
2318
|
}
|
|
1832
2319
|
};
|
|
1833
2320
|
|
|
1834
|
-
if (!indexUri || !runtimeReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
2321
|
+
if (!indexUri || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
1835
2322
|
return <WebView
|
|
1836
2323
|
allowFileAccess
|
|
1837
2324
|
allowFileAccessFromFileURLs
|
|
@@ -1903,13 +2390,25 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1903
2390
|
await writeFile(temporary, source, { flag: "wx" });
|
|
1904
2391
|
await rename(temporary, path);
|
|
1905
2392
|
return true;
|
|
2393
|
+
}, pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
2394
|
+
const appDirectory = join8(project, "app");
|
|
2395
|
+
if (!await exists(appDirectory))
|
|
2396
|
+
return 0;
|
|
2397
|
+
const files = await walkFiles(appDirectory);
|
|
2398
|
+
const stale = (await Promise.all(files.map(async (path) => ({
|
|
2399
|
+
managed: path.endsWith(".tsx") && (await readFile(path, "utf8")).startsWith(EXPO_GENERATED_HEADER),
|
|
2400
|
+
path
|
|
2401
|
+
})))).filter(({ managed, path }) => managed && !expected.has(path));
|
|
2402
|
+
await Promise.all(stale.map(({ path }) => rm(path, { force: true })));
|
|
2403
|
+
return stale.length;
|
|
1906
2404
|
}, jsonSource = (value) => `${JSON.stringify(value, null, "\t")}
|
|
1907
2405
|
`, emptyWebAssetsSource, writeAbsoluteExpoProject = async (config, options) => {
|
|
1908
2406
|
if (config.engine !== "expo")
|
|
1909
2407
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
1910
|
-
const projectRoot =
|
|
2408
|
+
const projectRoot = resolve5(options.projectRoot);
|
|
1911
2409
|
const project = config.nativeProjectDirectory;
|
|
1912
2410
|
const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
|
|
2411
|
+
const devices = resolveAbsoluteDeviceCapabilityPlan(projectRoot, "expo");
|
|
1913
2412
|
const syncEnabled = Boolean(auth && projectUsesAbsoluteSync(projectRoot));
|
|
1914
2413
|
const syncSchema = syncEnabled ? { components: discoverAbsoluteSyncSchema(projectRoot).components } : undefined;
|
|
1915
2414
|
const routeModules = Object.entries(config.expoNativeRoutes);
|
|
@@ -1922,7 +2421,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1922
2421
|
if (missing) {
|
|
1923
2422
|
throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
|
|
1924
2423
|
}
|
|
1925
|
-
const marker =
|
|
2424
|
+
const marker = join8(project, EXPO_PROJECT_MARKER);
|
|
1926
2425
|
if (await exists(project) && !await exists(marker)) {
|
|
1927
2426
|
const entries = await readdir(project);
|
|
1928
2427
|
if (entries.length > 0 && !options.force) {
|
|
@@ -1935,7 +2434,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1935
2434
|
const authEnabled = Boolean(auth);
|
|
1936
2435
|
const files = new Map([
|
|
1937
2436
|
[
|
|
1938
|
-
|
|
2437
|
+
join8(project, ".gitignore"),
|
|
1939
2438
|
`.expo/
|
|
1940
2439
|
android/
|
|
1941
2440
|
ios/
|
|
@@ -1943,61 +2442,66 @@ node_modules/
|
|
|
1943
2442
|
`
|
|
1944
2443
|
],
|
|
1945
2444
|
[
|
|
1946
|
-
|
|
1947
|
-
jsonSource(expoAppConfig(config, authEnabled, syncEnabled))
|
|
2445
|
+
join8(project, "app.json"),
|
|
2446
|
+
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices))
|
|
1948
2447
|
],
|
|
1949
|
-
[
|
|
2448
|
+
[join8(project, "app.config.js"), expoDynamicAppConfig],
|
|
1950
2449
|
[
|
|
1951
|
-
|
|
1952
|
-
jsonSource(expoPackage(authEnabled, syncEnabled))
|
|
2450
|
+
join8(project, "package.json"),
|
|
2451
|
+
jsonSource(expoPackage(authEnabled, syncEnabled, devices))
|
|
1953
2452
|
],
|
|
1954
|
-
[
|
|
2453
|
+
[join8(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
1955
2454
|
[
|
|
1956
|
-
|
|
2455
|
+
join8(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
1957
2456
|
expoDevelopmentCaPlugin
|
|
1958
2457
|
],
|
|
1959
2458
|
[
|
|
1960
|
-
|
|
2459
|
+
join8(project, "tsconfig.json"),
|
|
1961
2460
|
jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
|
|
1962
2461
|
],
|
|
1963
2462
|
[
|
|
1964
|
-
|
|
2463
|
+
join8(project, "app", "_layout.tsx"),
|
|
1965
2464
|
layoutSource(authEnabled, syncEnabled)
|
|
1966
2465
|
],
|
|
1967
2466
|
[
|
|
1968
|
-
|
|
2467
|
+
join8(project, "app", "__absolute", "native", "index.tsx"),
|
|
1969
2468
|
nativeDiagnosticSource
|
|
1970
2469
|
],
|
|
1971
2470
|
[
|
|
1972
|
-
|
|
2471
|
+
join8(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
2472
|
+
devicesRuntimeSource(config, devices, authEnabled)
|
|
2473
|
+
],
|
|
2474
|
+
[
|
|
2475
|
+
join8(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
1973
2476
|
webHostSource(config, auth, syncEnabled)
|
|
1974
2477
|
]
|
|
1975
2478
|
]);
|
|
1976
2479
|
if (auth) {
|
|
1977
|
-
files.set(
|
|
2480
|
+
files.set(join8(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
1978
2481
|
}
|
|
1979
2482
|
if (syncSchema) {
|
|
1980
|
-
files.set(
|
|
2483
|
+
files.set(join8(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
1981
2484
|
}
|
|
1982
|
-
const webAssetsPath =
|
|
2485
|
+
const webAssetsPath = join8(project, "src", "generated", "webAssets.ts");
|
|
1983
2486
|
if (!await exists(webAssetsPath)) {
|
|
1984
2487
|
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
1985
2488
|
}
|
|
1986
2489
|
if (!config.expoNativeRoutes["/"]) {
|
|
1987
|
-
files.set(
|
|
2490
|
+
files.set(join8(project, "app", "index.tsx"), webRouteSource);
|
|
1988
2491
|
}
|
|
1989
|
-
files.set(
|
|
2492
|
+
files.set(join8(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
1990
2493
|
for (const [route, module] of routeModules) {
|
|
1991
|
-
const wrapper = route === "/" ?
|
|
2494
|
+
const wrapper = route === "/" ? join8(project, "app", "index.tsx") : routeFile(project, route);
|
|
1992
2495
|
files.set(wrapper, nativeWrapperSource(wrapper, module));
|
|
1993
2496
|
}
|
|
2497
|
+
const removed = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join8(project, "app")}${sep}`))));
|
|
1994
2498
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
1995
|
-
const changed = changes.filter(Boolean).length;
|
|
2499
|
+
const changed = removed + changes.filter(Boolean).length;
|
|
1996
2500
|
return { changed, path: project, written: [...files.keys()] };
|
|
1997
2501
|
}, walkFiles = async (root, directory = root) => {
|
|
1998
2502
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
1999
2503
|
const nested = await Promise.all(entries.map((entry) => {
|
|
2000
|
-
const path =
|
|
2504
|
+
const path = join8(directory, entry.name);
|
|
2001
2505
|
if (entry.isDirectory())
|
|
2002
2506
|
return walkFiles(root, path);
|
|
2003
2507
|
if (entry.isFile())
|
|
@@ -2058,11 +2562,11 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2058
2562
|
`, syncAbsoluteExpoWebAssets = async (config) => {
|
|
2059
2563
|
if (config.engine !== "expo")
|
|
2060
2564
|
throw new TypeError("Expo asset sync requires mobile.engine: expo.");
|
|
2061
|
-
const marker =
|
|
2565
|
+
const marker = join8(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
|
|
2062
2566
|
if (!await exists(marker)) {
|
|
2063
2567
|
throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
|
|
2064
2568
|
}
|
|
2065
|
-
const manifestPath =
|
|
2569
|
+
const manifestPath = join8(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
2066
2570
|
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
2067
2571
|
const appBuild = typeof manifest === "object" && manifest !== null && typeof Reflect.get(manifest, "appBuild") === "string" ? String(Reflect.get(manifest, "appBuild")) : undefined;
|
|
2068
2572
|
if (!appBuild)
|
|
@@ -2071,23 +2575,23 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2071
2575
|
const bundleHash = createHash("sha256");
|
|
2072
2576
|
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile(file), file })));
|
|
2073
2577
|
filesWithContents.forEach(({ contents, file }) => {
|
|
2074
|
-
bundleHash.update(
|
|
2578
|
+
bundleHash.update(relative2(config.bundleDirectory, file).replaceAll("\\", "/"));
|
|
2075
2579
|
bundleHash.update("\x00");
|
|
2076
2580
|
bundleHash.update(contents);
|
|
2077
2581
|
bundleHash.update("\x00");
|
|
2078
2582
|
});
|
|
2079
2583
|
const bundleId = `amexpo_${bundleHash.digest("hex")}`;
|
|
2080
|
-
const destination =
|
|
2584
|
+
const destination = join8(config.nativeProjectDirectory, "assets", "absolute");
|
|
2081
2585
|
await mkdir(dirname4(destination), { recursive: true });
|
|
2082
|
-
const staging = await mkdtemp(
|
|
2586
|
+
const staging = await mkdtemp(join8(dirname4(destination), `.${basename2(destination)}.stage-`));
|
|
2083
2587
|
let assets;
|
|
2084
2588
|
try {
|
|
2085
2589
|
assets = await Promise.all(files.map(async (source, index) => {
|
|
2086
2590
|
const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
|
|
2087
|
-
await cp(source,
|
|
2591
|
+
await cp(source, join8(staging, name));
|
|
2088
2592
|
return {
|
|
2089
|
-
asset: portableRelative(
|
|
2090
|
-
path:
|
|
2593
|
+
asset: portableRelative(join8(config.nativeProjectDirectory, "src", "generated"), join8(destination, name)),
|
|
2594
|
+
path: relative2(config.bundleDirectory, source).replaceAll("\\", "/")
|
|
2091
2595
|
};
|
|
2092
2596
|
}));
|
|
2093
2597
|
await installStagedDirectory(staging, destination);
|
|
@@ -2095,13 +2599,14 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2095
2599
|
await rm(staging, { force: true, recursive: true });
|
|
2096
2600
|
throw error;
|
|
2097
2601
|
}
|
|
2098
|
-
const generated =
|
|
2602
|
+
const generated = join8(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
2099
2603
|
await writeManagedFile(generated, assetModuleSource(assets, bundleId), true);
|
|
2100
2604
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
2101
2605
|
};
|
|
2102
2606
|
var init_expoProject = __esm(() => {
|
|
2103
2607
|
init_nativeAuth();
|
|
2104
2608
|
init_syncSchema();
|
|
2609
|
+
init_deviceCapabilities();
|
|
2105
2610
|
expoDynamicAppConfig = `${EXPO_GENERATED_HEADER}const config = require('./app.json');
|
|
2106
2611
|
|
|
2107
2612
|
if (process.env.ABSOLUTE_EXPO_DEVELOPMENT === '1' && process.env.ABSOLUTE_EXPO_DEVELOPMENT_CA_PATH) {
|
|
@@ -2207,14 +2712,14 @@ import {
|
|
|
2207
2712
|
isIP
|
|
2208
2713
|
} from "net";
|
|
2209
2714
|
import { readFile as readFile2 } from "fs/promises";
|
|
2210
|
-
var closeServer = (server) => new Promise((
|
|
2715
|
+
var closeServer = (server) => new Promise((resolve6, reject) => {
|
|
2211
2716
|
server.close((error) => {
|
|
2212
2717
|
if (error)
|
|
2213
2718
|
reject(error);
|
|
2214
2719
|
else
|
|
2215
|
-
|
|
2720
|
+
resolve6();
|
|
2216
2721
|
});
|
|
2217
|
-
}), listen = (server, port) => new Promise((
|
|
2722
|
+
}), listen = (server, port) => new Promise((resolve6, reject) => {
|
|
2218
2723
|
server.once("error", reject);
|
|
2219
2724
|
server.listen(port, "0.0.0.0", () => {
|
|
2220
2725
|
server.off("error", reject);
|
|
@@ -2223,11 +2728,11 @@ var closeServer = (server) => new Promise((resolve5, reject) => {
|
|
|
2223
2728
|
reject(new Error("Could not determine the iOS device helper port."));
|
|
2224
2729
|
return;
|
|
2225
2730
|
}
|
|
2226
|
-
|
|
2731
|
+
resolve6(address.port);
|
|
2227
2732
|
});
|
|
2228
2733
|
}), findEphemeralPort = async () => {
|
|
2229
2734
|
const probe = createTcpServer();
|
|
2230
|
-
const port = await new Promise((
|
|
2735
|
+
const port = await new Promise((resolve6, reject) => {
|
|
2231
2736
|
probe.once("error", reject);
|
|
2232
2737
|
probe.listen(0, "127.0.0.1", () => {
|
|
2233
2738
|
const address = probe.address();
|
|
@@ -2235,7 +2740,7 @@ var closeServer = (server) => new Promise((resolve5, reject) => {
|
|
|
2235
2740
|
reject(new Error("Could not allocate the iOS CA enrollment port."));
|
|
2236
2741
|
return;
|
|
2237
2742
|
}
|
|
2238
|
-
|
|
2743
|
+
resolve6(address.port);
|
|
2239
2744
|
});
|
|
2240
2745
|
});
|
|
2241
2746
|
await closeServer(probe);
|
|
@@ -2292,12 +2797,12 @@ var init_iosPhysicalDeviceTransport = () => {};
|
|
|
2292
2797
|
// src/cli/utils.ts
|
|
2293
2798
|
var {$: $2 } = globalThis.Bun;
|
|
2294
2799
|
import { execSync } from "child_process";
|
|
2295
|
-
import { existsSync as
|
|
2800
|
+
import { existsSync as existsSync4, readFileSync as readFileSync8 } from "fs";
|
|
2296
2801
|
import { createServer as createServer3 } from "net";
|
|
2297
|
-
import { resolve as
|
|
2802
|
+
import { resolve as resolve6 } from "path";
|
|
2298
2803
|
var COMPOSE_PATH = "db/docker-compose.db.yml", DEFAULT_SERVER_ENTRY = "src/backend/server.ts", isWSLEnvironment = () => {
|
|
2299
2804
|
try {
|
|
2300
|
-
const release =
|
|
2805
|
+
const release = readFileSync8("/proc/version", "utf-8");
|
|
2301
2806
|
return /microsoft|wsl/i.test(release);
|
|
2302
2807
|
} catch {
|
|
2303
2808
|
return false;
|
|
@@ -2396,8 +2901,8 @@ var COMPOSE_PATH = "db/docker-compose.db.yml", DEFAULT_SERVER_ENTRY = "src/backe
|
|
|
2396
2901
|
}, printHint = () => {
|
|
2397
2902
|
console.log("\x1B[90mpress h + enter to show shortcuts\x1B[0m");
|
|
2398
2903
|
}, readDbScripts = async () => {
|
|
2399
|
-
const pkgPath =
|
|
2400
|
-
if (!
|
|
2904
|
+
const pkgPath = resolve6("package.json");
|
|
2905
|
+
if (!existsSync4(pkgPath))
|
|
2401
2906
|
return null;
|
|
2402
2907
|
const pkg = await Bun.file(pkgPath).json();
|
|
2403
2908
|
const upCommand = pkg.scripts?.["db:up"];
|
|
@@ -2431,7 +2936,7 @@ var init_utils = __esm(() => {
|
|
|
2431
2936
|
// src/mobile/emulatorDoctor.ts
|
|
2432
2937
|
import { access as access3 } from "fs/promises";
|
|
2433
2938
|
import { homedir as homedir3 } from "os";
|
|
2434
|
-
import { join as
|
|
2939
|
+
import { join as join10 } from "path";
|
|
2435
2940
|
var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command) => {
|
|
2436
2941
|
try {
|
|
2437
2942
|
const result = Bun.spawnSync(command, {
|
|
@@ -2476,15 +2981,15 @@ var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command)
|
|
|
2476
2981
|
}
|
|
2477
2982
|
}, absoluteManagedAndroidSdkRoot = (host2, env = process.env) => {
|
|
2478
2983
|
if (host2 === "windows") {
|
|
2479
|
-
return
|
|
2984
|
+
return join10(env.LOCALAPPDATA ?? join10(homedir3(), "AppData", "Local"), "AbsoluteJS", "Android", "Sdk");
|
|
2480
2985
|
}
|
|
2481
2986
|
if (host2 === "wsl") {
|
|
2482
2987
|
const localAppData = windowsLocalAppDataFromWsl();
|
|
2483
2988
|
if (localAppData) {
|
|
2484
|
-
return
|
|
2989
|
+
return join10(localAppData, "AbsoluteJS", "Android", "Sdk");
|
|
2485
2990
|
}
|
|
2486
2991
|
}
|
|
2487
|
-
return
|
|
2992
|
+
return join10(homedir3(), ".absolutejs", "android-sdk");
|
|
2488
2993
|
}, pathExists = async (path) => {
|
|
2489
2994
|
try {
|
|
2490
2995
|
await access3(path);
|
|
@@ -2537,7 +3042,7 @@ var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command)
|
|
|
2537
3042
|
const capture = input.capture ?? captureCommand;
|
|
2538
3043
|
const androidRoot = input.androidRoot === null ? undefined : input.androidRoot ?? env.ANDROID_HOME ?? env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host2, env);
|
|
2539
3044
|
const windowsAndroidTools = host2 === "windows" || host2 === "wsl";
|
|
2540
|
-
const android = (segments) => androidRoot ?
|
|
3045
|
+
const android = (segments) => androidRoot ? join10(androidRoot, ...segments) : undefined;
|
|
2541
3046
|
const paths = (values) => values.filter((value) => Boolean(value));
|
|
2542
3047
|
const adb = await findExecutable("adb", paths([
|
|
2543
3048
|
android(["platform-tools", windowsAndroidTools ? "adb.exe" : "adb"])
|
|
@@ -2644,8 +3149,8 @@ var init_emulatorDoctor = __esm(() => {
|
|
|
2644
3149
|
|
|
2645
3150
|
// src/mobile/capacitorProject.ts
|
|
2646
3151
|
import { access as access4, readFile as readFile3, rename as rename2, writeFile as writeFile2 } from "fs/promises";
|
|
2647
|
-
import { relative as
|
|
2648
|
-
var CONFIG_FILE = "capacitor.config.ts", portableRelative2 = (root, path) =>
|
|
3152
|
+
import { relative as relative3, resolve as resolve7 } from "path";
|
|
3153
|
+
var CONFIG_FILE = "capacitor.config.ts", portableRelative2 = (root, path) => relative3(root, path).replaceAll("\\", "/"), capacitorConfigSource = (config, projectRoot) => `import type { CapacitorConfig } from '@capacitor/cli';
|
|
2649
3154
|
|
|
2650
3155
|
const config: CapacitorConfig = {
|
|
2651
3156
|
appId: ${JSON.stringify(config.appId)},
|
|
@@ -2668,8 +3173,8 @@ export default config;
|
|
|
2668
3173
|
return false;
|
|
2669
3174
|
}
|
|
2670
3175
|
}, writeAbsoluteCapacitorConfig = async (config, options) => {
|
|
2671
|
-
const projectRoot =
|
|
2672
|
-
const destination =
|
|
3176
|
+
const projectRoot = resolve7(options.projectRoot);
|
|
3177
|
+
const destination = resolve7(projectRoot, CONFIG_FILE);
|
|
2673
3178
|
const source = capacitorConfigSource(config, projectRoot);
|
|
2674
3179
|
if (await exists2(destination)) {
|
|
2675
3180
|
const current = await readFile3(destination, "utf8");
|
|
@@ -2704,10 +3209,10 @@ import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
|
|
|
2704
3209
|
import {
|
|
2705
3210
|
dirname as dirname5,
|
|
2706
3211
|
isAbsolute,
|
|
2707
|
-
join as
|
|
2708
|
-
relative as
|
|
2709
|
-
resolve as
|
|
2710
|
-
sep,
|
|
3212
|
+
join as join11,
|
|
3213
|
+
relative as relative4,
|
|
3214
|
+
resolve as resolve8,
|
|
3215
|
+
sep as sep2,
|
|
2711
3216
|
win32
|
|
2712
3217
|
} from "path";
|
|
2713
3218
|
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]) => {
|
|
@@ -2876,21 +3381,21 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2876
3381
|
return;
|
|
2877
3382
|
throw new DOMException("Android development startup was cancelled.", "AbortError");
|
|
2878
3383
|
}, journalPaths = (projectRoot) => {
|
|
2879
|
-
const root =
|
|
3384
|
+
const root = join11(projectRoot, ".absolutejs", "mobile", "dev-session");
|
|
2880
3385
|
return {
|
|
2881
|
-
backup:
|
|
2882
|
-
caBackup:
|
|
2883
|
-
journal:
|
|
2884
|
-
manifestBackup:
|
|
2885
|
-
networkConfigBackup:
|
|
3386
|
+
backup: join11(root, "capacitor.config.backup.json"),
|
|
3387
|
+
caBackup: join11(root, "absolutejs_dev_ca.backup.pem"),
|
|
3388
|
+
journal: join11(root, "journal.json"),
|
|
3389
|
+
manifestBackup: join11(root, "AndroidManifest.backup.xml"),
|
|
3390
|
+
networkConfigBackup: join11(root, "absolutejs_dev_network_security.backup.xml"),
|
|
2886
3391
|
root
|
|
2887
3392
|
};
|
|
2888
3393
|
}, isInside = (root, path) => {
|
|
2889
|
-
const resolvedRoot =
|
|
2890
|
-
const resolvedPath =
|
|
2891
|
-
const relativePath =
|
|
2892
|
-
return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${
|
|
2893
|
-
}, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), nativeCachePath = (projectRoot) =>
|
|
3394
|
+
const resolvedRoot = resolve8(root);
|
|
3395
|
+
const resolvedPath = resolve8(path);
|
|
3396
|
+
const relativePath = relative4(resolvedRoot, resolvedPath);
|
|
3397
|
+
return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${sep2}`) && !isAbsolute(relativePath);
|
|
3398
|
+
}, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), nativeCachePath = (projectRoot) => join11(projectRoot, ".absolutejs", "mobile", "cache", "android-debug.json"), parseNativeCache = (value) => {
|
|
2894
3399
|
if (!isRecord(value))
|
|
2895
3400
|
return null;
|
|
2896
3401
|
const { appId, fingerprint, format, installations } = value;
|
|
@@ -2922,27 +3427,27 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2922
3427
|
});
|
|
2923
3428
|
}
|
|
2924
3429
|
}, nativeDependencySources = async (nativeDirectory) => {
|
|
2925
|
-
const settings = await readFile4(
|
|
3430
|
+
const settings = await readFile4(join11(nativeDirectory, "capacitor.settings.gradle"), "utf8");
|
|
2926
3431
|
const pattern = new RegExp(CAPACITOR_PROJECT_DIRECTORY_PATTERN.source, CAPACITOR_PROJECT_DIRECTORY_PATTERN.flags);
|
|
2927
3432
|
const dependencies = [...settings.matchAll(pattern)].map((match) => ({
|
|
2928
3433
|
name: (match[1] ?? "").slice(1).replaceAll(/[^a-zA-Z0-9_.-]/gu, "_"),
|
|
2929
|
-
source:
|
|
3434
|
+
source: resolve8(nativeDirectory, match[2] ?? "")
|
|
2930
3435
|
}));
|
|
2931
3436
|
if (dependencies.length === 0) {
|
|
2932
3437
|
throw new Error("Capacitor Android settings did not declare any native dependencies.");
|
|
2933
3438
|
}
|
|
2934
3439
|
return { dependencies, settings };
|
|
2935
3440
|
}, shouldIgnoreNativePath = (relativePath, ignorePublicBundle) => {
|
|
2936
|
-
const parts = relativePath.split(
|
|
3441
|
+
const parts = relativePath.split(sep2);
|
|
2937
3442
|
if (parts.includes(".gradle") || parts.includes("build") || parts.includes(".absolutejs-dependencies")) {
|
|
2938
3443
|
return true;
|
|
2939
3444
|
}
|
|
2940
3445
|
return ignorePublicBundle && parts.slice(0, NATIVE_PUBLIC_PATH_SEGMENTS).join("/") === "app/src/main/assets/public";
|
|
2941
3446
|
}, collectNativePath = async (root, label, path, isDirectory, isFile, isSymbolicLink, ignorePublicBundle) => {
|
|
2942
|
-
const relativePath =
|
|
3447
|
+
const relativePath = relative4(root, path);
|
|
2943
3448
|
if (shouldIgnoreNativePath(relativePath, ignorePublicBundle))
|
|
2944
3449
|
return [];
|
|
2945
|
-
const identity = `${label}:${relativePath.split(
|
|
3450
|
+
const identity = `${label}:${relativePath.split(sep2).join("/")}\x00`;
|
|
2946
3451
|
if (isDirectory) {
|
|
2947
3452
|
return collectNativeDirectory(root, label, path, ignorePublicBundle);
|
|
2948
3453
|
}
|
|
@@ -2962,7 +3467,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2962
3467
|
}, collectNativeDirectory = async (root, label, directory, ignorePublicBundle) => {
|
|
2963
3468
|
const entries = await readdir2(directory, { withFileTypes: true });
|
|
2964
3469
|
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
2965
|
-
const records = await Promise.all(entries.map((entry) => collectNativePath(root, label,
|
|
3470
|
+
const records = await Promise.all(entries.map((entry) => collectNativePath(root, label, join11(directory, entry.name), entry.isDirectory(), entry.isFile(), entry.isSymbolicLink(), ignorePublicBundle)));
|
|
2966
3471
|
return records.flat();
|
|
2967
3472
|
}, hashNativeTree = async (root, label, ignorePublicBundle) => {
|
|
2968
3473
|
const resolvedRoot = await realpath(root);
|
|
@@ -3091,11 +3596,11 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3091
3596
|
await mkdir2(paths.root, { recursive: true });
|
|
3092
3597
|
await writeFile3(paths.backup, source, { flag: "wx" });
|
|
3093
3598
|
await writeFile3(paths.manifestBackup, manifestSource, { flag: "wx" });
|
|
3094
|
-
const resourceRoot =
|
|
3095
|
-
const caPath =
|
|
3599
|
+
const resourceRoot = join11(dirname5(nativeManifestPath), "res");
|
|
3600
|
+
const caPath = join11(resourceRoot, "raw", "absolutejs_dev_ca.pem");
|
|
3096
3601
|
const existingNetworkConfig = manifestSource.match(/android:networkSecurityConfig=["']@xml\/([a-z0-9_]+)["']/u)?.[1];
|
|
3097
3602
|
const networkConfigName = existingNetworkConfig ?? "absolutejs_dev_network_security";
|
|
3098
|
-
const networkConfigPath =
|
|
3603
|
+
const networkConfigPath = join11(resourceRoot, "xml", `${networkConfigName}.xml`);
|
|
3099
3604
|
const backupProjectedFile = async ([path, backupPath]) => {
|
|
3100
3605
|
if (!await pathExists2(path))
|
|
3101
3606
|
return { path };
|
|
@@ -3188,12 +3693,12 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3188
3693
|
}
|
|
3189
3694
|
return result.stdout.trim();
|
|
3190
3695
|
}, mirroredCapacitorDependencies = async (project, capture) => {
|
|
3191
|
-
const settingsPath =
|
|
3696
|
+
const settingsPath = join11(project.nativeDirectory, "capacitor.settings.gradle");
|
|
3192
3697
|
const settings = await readFile4(settingsPath, "utf8");
|
|
3193
3698
|
const dependencies = [];
|
|
3194
3699
|
const rewrittenSettings = settings.replace(CAPACITOR_PROJECT_DIRECTORY_PATTERN, (_statement, projectName, sourcePath) => {
|
|
3195
3700
|
const name = projectName.slice(1).replaceAll(/[^a-zA-Z0-9_.-]/gu, "_");
|
|
3196
|
-
const source =
|
|
3701
|
+
const source = resolve8(project.nativeDirectory, sourcePath);
|
|
3197
3702
|
dependencies.push({
|
|
3198
3703
|
name,
|
|
3199
3704
|
windowsSource: windowsPathFromWsl(source, capture)
|
|
@@ -3234,7 +3739,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3234
3739
|
].join("; ");
|
|
3235
3740
|
return Buffer.from(source, "utf16le").toString("base64");
|
|
3236
3741
|
}, gradleArtifactPath = (nativeDirectory, task, windows = false) => {
|
|
3237
|
-
const pathJoin = windows ? win32.join :
|
|
3742
|
+
const pathJoin = windows ? win32.join : join11;
|
|
3238
3743
|
if (task === "assembleDebug") {
|
|
3239
3744
|
return pathJoin(nativeDirectory, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
|
|
3240
3745
|
}
|
|
@@ -3247,7 +3752,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3247
3752
|
if (task !== "assembleRelease" || await pathExists2(primary)) {
|
|
3248
3753
|
return primary;
|
|
3249
3754
|
}
|
|
3250
|
-
return
|
|
3755
|
+
return join11(nativeDirectory, "app", "build", "outputs", "apk", "release", "app-release-unsigned.apk");
|
|
3251
3756
|
}, buildAbsoluteAndroidGradleArtifact = async (options) => {
|
|
3252
3757
|
const { project, task } = options;
|
|
3253
3758
|
const capture = options.capture ?? captureCommand2;
|
|
@@ -3257,7 +3762,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3257
3762
|
if (project.host === "wsl") {
|
|
3258
3763
|
const windowsSource = windowsPathFromWsl(project.nativeDirectory, capture);
|
|
3259
3764
|
const buildId = Bun.hash(project.projectRoot).toString(HASH_RADIX);
|
|
3260
|
-
const managedBuildDirectory =
|
|
3765
|
+
const managedBuildDirectory = resolve8(project.androidRoot, "..", "..", "Builds", `${project.config.appId}-${buildId}`);
|
|
3261
3766
|
const windowsDirectory = windowsPathFromWsl(managedBuildDirectory, capture);
|
|
3262
3767
|
const windowsAndroidRoot = windowsPathFromWsl(project.androidRoot, capture);
|
|
3263
3768
|
const { dependencies, rewrittenSettings } = await mirroredCapacitorDependencies(project, capture);
|
|
@@ -3440,7 +3945,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3440
3945
|
"chromium:I"
|
|
3441
3946
|
], { env }, onLine);
|
|
3442
3947
|
}, prepareAbsoluteAndroidDevProject = async (config, options) => {
|
|
3443
|
-
const projectRoot =
|
|
3948
|
+
const projectRoot = resolve8(options.projectRoot);
|
|
3444
3949
|
const host2 = detectAbsoluteMobileHost();
|
|
3445
3950
|
const androidRoot = process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host2);
|
|
3446
3951
|
const checks = await inspectAbsoluteMobileToolchain({ androidRoot, host: host2 });
|
|
@@ -3459,18 +3964,18 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3459
3964
|
if (!adb || options.target !== "device" && !emulator) {
|
|
3460
3965
|
throw new Error("Android SDK tools disappeared after readiness checks.");
|
|
3461
3966
|
}
|
|
3462
|
-
const cap =
|
|
3967
|
+
const cap = join11(projectRoot, "node_modules", ".bin", host2 === "windows" ? "cap.cmd" : "cap");
|
|
3463
3968
|
if (!await pathExists2(cap)) {
|
|
3464
3969
|
throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
|
|
3465
3970
|
}
|
|
3466
3971
|
await writeAbsoluteCapacitorConfig(config, { projectRoot });
|
|
3467
3972
|
await mkdir2(config.bundleDirectory, { recursive: true });
|
|
3468
|
-
const placeholder =
|
|
3973
|
+
const placeholder = join11(config.bundleDirectory, "index.html");
|
|
3469
3974
|
if (!await pathExists2(placeholder)) {
|
|
3470
3975
|
await writeFile3(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
|
|
3471
3976
|
`);
|
|
3472
3977
|
}
|
|
3473
|
-
const nativeDirectory =
|
|
3978
|
+
const nativeDirectory = join11(config.nativeProjectDirectory, "android");
|
|
3474
3979
|
if (!await pathExists2(nativeDirectory)) {
|
|
3475
3980
|
if (!options.createNativeProject) {
|
|
3476
3981
|
throw new Error("Android native project has not been created.");
|
|
@@ -3531,8 +4036,8 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3531
4036
|
await requireSuccess([project.cap, "sync", "android"], "Capacitor Android synchronization", run, { cwd: project.projectRoot, env, signal: options.signal });
|
|
3532
4037
|
throwIfAborted(options.signal);
|
|
3533
4038
|
transition("configuring");
|
|
3534
|
-
const nativeConfigPath =
|
|
3535
|
-
const nativeManifestPath =
|
|
4039
|
+
const nativeConfigPath = join11(project.nativeDirectory, "app", "src", "main", "assets", "capacitor.config.json");
|
|
4040
|
+
const nativeManifestPath = join11(project.nativeDirectory, "app", "src", "main", "AndroidManifest.xml");
|
|
3536
4041
|
let connectedSerial;
|
|
3537
4042
|
let nativeLogs = null;
|
|
3538
4043
|
const closeNativeLogs = async () => {
|
|
@@ -3691,7 +4196,7 @@ var init_androidEmulatorController = __esm(() => {
|
|
|
3691
4196
|
import { createHash as createHash3 } from "crypto";
|
|
3692
4197
|
import { cp as cp2, mkdir as mkdir3, mkdtemp as mkdtemp2, readFile as readFile5, rm as rm3 } from "fs/promises";
|
|
3693
4198
|
import { tmpdir } from "os";
|
|
3694
|
-
import { basename as basename3, join as
|
|
4199
|
+
import { basename as basename3, join as join12 } from "path";
|
|
3695
4200
|
var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION = "15859902", LICENSE_ACCEPTANCE_RESPONSES = 100, COMMAND_LINE_TOOLS, defaultRun = async (command, options = {}) => {
|
|
3696
4201
|
const subprocess = Bun.spawn(command, {
|
|
3697
4202
|
env: options.env,
|
|
@@ -3723,7 +4228,7 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3723
4228
|
exitCode: result.exitCode,
|
|
3724
4229
|
stdout: result.stdout.toString()
|
|
3725
4230
|
};
|
|
3726
|
-
}, commandPath = (root, host2, tool) =>
|
|
4231
|
+
}, commandPath = (root, host2, tool) => join12(root, "cmdline-tools", "latest", "bin", host2 === "windows" || host2 === "wsl" ? `${tool}.bat` : tool), executablePath = (root, host2, directory, tool) => join12(root, directory, host2 === "windows" || host2 === "wsl" ? `${tool}.exe` : tool), windowsPath = (path) => {
|
|
3727
4232
|
const match = /^\/mnt\/([a-z])\/(.*)$/i.exec(path);
|
|
3728
4233
|
if (!match)
|
|
3729
4234
|
return path;
|
|
@@ -3797,10 +4302,10 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3797
4302
|
if (digest !== release.sha256) {
|
|
3798
4303
|
throw new Error(`Android command-line-tools checksum mismatch: expected ${release.sha256}, received ${digest}.`);
|
|
3799
4304
|
}
|
|
3800
|
-
const temporary = await mkdtemp2(
|
|
4305
|
+
const temporary = await mkdtemp2(join12(tmpdir(), "absolutejs-android-sdk-"));
|
|
3801
4306
|
try {
|
|
3802
|
-
const archive =
|
|
3803
|
-
const extracted =
|
|
4307
|
+
const archive = join12(temporary, "command-line-tools.zip");
|
|
4308
|
+
const extracted = join12(temporary, "extracted");
|
|
3804
4309
|
await Bun.write(archive, bytes);
|
|
3805
4310
|
await mkdir3(extracted, { recursive: true });
|
|
3806
4311
|
const extraction = plan.host === "windows" ? [
|
|
@@ -3817,12 +4322,12 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3817
4322
|
if (await input.run(extraction) !== 0) {
|
|
3818
4323
|
throw new Error("Failed to extract Android command-line tools.");
|
|
3819
4324
|
}
|
|
3820
|
-
const destination =
|
|
3821
|
-
await mkdir3(
|
|
4325
|
+
const destination = join12(plan.androidRoot, "cmdline-tools", "latest");
|
|
4326
|
+
await mkdir3(join12(plan.androidRoot, "cmdline-tools"), {
|
|
3822
4327
|
recursive: true
|
|
3823
4328
|
});
|
|
3824
4329
|
await rm3(destination, { force: true, recursive: true });
|
|
3825
|
-
await cp2(
|
|
4330
|
+
await cp2(join12(extracted, "cmdline-tools"), destination, {
|
|
3826
4331
|
recursive: true
|
|
3827
4332
|
});
|
|
3828
4333
|
} finally {
|
|
@@ -4007,7 +4512,7 @@ import {
|
|
|
4007
4512
|
stat,
|
|
4008
4513
|
writeFile as writeFile4
|
|
4009
4514
|
} from "fs/promises";
|
|
4010
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as
|
|
4515
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join13, relative as relative5, resolve as resolve9, sep as sep3 } from "path";
|
|
4011
4516
|
var developmentTeamArgument = (value) => {
|
|
4012
4517
|
if (value === undefined)
|
|
4013
4518
|
return;
|
|
@@ -4064,8 +4569,8 @@ var developmentTeamArgument = (value) => {
|
|
|
4064
4569
|
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root, options = {}) => {
|
|
4065
4570
|
const entries = await readdir3(current, { withFileTypes: true });
|
|
4066
4571
|
const nested = await Promise.all(entries.sort((left, right) => left.name.localeCompare(right.name)).map(async (entry) => {
|
|
4067
|
-
const path =
|
|
4068
|
-
const projectRelative =
|
|
4572
|
+
const path = join13(current, entry.name);
|
|
4573
|
+
const projectRelative = relative5(root, path).replaceAll("\\", "/");
|
|
4069
4574
|
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public" && options.includePublicBundle !== true);
|
|
4070
4575
|
if (ignored)
|
|
4071
4576
|
return [];
|
|
@@ -4079,17 +4584,17 @@ var developmentTeamArgument = (value) => {
|
|
|
4079
4584
|
const files = await fingerprintFiles(nativeDirectory, nativeDirectory, options);
|
|
4080
4585
|
const contents = await Promise.all(files.map((file) => readFile6(file)));
|
|
4081
4586
|
files.forEach((file, index) => {
|
|
4082
|
-
hasher.update(
|
|
4587
|
+
hasher.update(relative5(nativeDirectory, file).replaceAll("\\", "/"));
|
|
4083
4588
|
hasher.update("\x00");
|
|
4084
4589
|
hasher.update(contents[index] ?? new Uint8Array);
|
|
4085
4590
|
hasher.update("\x00");
|
|
4086
4591
|
});
|
|
4087
4592
|
return hasher.digest("hex");
|
|
4088
4593
|
}, safeOutputDirectory = (projectRoot, requested) => {
|
|
4089
|
-
const root =
|
|
4090
|
-
const output =
|
|
4091
|
-
const projectRelative =
|
|
4092
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
4594
|
+
const root = resolve9(projectRoot);
|
|
4595
|
+
const output = resolve9(root, requested ?? ".absolutejs/mobile/releases/ios");
|
|
4596
|
+
const projectRelative = relative5(root, output);
|
|
4597
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep3}`) || isAbsolute2(projectRelative)) {
|
|
4093
4598
|
throw new TypeError("mobile build --outdir must remain inside the project.");
|
|
4094
4599
|
}
|
|
4095
4600
|
return output;
|
|
@@ -4098,7 +4603,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4098
4603
|
return;
|
|
4099
4604
|
const entries = await readdir3(root, { withFileTypes: true });
|
|
4100
4605
|
const matches = await Promise.all(entries.map(async (entry) => {
|
|
4101
|
-
const path =
|
|
4606
|
+
const path = join13(root, entry.name);
|
|
4102
4607
|
if (entry.isDirectory() && entry.name.endsWith(extension))
|
|
4103
4608
|
return path;
|
|
4104
4609
|
if (entry.isFile() && entry.name.endsWith(extension))
|
|
@@ -4121,10 +4626,10 @@ var developmentTeamArgument = (value) => {
|
|
|
4121
4626
|
throw new TypeError("iOS build number must be a positive integer.");
|
|
4122
4627
|
return value;
|
|
4123
4628
|
}, installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
4124
|
-
const releaseRoot =
|
|
4125
|
-
const destination =
|
|
4629
|
+
const releaseRoot = join13(outputRoot, metadata.releaseId);
|
|
4630
|
+
const destination = join13(releaseRoot, "App.ipa");
|
|
4126
4631
|
if (await pathExists3(releaseRoot)) {
|
|
4127
|
-
const value = JSON.parse(await readFile6(
|
|
4632
|
+
const value = JSON.parse(await readFile6(join13(releaseRoot, "release.json"), "utf8"));
|
|
4128
4633
|
if (!isRecord2(value) || value.artifact !== "App.ipa" || Object.entries(metadata).some(([key, expected]) => Reflect.get(value, key) !== expected)) {
|
|
4129
4634
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
|
|
4130
4635
|
}
|
|
@@ -4144,14 +4649,14 @@ var developmentTeamArgument = (value) => {
|
|
|
4144
4649
|
};
|
|
4145
4650
|
}
|
|
4146
4651
|
await mkdir4(dirname6(releaseRoot), { recursive: true });
|
|
4147
|
-
const staging = await mkdtemp3(
|
|
4652
|
+
const staging = await mkdtemp3(join13(dirname6(releaseRoot), ".ios-stage-"));
|
|
4148
4653
|
try {
|
|
4149
|
-
await copyFile2(artifactPath,
|
|
4654
|
+
await copyFile2(artifactPath, join13(staging, "App.ipa"));
|
|
4150
4655
|
const complete = {
|
|
4151
4656
|
...metadata,
|
|
4152
4657
|
artifact: "App.ipa"
|
|
4153
4658
|
};
|
|
4154
|
-
await writeFile4(
|
|
4659
|
+
await writeFile4(join13(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
|
|
4155
4660
|
`, { flag: "wx" });
|
|
4156
4661
|
await rename4(staging, releaseRoot);
|
|
4157
4662
|
return { artifactPath: destination, metadata: complete, releaseRoot };
|
|
@@ -4168,22 +4673,22 @@ var developmentTeamArgument = (value) => {
|
|
|
4168
4673
|
const marketingVersion = options.config.iosVersion;
|
|
4169
4674
|
if (!marketingVersion)
|
|
4170
4675
|
throw new TypeError("iOS release builds require mobile.ios.version in absolutejs.config.ts.");
|
|
4171
|
-
const manifest = requireManifest(JSON.parse(await readFile6(
|
|
4676
|
+
const manifest = requireManifest(JSON.parse(await readFile6(join13(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
|
|
4172
4677
|
if (manifest.appId !== options.config.appId)
|
|
4173
4678
|
throw new TypeError("Embedded mobile manifest appId does not match mobile.appId.");
|
|
4174
|
-
const nativeDirectory =
|
|
4679
|
+
const nativeDirectory = join13(options.config.nativeProjectDirectory, "ios");
|
|
4175
4680
|
let buildNumber = requireBuildNumber(options.buildNumber);
|
|
4176
4681
|
if (options.prepareBuildNumber) {
|
|
4177
4682
|
const nativeFingerprint = await fingerprintAbsoluteIosNativeProject(nativeDirectory);
|
|
4178
4683
|
const buildIdentity = createHash4("sha256").update(`${manifest.appBuild}\x00${nativeFingerprint}\x00${marketingVersion}`).digest("hex");
|
|
4179
4684
|
buildNumber = requireBuildNumber(await options.prepareBuildNumber(buildIdentity));
|
|
4180
4685
|
}
|
|
4181
|
-
const stagingParent =
|
|
4686
|
+
const stagingParent = resolve9(options.projectRoot, ".absolutejs/mobile");
|
|
4182
4687
|
await mkdir4(stagingParent, { recursive: true });
|
|
4183
|
-
const staging = await mkdtemp3(
|
|
4184
|
-
const archivePath =
|
|
4185
|
-
const exportPath =
|
|
4186
|
-
const exportPlist =
|
|
4688
|
+
const staging = await mkdtemp3(join13(stagingParent, ".ios-build-"));
|
|
4689
|
+
const archivePath = join13(staging, "App.xcarchive");
|
|
4690
|
+
const exportPath = join13(staging, "export");
|
|
4691
|
+
const exportPlist = join13(staging, "ExportOptions.plist");
|
|
4187
4692
|
await mkdir4(exportPath, { recursive: true });
|
|
4188
4693
|
await writeFile4(exportPlist, exportOptions());
|
|
4189
4694
|
const run = options.run ?? defaultRun2;
|
|
@@ -4197,7 +4702,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4197
4702
|
const archiveExit = await run([
|
|
4198
4703
|
"xcodebuild",
|
|
4199
4704
|
"-workspace",
|
|
4200
|
-
|
|
4705
|
+
join13(nativeDirectory, "App", "App.xcworkspace"),
|
|
4201
4706
|
"-scheme",
|
|
4202
4707
|
"App",
|
|
4203
4708
|
"-configuration",
|
|
@@ -4211,7 +4716,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4211
4716
|
], { cwd: nativeDirectory });
|
|
4212
4717
|
if (archiveExit !== 0)
|
|
4213
4718
|
throw new TypeError("Xcode failed to archive the iOS app.");
|
|
4214
|
-
const archivedApp = await findByExtension(
|
|
4719
|
+
const archivedApp = await findByExtension(join13(archivePath, "Products", "Applications"), ".app");
|
|
4215
4720
|
const capture = options.capture ?? defaultCapture2;
|
|
4216
4721
|
const signed = archivedApp ? capture([
|
|
4217
4722
|
"codesign",
|
|
@@ -4285,7 +4790,7 @@ import {
|
|
|
4285
4790
|
writeFile as writeFile5
|
|
4286
4791
|
} from "fs/promises";
|
|
4287
4792
|
import { isIP as isIP2 } from "net";
|
|
4288
|
-
import { dirname as dirname7, isAbsolute as isAbsolute3, join as
|
|
4793
|
+
import { dirname as dirname7, isAbsolute as isAbsolute3, join as join14, relative as relative6, resolve as resolve10, sep as sep4 } from "path";
|
|
4289
4794
|
var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000, BOOT_POLL_MS = 1000, DEV_JOURNAL_FORMAT2 = 1, NATIVE_CACHE_FORMAT2 = 1, isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), pathExists4 = async (path) => {
|
|
4290
4795
|
try {
|
|
4291
4796
|
await access7(path);
|
|
@@ -4503,16 +5008,16 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4503
5008
|
const leftPro = left.name.includes("Pro") ? 1 : 0;
|
|
4504
5009
|
return rightPro - leftPro;
|
|
4505
5010
|
})[0], journalPaths2 = (projectRoot) => {
|
|
4506
|
-
const root =
|
|
5011
|
+
const root = join14(projectRoot, ".absolutejs", "mobile", "ios-dev-session");
|
|
4507
5012
|
return {
|
|
4508
|
-
configBackup:
|
|
4509
|
-
infoBackup:
|
|
4510
|
-
journal:
|
|
5013
|
+
configBackup: join14(root, "capacitor-config.backup"),
|
|
5014
|
+
infoBackup: join14(root, "Info.plist.backup"),
|
|
5015
|
+
journal: join14(root, "journal.json"),
|
|
4511
5016
|
root
|
|
4512
5017
|
};
|
|
4513
|
-
}, nativeCachePath2 = (projectRoot) =>
|
|
4514
|
-
const value =
|
|
4515
|
-
return value === "" || !value.startsWith(`..${
|
|
5018
|
+
}, nativeCachePath2 = (projectRoot) => join14(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json"), isInside2 = (root, path) => {
|
|
5019
|
+
const value = relative6(resolve10(root), resolve10(path));
|
|
5020
|
+
return value === "" || !value.startsWith(`..${sep4}`) && value !== ".." && !isAbsolute3(value);
|
|
4516
5021
|
}, parseJournal2 = (value) => {
|
|
4517
5022
|
if (!isRecord3(value) || value.format !== DEV_JOURNAL_FORMAT2)
|
|
4518
5023
|
return null;
|
|
@@ -4567,8 +5072,8 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4567
5072
|
}, writeDevProjection = async (project, port, https, serverHost = "localhost") => {
|
|
4568
5073
|
const paths = journalPaths2(project.projectRoot);
|
|
4569
5074
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
4570
|
-
const nativeConfigPath =
|
|
4571
|
-
const infoPath =
|
|
5075
|
+
const nativeConfigPath = join14(project.nativeDirectory, "App", "App", "capacitor.config.json");
|
|
5076
|
+
const infoPath = join14(project.nativeDirectory, "App", "App", "Info.plist");
|
|
4572
5077
|
const [configSource, infoSource] = await Promise.all([
|
|
4573
5078
|
readFile7(nativeConfigPath, "utf8"),
|
|
4574
5079
|
readFile7(infoPath, "utf8")
|
|
@@ -4729,12 +5234,12 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4729
5234
|
]);
|
|
4730
5235
|
return result.exitCode === 0 && result.stdout.includes(project.config.appId);
|
|
4731
5236
|
}, buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
4732
|
-
const derivedDataPath =
|
|
5237
|
+
const derivedDataPath = join14(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash5("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
4733
5238
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
4734
5239
|
await requireSuccess2([
|
|
4735
5240
|
project.xcodebuild,
|
|
4736
5241
|
"-workspace",
|
|
4737
|
-
|
|
5242
|
+
join14(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
4738
5243
|
"-scheme",
|
|
4739
5244
|
"App",
|
|
4740
5245
|
"-configuration",
|
|
@@ -4745,17 +5250,17 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4745
5250
|
derivedDataPath,
|
|
4746
5251
|
"build"
|
|
4747
5252
|
], "iOS simulator build", run, { cwd: project.nativeDirectory, signal });
|
|
4748
|
-
const appPath =
|
|
5253
|
+
const appPath = join14(derivedDataPath, "Build", "Products", "Debug-iphonesimulator", "App.app");
|
|
4749
5254
|
if (!await pathExists4(appPath))
|
|
4750
5255
|
throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
|
|
4751
5256
|
return appPath;
|
|
4752
5257
|
}, buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
|
|
4753
|
-
const derivedDataPath =
|
|
5258
|
+
const derivedDataPath = join14(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash5("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
4754
5259
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
4755
5260
|
await requireSuccess2([
|
|
4756
5261
|
project.xcodebuild,
|
|
4757
5262
|
"-workspace",
|
|
4758
|
-
|
|
5263
|
+
join14(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
4759
5264
|
"-scheme",
|
|
4760
5265
|
"App",
|
|
4761
5266
|
"-configuration",
|
|
@@ -4767,7 +5272,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4767
5272
|
"-allowProvisioningUpdates",
|
|
4768
5273
|
"build"
|
|
4769
5274
|
], "iOS physical-device build (configure automatic signing and a Development Team in Xcode if this is the first run)", run, { cwd: project.nativeDirectory, signal });
|
|
4770
|
-
const appPath =
|
|
5275
|
+
const appPath = join14(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
|
|
4771
5276
|
if (!await pathExists4(appPath))
|
|
4772
5277
|
throw new Error(`Xcode did not produce the physical-device app at ${appPath}.`);
|
|
4773
5278
|
return appPath;
|
|
@@ -4878,7 +5383,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4878
5383
|
if (detectAbsoluteMobileHost() !== "macos")
|
|
4879
5384
|
throw new Error("iOS development requires macOS and Xcode.");
|
|
4880
5385
|
const target = options.target ?? "simulator";
|
|
4881
|
-
const projectRoot =
|
|
5386
|
+
const projectRoot = resolve10(options.projectRoot);
|
|
4882
5387
|
const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
|
|
4883
5388
|
const failed = checks.filter((check) => check.platform === "ios" && !(target === "device" && check.id === "ios.runtime") && (check.status === "fail" || check.status === "warn"));
|
|
4884
5389
|
if (failed.length > 0)
|
|
@@ -4887,16 +5392,16 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4887
5392
|
const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
|
|
4888
5393
|
if (!xcrun || !xcodebuild)
|
|
4889
5394
|
throw new Error("Xcode tools disappeared after readiness checks.");
|
|
4890
|
-
const cap =
|
|
5395
|
+
const cap = join14(projectRoot, "node_modules", ".bin", "cap");
|
|
4891
5396
|
if (!await pathExists4(cap))
|
|
4892
5397
|
throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
|
|
4893
5398
|
await writeAbsoluteCapacitorConfig(config, { projectRoot });
|
|
4894
5399
|
await mkdir5(config.bundleDirectory, { recursive: true });
|
|
4895
|
-
const placeholder =
|
|
5400
|
+
const placeholder = join14(config.bundleDirectory, "index.html");
|
|
4896
5401
|
if (!await pathExists4(placeholder))
|
|
4897
5402
|
await writeFile5(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
|
|
4898
5403
|
`);
|
|
4899
|
-
const nativeDirectory =
|
|
5404
|
+
const nativeDirectory = join14(config.nativeProjectDirectory, "ios");
|
|
4900
5405
|
if (!await pathExists4(nativeDirectory)) {
|
|
4901
5406
|
if (!options.createNativeProject)
|
|
4902
5407
|
throw new Error("iOS native project has not been created.");
|
|
@@ -5121,7 +5626,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
5121
5626
|
screenshot: async (destination) => {
|
|
5122
5627
|
if (deviceIdentifier)
|
|
5123
5628
|
throw new Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");
|
|
5124
|
-
const resolved =
|
|
5629
|
+
const resolved = resolve10(project.projectRoot, destination);
|
|
5125
5630
|
if (!isInside2(project.projectRoot, resolved))
|
|
5126
5631
|
throw new Error("iOS screenshot destination must remain inside the project.");
|
|
5127
5632
|
await mkdir5(dirname7(resolved), { recursive: true });
|
|
@@ -5185,13 +5690,13 @@ import { isIP as isIP3 } from "net";
|
|
|
5185
5690
|
import {
|
|
5186
5691
|
dirname as dirname8,
|
|
5187
5692
|
isAbsolute as isAbsolute4,
|
|
5188
|
-
join as
|
|
5693
|
+
join as join15,
|
|
5189
5694
|
posix,
|
|
5190
|
-
relative as
|
|
5695
|
+
relative as relative7,
|
|
5191
5696
|
resolve as resolvePath,
|
|
5192
|
-
sep as
|
|
5697
|
+
sep as sep5
|
|
5193
5698
|
} from "path";
|
|
5194
|
-
var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TIMEOUT_MS = 2000, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () =>
|
|
5699
|
+
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 = () => ({
|
|
5195
5700
|
format: PROFILE_FORMAT,
|
|
5196
5701
|
profiles: {}
|
|
5197
5702
|
}), loadStore = async (path = defaultProfilePath()) => {
|
|
@@ -5367,9 +5872,9 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5367
5872
|
throw new TypeError("Remote Expo execution requires mobile.engine: expo.");
|
|
5368
5873
|
return createAbsoluteRemoteIosDevProject(config, projectRoot, profile);
|
|
5369
5874
|
}, createAbsoluteRemoteIosDevProject = (config, projectRoot, profile) => ({
|
|
5370
|
-
cap:
|
|
5875
|
+
cap: join15(resolvePath(projectRoot), "node_modules", ".bin", "cap"),
|
|
5371
5876
|
config,
|
|
5372
|
-
nativeDirectory:
|
|
5877
|
+
nativeDirectory: join15(config.nativeProjectDirectory, "ios"),
|
|
5373
5878
|
profile,
|
|
5374
5879
|
projectRoot: resolvePath(projectRoot),
|
|
5375
5880
|
remote: true,
|
|
@@ -5416,8 +5921,8 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5416
5921
|
return { ...artifact, remotePath, uploaded: true };
|
|
5417
5922
|
}, materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
|
|
5418
5923
|
const shippedCandidates = [
|
|
5419
|
-
|
|
5420
|
-
|
|
5924
|
+
join15(import.meta.dir, "remoteMacAgentEntry.js"),
|
|
5925
|
+
join15(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
|
|
5421
5926
|
];
|
|
5422
5927
|
let path;
|
|
5423
5928
|
for (const candidate of shippedCandidates) {
|
|
@@ -5428,13 +5933,13 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5428
5933
|
}
|
|
5429
5934
|
if (!path) {
|
|
5430
5935
|
const sourceCandidates = [
|
|
5431
|
-
|
|
5432
|
-
|
|
5936
|
+
join15(import.meta.dir, "remoteMacAgentEntry.ts"),
|
|
5937
|
+
join15(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
|
|
5433
5938
|
];
|
|
5434
5939
|
const source = await sourceCandidates.reduce(async (found, candidate) => await found ?? (await Bun.file(candidate).exists() ? candidate : undefined), Promise.resolve(undefined));
|
|
5435
5940
|
if (!source)
|
|
5436
5941
|
throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
|
|
5437
|
-
const outdir =
|
|
5942
|
+
const outdir = join15(resolvePath(projectRoot), ".absolutejs", "mobile", "remote-agent");
|
|
5438
5943
|
await mkdir6(outdir, { recursive: true });
|
|
5439
5944
|
const result = await Bun.build({
|
|
5440
5945
|
entrypoints: [source],
|
|
@@ -5444,12 +5949,12 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5444
5949
|
});
|
|
5445
5950
|
if (!result.success)
|
|
5446
5951
|
throw new AggregateError(result.logs, "Failed to build the AbsoluteJS remote Mac agent.");
|
|
5447
|
-
path =
|
|
5952
|
+
path = join15(outdir, "remoteMacAgentEntry.js");
|
|
5448
5953
|
}
|
|
5449
5954
|
const bytes = await Bun.file(path).arrayBuffer();
|
|
5450
5955
|
const sha256 = createHash6("sha256").update(new Uint8Array(bytes)).digest("hex");
|
|
5451
5956
|
return { bytes: bytes.byteLength, path, sha256 };
|
|
5452
|
-
}, portableRelativePath = (root, path) =>
|
|
5957
|
+
}, portableRelativePath = (root, path) => relative7(root, path).split(sep5).join(posix.sep), portableMobileConfig = (project) => ({
|
|
5453
5958
|
appId: project.config.appId,
|
|
5454
5959
|
appName: project.config.appName,
|
|
5455
5960
|
bundleDirectory: portableRelativePath(project.projectRoot, project.config.bundleDirectory),
|
|
@@ -5665,8 +6170,8 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5665
6170
|
const pending = new Map;
|
|
5666
6171
|
let resolveReady;
|
|
5667
6172
|
let rejectReady;
|
|
5668
|
-
const readyPromise = new Promise((
|
|
5669
|
-
resolveReady =
|
|
6173
|
+
const readyPromise = new Promise((resolve11, reject) => {
|
|
6174
|
+
resolveReady = resolve11;
|
|
5670
6175
|
rejectReady = reject;
|
|
5671
6176
|
});
|
|
5672
6177
|
const handleEvent = (event) => {
|
|
@@ -5767,7 +6272,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5767
6272
|
options.log?.(`Remote Mac connected (${options.project.profile.name}); agent ${agent.uploaded ? "uploaded" : "cache hit"}, project synced, and ${expo ? "Expo " : ""}iOS ready in ${totalDuration.toFixed(2)}ms.`);
|
|
5768
6273
|
const request = (commandName) => {
|
|
5769
6274
|
const id = randomUUID4();
|
|
5770
|
-
const response = new Promise((
|
|
6275
|
+
const response = new Promise((resolve11, reject) => pending.set(id, { reject, resolve: resolve11 }));
|
|
5771
6276
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
5772
6277
|
`);
|
|
5773
6278
|
const flush = async () => {
|
|
@@ -5787,7 +6292,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5787
6292
|
if (closed)
|
|
5788
6293
|
return;
|
|
5789
6294
|
closed = true;
|
|
5790
|
-
const timeout = () => new Promise((
|
|
6295
|
+
const timeout = () => new Promise((resolve11) => setTimeout(() => resolve11("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
|
|
5791
6296
|
await Promise.race([
|
|
5792
6297
|
request("close").catch(() => {
|
|
5793
6298
|
return;
|
|
@@ -5835,7 +6340,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5835
6340
|
screenshot: async (destination) => {
|
|
5836
6341
|
const result = await request("screenshot");
|
|
5837
6342
|
const target = resolvePath(options.project.projectRoot, destination);
|
|
5838
|
-
const targetRelative =
|
|
6343
|
+
const targetRelative = relative7(options.project.projectRoot, target);
|
|
5839
6344
|
if (targetRelative.startsWith("..") || isAbsolute4(targetRelative))
|
|
5840
6345
|
throw new Error("iOS screenshot must remain inside the project.");
|
|
5841
6346
|
await mkdir6(dirname8(target), { recursive: true });
|
|
@@ -5875,16 +6380,16 @@ __export(exports_devCert, {
|
|
|
5875
6380
|
});
|
|
5876
6381
|
import {
|
|
5877
6382
|
copyFileSync,
|
|
5878
|
-
existsSync as
|
|
6383
|
+
existsSync as existsSync5,
|
|
5879
6384
|
mkdirSync as mkdirSync4,
|
|
5880
|
-
readFileSync as
|
|
6385
|
+
readFileSync as readFileSync9,
|
|
5881
6386
|
rmSync
|
|
5882
6387
|
} from "fs";
|
|
5883
6388
|
import { X509Certificate as X509Certificate2 } from "crypto";
|
|
5884
6389
|
import { isIP as isIP4 } from "net";
|
|
5885
6390
|
import { platform as platform2 } from "os";
|
|
5886
|
-
import { join as
|
|
5887
|
-
var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE_HOSTS, CERTIFICATE_HOSTNAME_PATTERN, devLog = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[36m[dev]\x1B[0m ${msg}`), devWarn = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[33m[dev]\x1B[0m \x1B[33m${msg}\x1B[0m`), certFilesExist = () =>
|
|
6391
|
+
import { join as join16 } from "path";
|
|
6392
|
+
var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE_HOSTS, CERTIFICATE_HOSTNAME_PATTERN, devLog = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[36m[dev]\x1B[0m ${msg}`), devWarn = (msg) => console.log(`\x1B[2m${new Date().toLocaleTimeString()}\x1B[0m \x1B[33m[dev]\x1B[0m \x1B[33m${msg}\x1B[0m`), certFilesExist = () => existsSync5(CERT_PATH) && existsSync5(KEY_PATH), normalizeDevCertificateHosts = (hosts = []) => {
|
|
5888
6393
|
const normalized = new Set(DEFAULT_CERTIFICATE_HOSTS);
|
|
5889
6394
|
for (const host2 of hosts) {
|
|
5890
6395
|
const value = host2.trim().toLowerCase();
|
|
@@ -5898,7 +6403,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
5898
6403
|
return [...normalized];
|
|
5899
6404
|
}, certificateIsUsable = (hosts) => {
|
|
5900
6405
|
try {
|
|
5901
|
-
const certPem =
|
|
6406
|
+
const certPem = readFileSync9(CERT_PATH, "utf-8");
|
|
5902
6407
|
const certificate = new X509Certificate2(certPem);
|
|
5903
6408
|
if (new Date(certificate.validTo).getTime() <= Date.now())
|
|
5904
6409
|
return false;
|
|
@@ -5983,8 +6488,8 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
5983
6488
|
return null;
|
|
5984
6489
|
try {
|
|
5985
6490
|
return {
|
|
5986
|
-
cert:
|
|
5987
|
-
key:
|
|
6491
|
+
cert: readFileSync9(paths.cert, "utf-8"),
|
|
6492
|
+
key: readFileSync9(paths.key, "utf-8")
|
|
5988
6493
|
};
|
|
5989
6494
|
} catch {
|
|
5990
6495
|
return null;
|
|
@@ -6080,7 +6585,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6080
6585
|
if (platform2() !== "linux")
|
|
6081
6586
|
return false;
|
|
6082
6587
|
try {
|
|
6083
|
-
return /microsoft|wsl/i.test(
|
|
6588
|
+
return /microsoft|wsl/i.test(readFileSync9("/proc/version", "utf-8"));
|
|
6084
6589
|
} catch {
|
|
6085
6590
|
return false;
|
|
6086
6591
|
}
|
|
@@ -6096,8 +6601,8 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6096
6601
|
}
|
|
6097
6602
|
}, mkcertCaRoot = () => runCapture(["mkcert", "-CAROOT"]), getDevCertificateAuthorityPath = () => {
|
|
6098
6603
|
const caRoot = hasMkcert() ? mkcertCaRoot() : null;
|
|
6099
|
-
const rootCertificate = caRoot ?
|
|
6100
|
-
if (rootCertificate &&
|
|
6604
|
+
const rootCertificate = caRoot ? join16(caRoot, "rootCA.pem") : null;
|
|
6605
|
+
if (rootCertificate && existsSync5(rootCertificate))
|
|
6101
6606
|
return rootCertificate;
|
|
6102
6607
|
if (certFilesExist())
|
|
6103
6608
|
return CERT_PATH;
|
|
@@ -6111,13 +6616,13 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6111
6616
|
const caRoot = mkcertCaRoot();
|
|
6112
6617
|
if (!caRoot)
|
|
6113
6618
|
return false;
|
|
6114
|
-
const rootCa =
|
|
6115
|
-
if (!
|
|
6619
|
+
const rootCa = join16(caRoot, "rootCA.pem");
|
|
6620
|
+
if (!existsSync5(rootCa))
|
|
6116
6621
|
return false;
|
|
6117
6622
|
const winTemp = windowsTempDir();
|
|
6118
6623
|
if (!winTemp)
|
|
6119
6624
|
return false;
|
|
6120
|
-
const staged =
|
|
6625
|
+
const staged = join16(winTemp, "absolutejs-mkcert-rootCA.crt");
|
|
6121
6626
|
try {
|
|
6122
6627
|
copyFileSync(rootCa, staged);
|
|
6123
6628
|
} catch {
|
|
@@ -6153,7 +6658,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6153
6658
|
devLog("Trusted the local CA in the Windows store \u2014 Chrome/Edge on Windows now accept dev HTTPS");
|
|
6154
6659
|
} else {
|
|
6155
6660
|
const caRoot = mkcertCaRoot();
|
|
6156
|
-
const hint = caRoot ? toWindowsPath(
|
|
6661
|
+
const hint = caRoot ? toWindowsPath(join16(caRoot, "rootCA.pem")) : null;
|
|
6157
6662
|
devWarn("Could not auto-trust the local CA on Windows; Windows browsers may warn.");
|
|
6158
6663
|
if (hint) {
|
|
6159
6664
|
console.log(` Run in PowerShell: Import-Certificate -FilePath "${hint}" -CertStoreLocation Cert:\\CurrentUser\\Root`);
|
|
@@ -6169,9 +6674,9 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6169
6674
|
return true;
|
|
6170
6675
|
};
|
|
6171
6676
|
var init_devCert = __esm(() => {
|
|
6172
|
-
CERT_DIR =
|
|
6173
|
-
CERT_PATH =
|
|
6174
|
-
KEY_PATH =
|
|
6677
|
+
CERT_DIR = join16(process.cwd(), ".absolutejs");
|
|
6678
|
+
CERT_PATH = join16(CERT_DIR, "cert.pem");
|
|
6679
|
+
KEY_PATH = join16(CERT_DIR, "key.pem");
|
|
6175
6680
|
DEFAULT_CERTIFICATE_HOSTS = ["localhost", "127.0.0.1", "::1"];
|
|
6176
6681
|
CERTIFICATE_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])?))*$/u;
|
|
6177
6682
|
});
|
|
@@ -6187,9 +6692,9 @@ __export(exports_eslintChunked, {
|
|
|
6187
6692
|
ruleSummary: () => ruleSummary,
|
|
6188
6693
|
upstreamRef: () => upstreamRef
|
|
6189
6694
|
});
|
|
6190
|
-
import { existsSync as
|
|
6191
|
-
import { relative as
|
|
6192
|
-
var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAULT_REPORT = ".absolutejs/lint-report.txt", CHILD_HEAP_MB = 4096, DJB2_SEED = 5381, DJB2_MULTIPLIER = 33, MS_PER_SECOND = 1000, SUMMARY_RULE_WIDTH = 60, SUMMARY_COUNT_PAD = 5, PORCELAIN_STATUS_WIDTH = 3, RENAME_ARROW = " -> ", ASCII_ESC = 27, LINTABLE_EXTENSIONS, ANSI_COLOR, stripAnsi = (
|
|
6695
|
+
import { existsSync as existsSync7 } from "fs";
|
|
6696
|
+
import { relative as relative8, resolve as resolve11 } from "path";
|
|
6697
|
+
var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAULT_REPORT = ".absolutejs/lint-report.txt", CHILD_HEAP_MB = 4096, DJB2_SEED = 5381, DJB2_MULTIPLIER = 33, MS_PER_SECOND = 1000, SUMMARY_RULE_WIDTH = 60, SUMMARY_COUNT_PAD = 5, PORCELAIN_STATUS_WIDTH = 3, RENAME_ARROW = " -> ", ASCII_ESC = 27, LINTABLE_EXTENSIONS, ANSI_COLOR, stripAnsi = (text2) => text2.replace(ANSI_COLOR, ""), shardOf = (path, shards) => [...path].reduce((accumulator, character) => (Math.imul(accumulator, DJB2_MULTIPLIER) ^ character.charCodeAt(0)) >>> 0, DJB2_SEED) % shards, gitLines = (cmd, cwd) => Bun.spawnSync(cmd, { cwd }).stdout.toString().split(`
|
|
6193
6698
|
`).map((line) => line.trimEnd()).filter(Boolean), applyChangedBase = (parsed, base) => {
|
|
6194
6699
|
parsed.changedOnly = true;
|
|
6195
6700
|
parsed.changedBase = base;
|
|
@@ -6200,7 +6705,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6200
6705
|
}, matchesAnyGlob = (file, globs) => globs.some((pattern) => new Bun.Glob(pattern).match(file)), resolveLintSet = (parsed, cwd) => {
|
|
6201
6706
|
const visible = gitVisibleFiles(cwd);
|
|
6202
6707
|
const matched = parsed.globs.length === 0 ? visible.filter((file) => LINTABLE_EXTENSIONS.test(file)) : visible.filter((file) => matchesAnyGlob(file, parsed.globs));
|
|
6203
|
-
return matched.filter((file) =>
|
|
6708
|
+
return matched.filter((file) => existsSync7(resolve11(cwd, file))).sort();
|
|
6204
6709
|
}, resolveLintTargets = (args, cwd = process.cwd()) => resolveLintSet(parseChunkedArgs(args), cwd), buildShardChunks = (files, shards, chunkSize) => {
|
|
6205
6710
|
const shardFiles = Array.from({ length: shards }, () => []);
|
|
6206
6711
|
for (const file of files)
|
|
@@ -6222,7 +6727,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6222
6727
|
"content"
|
|
6223
6728
|
];
|
|
6224
6729
|
const proc = Bun.spawn([
|
|
6225
|
-
|
|
6730
|
+
resolve11(cwd, "node_modules/.bin/eslint"),
|
|
6226
6731
|
"--color",
|
|
6227
6732
|
...hasMaxWarnings ? [] : ["--max-warnings", "0"],
|
|
6228
6733
|
...cacheArgs,
|
|
@@ -6269,7 +6774,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6269
6774
|
const fingerprint = createEslintCacheFingerprint(cwd);
|
|
6270
6775
|
for (let shard = 0;shard < parsed.shards; shard++)
|
|
6271
6776
|
prepareEslintCache({
|
|
6272
|
-
cacheLocation:
|
|
6777
|
+
cacheLocation: relative8(cwd, resolve11(cwd, `${cachePrefix}${shard}`)),
|
|
6273
6778
|
cwd,
|
|
6274
6779
|
fingerprint
|
|
6275
6780
|
});
|
|
@@ -6310,7 +6815,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6310
6815
|
const header = `eslint report \u2014 ${files.length} files, ${totalChunks} chunks, ${elapsed}s
|
|
6311
6816
|
${"=".repeat(SUMMARY_RULE_WIDTH)}
|
|
6312
6817
|
`;
|
|
6313
|
-
await Bun.write(
|
|
6818
|
+
await Bun.write(resolve11(cwd, parsed.outFile), header + report + summary);
|
|
6314
6819
|
console.log(summary);
|
|
6315
6820
|
console.log(`Full report written to ${parsed.outFile}`);
|
|
6316
6821
|
if (failedChunks > 0) {
|
|
@@ -6397,14 +6902,14 @@ var init_eslintChunked = __esm(() => {
|
|
|
6397
6902
|
// src/cli/scripts/eslint.ts
|
|
6398
6903
|
import { createHash as createHash7 } from "crypto";
|
|
6399
6904
|
import {
|
|
6400
|
-
existsSync as
|
|
6905
|
+
existsSync as existsSync8,
|
|
6401
6906
|
mkdirSync as mkdirSync5,
|
|
6402
|
-
readFileSync as
|
|
6907
|
+
readFileSync as readFileSync11,
|
|
6403
6908
|
renameSync,
|
|
6404
6909
|
rmSync as rmSync3,
|
|
6405
6910
|
writeFileSync as writeFileSync5
|
|
6406
6911
|
} from "fs";
|
|
6407
|
-
import { dirname as dirname9, relative as
|
|
6912
|
+
import { dirname as dirname9, relative as relative9, resolve as resolve12 } from "path";
|
|
6408
6913
|
var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION = "1", CACHE_FINGERPRINT_SUFFIX = ".fingerprint", flagValue = (args, flag) => {
|
|
6409
6914
|
const assignment = args.find((arg) => arg.startsWith(`${flag}=`));
|
|
6410
6915
|
if (assignment)
|
|
@@ -6428,20 +6933,20 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6428
6933
|
return false;
|
|
6429
6934
|
}, findEslintConfigPath = (cwd = process.cwd()) => {
|
|
6430
6935
|
for (const name of CONFIG_CANDIDATES) {
|
|
6431
|
-
const candidate =
|
|
6432
|
-
if (
|
|
6936
|
+
const candidate = resolve12(cwd, name);
|
|
6937
|
+
if (existsSync8(candidate))
|
|
6433
6938
|
return candidate;
|
|
6434
6939
|
}
|
|
6435
6940
|
return null;
|
|
6436
6941
|
}, fingerprintLocation = (cacheLocation, cwd) => {
|
|
6437
|
-
const absolute =
|
|
6438
|
-
return /[\\/]$/.test(cacheLocation) ?
|
|
6942
|
+
const absolute = resolve12(cwd, cacheLocation);
|
|
6943
|
+
return /[\\/]$/.test(cacheLocation) ? resolve12(absolute, CACHE_FINGERPRINT_SUFFIX.slice(1)) : `${absolute}${CACHE_FINGERPRINT_SUFFIX}`;
|
|
6439
6944
|
}, addFileToFingerprint = (hash, path, label) => {
|
|
6440
|
-
if (!
|
|
6945
|
+
if (!existsSync8(path))
|
|
6441
6946
|
return;
|
|
6442
6947
|
hash.update(label);
|
|
6443
6948
|
hash.update("\x00");
|
|
6444
|
-
hash.update(
|
|
6949
|
+
hash.update(readFileSync11(path));
|
|
6445
6950
|
hash.update("\x00");
|
|
6446
6951
|
}, packageNameFor = (specifier) => {
|
|
6447
6952
|
if (specifier.startsWith("@"))
|
|
@@ -6451,7 +6956,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6451
6956
|
}, configPackageNames = (configPath2) => {
|
|
6452
6957
|
if (!configPath2)
|
|
6453
6958
|
return [];
|
|
6454
|
-
const source =
|
|
6959
|
+
const source = readFileSync11(configPath2, "utf-8");
|
|
6455
6960
|
const names = new Set;
|
|
6456
6961
|
for (const match of source.matchAll(/(?:from\s+|import\s*(?:\(\s*)?|require\s*\(\s*)(['"])([^'".][^'"]*)\1/g)) {
|
|
6457
6962
|
const [, , specifier] = match;
|
|
@@ -6470,11 +6975,11 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6470
6975
|
return Object.keys(value);
|
|
6471
6976
|
});
|
|
6472
6977
|
}, lintDependencyNames = (cwd, configPath2) => {
|
|
6473
|
-
const manifestPath =
|
|
6474
|
-
if (!
|
|
6978
|
+
const manifestPath = resolve12(cwd, "package.json");
|
|
6979
|
+
if (!existsSync8(manifestPath))
|
|
6475
6980
|
return configPackageNames(configPath2);
|
|
6476
6981
|
try {
|
|
6477
|
-
const manifest = JSON.parse(
|
|
6982
|
+
const manifest = JSON.parse(readFileSync11(manifestPath, "utf-8"));
|
|
6478
6983
|
const lintPackages = manifestDependencyNames(manifest).filter((name) => /eslint|typescript/.test(name));
|
|
6479
6984
|
return [
|
|
6480
6985
|
...new Set([...lintPackages, ...configPackageNames(configPath2)])
|
|
@@ -6485,8 +6990,8 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6485
6990
|
}, findInstalledManifest = (cwd, dependency) => {
|
|
6486
6991
|
let directory = cwd;
|
|
6487
6992
|
while (true) {
|
|
6488
|
-
const candidate =
|
|
6489
|
-
if (
|
|
6993
|
+
const candidate = resolve12(directory, "node_modules", dependency, "package.json");
|
|
6994
|
+
if (existsSync8(candidate))
|
|
6490
6995
|
return candidate;
|
|
6491
6996
|
const parent = dirname9(directory);
|
|
6492
6997
|
if (parent === directory)
|
|
@@ -6508,7 +7013,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6508
7013
|
hash.update(`absolute-eslint-config:${CACHE_CONTRACT_VERSION}\x00`);
|
|
6509
7014
|
const configPath2 = findEslintConfigPath(cwd);
|
|
6510
7015
|
if (configPath2)
|
|
6511
|
-
addFileToFingerprint(hash, configPath2,
|
|
7016
|
+
addFileToFingerprint(hash, configPath2, relative9(cwd, configPath2));
|
|
6512
7017
|
return hash.digest("hex");
|
|
6513
7018
|
}, writeFingerprint = (path, fingerprint) => {
|
|
6514
7019
|
mkdirSync5(dirname9(path), { recursive: true });
|
|
@@ -6518,10 +7023,10 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6518
7023
|
renameSync(temporary, path);
|
|
6519
7024
|
}, prepareEslintCache = (options) => {
|
|
6520
7025
|
const cwd = options.cwd ?? process.cwd();
|
|
6521
|
-
const cachePath =
|
|
7026
|
+
const cachePath = resolve12(cwd, options.cacheLocation);
|
|
6522
7027
|
const metadataPath = fingerprintLocation(options.cacheLocation, cwd);
|
|
6523
7028
|
const fingerprint = options.fingerprint ?? createEslintCacheFingerprint(cwd);
|
|
6524
|
-
const prior =
|
|
7029
|
+
const prior = existsSync8(metadataPath) ? readFileSync11(metadataPath, "utf-8").trim() : null;
|
|
6525
7030
|
if (prior === fingerprint)
|
|
6526
7031
|
return false;
|
|
6527
7032
|
rmSync3(cachePath, { force: true, recursive: true });
|
|
@@ -6609,7 +7114,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6609
7114
|
return;
|
|
6610
7115
|
let source;
|
|
6611
7116
|
try {
|
|
6612
|
-
source =
|
|
7117
|
+
source = readFileSync11(configPath2, "utf-8");
|
|
6613
7118
|
} catch {
|
|
6614
7119
|
return;
|
|
6615
7120
|
}
|
|
@@ -6648,7 +7153,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6648
7153
|
return `${minutes}m ${seconds}s`;
|
|
6649
7154
|
}, handleClearCache = (cacheLocation, cwd = process.cwd()) => {
|
|
6650
7155
|
try {
|
|
6651
|
-
const cachePath =
|
|
7156
|
+
const cachePath = resolve12(cwd, cacheLocation);
|
|
6652
7157
|
const metadataPath = fingerprintLocation(cacheLocation, cwd);
|
|
6653
7158
|
rmSync3(cachePath, { force: true, recursive: true });
|
|
6654
7159
|
rmSync3(metadataPath, { force: true, recursive: true });
|
|
@@ -6677,7 +7182,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6677
7182
|
return;
|
|
6678
7183
|
}
|
|
6679
7184
|
if (args.includes("--chunked")) {
|
|
6680
|
-
if (!
|
|
7185
|
+
if (!existsSync8(resolve12("node_modules", ".bin", "eslint"))) {
|
|
6681
7186
|
console.error("\x1B[31m\u2717\x1B[0m ESLint is not installed in this project. Add it (and a flat `eslint.config.*`): bun add -d eslint");
|
|
6682
7187
|
process.exit(1);
|
|
6683
7188
|
}
|
|
@@ -6685,7 +7190,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6685
7190
|
await eslintChunked2(args);
|
|
6686
7191
|
return;
|
|
6687
7192
|
}
|
|
6688
|
-
if (!
|
|
7193
|
+
if (!existsSync8(resolve12("node_modules", ".bin", "eslint"))) {
|
|
6689
7194
|
console.error("\x1B[31m\u2717\x1B[0m ESLint is not installed in this project. Add it (and a flat `eslint.config.*`): bun add -d eslint");
|
|
6690
7195
|
process.exit(1);
|
|
6691
7196
|
}
|
|
@@ -6876,8 +7381,8 @@ var isRecord4 = (value) => typeof value === "object" && value !== null, getIslan
|
|
|
6876
7381
|
var init_islands = () => {};
|
|
6877
7382
|
|
|
6878
7383
|
// src/build/islandEntries.ts
|
|
6879
|
-
import { dirname as dirname10, extname, join as
|
|
6880
|
-
import
|
|
7384
|
+
import { dirname as dirname10, extname as extname2, join as join19, relative as relative10, resolve as resolve14 } from "path";
|
|
7385
|
+
import ts2 from "typescript";
|
|
6881
7386
|
var frameworks, isRecord5 = (value) => typeof value === "object" && value !== null, resolveRegistryExport = (mod) => {
|
|
6882
7387
|
if (isRecord5(mod.islandRegistry))
|
|
6883
7388
|
return mod.islandRegistry;
|
|
@@ -6888,9 +7393,9 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6888
7393
|
if (sourcePath.startsWith("file://")) {
|
|
6889
7394
|
return new URL(sourcePath).pathname;
|
|
6890
7395
|
}
|
|
6891
|
-
return
|
|
7396
|
+
return resolve14(dirname10(registryPath), sourcePath);
|
|
6892
7397
|
}, getObjectPropertyName = (name) => {
|
|
6893
|
-
if (
|
|
7398
|
+
if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
|
|
6894
7399
|
return name.text;
|
|
6895
7400
|
}
|
|
6896
7401
|
return null;
|
|
@@ -6903,7 +7408,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6903
7408
|
});
|
|
6904
7409
|
}, collectNamedImports = (imports, importClause, source) => {
|
|
6905
7410
|
const bindings = importClause.namedBindings;
|
|
6906
|
-
if (!bindings || !
|
|
7411
|
+
if (!bindings || !ts2.isNamedImports(bindings))
|
|
6907
7412
|
return;
|
|
6908
7413
|
for (const element of bindings.elements) {
|
|
6909
7414
|
imports.set(element.name.text, {
|
|
@@ -6917,7 +7422,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6917
7422
|
const bindings = importClause.namedBindings;
|
|
6918
7423
|
if (!bindings)
|
|
6919
7424
|
return;
|
|
6920
|
-
if (
|
|
7425
|
+
if (ts2.isNamespaceImport(bindings)) {
|
|
6921
7426
|
registryNamespaceNames.add(bindings.name.text);
|
|
6922
7427
|
return;
|
|
6923
7428
|
}
|
|
@@ -6935,13 +7440,13 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6935
7440
|
const frameworkRegistry = registry2[framework] ?? {};
|
|
6936
7441
|
registry2[framework] = frameworkRegistry;
|
|
6937
7442
|
for (const property of frameworkNode.properties) {
|
|
6938
|
-
if (!
|
|
7443
|
+
if (!ts2.isPropertyAssignment(property) && !ts2.isShorthandPropertyAssignment(property))
|
|
6939
7444
|
continue;
|
|
6940
7445
|
const componentName = getObjectPropertyName(property.name);
|
|
6941
7446
|
if (!componentName)
|
|
6942
7447
|
continue;
|
|
6943
|
-
const initializer =
|
|
6944
|
-
if (!
|
|
7448
|
+
const initializer = ts2.isPropertyAssignment(property) ? property.initializer : property.name;
|
|
7449
|
+
if (!ts2.isIdentifier(initializer))
|
|
6945
7450
|
continue;
|
|
6946
7451
|
const reference = imports.get(initializer.text);
|
|
6947
7452
|
if (!reference)
|
|
@@ -6955,7 +7460,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6955
7460
|
}
|
|
6956
7461
|
}, processDefineIslandRegistry = (node, imports, definitions, registry2) => {
|
|
6957
7462
|
const [firstArg] = node.arguments;
|
|
6958
|
-
if (!firstArg || !
|
|
7463
|
+
if (!firstArg || !ts2.isObjectLiteralExpression(firstArg))
|
|
6959
7464
|
return;
|
|
6960
7465
|
const validFrameworks = [
|
|
6961
7466
|
"react",
|
|
@@ -6964,7 +7469,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6964
7469
|
"angular"
|
|
6965
7470
|
];
|
|
6966
7471
|
for (const property of firstArg.properties) {
|
|
6967
|
-
if (!
|
|
7472
|
+
if (!ts2.isPropertyAssignment(property))
|
|
6968
7473
|
continue;
|
|
6969
7474
|
const frameworkName = getObjectPropertyName(property.name);
|
|
6970
7475
|
if (!frameworkName)
|
|
@@ -6972,28 +7477,28 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6972
7477
|
const framework = validFrameworks.find((f) => f === frameworkName);
|
|
6973
7478
|
if (!framework)
|
|
6974
7479
|
continue;
|
|
6975
|
-
if (!
|
|
7480
|
+
if (!ts2.isObjectLiteralExpression(property.initializer))
|
|
6976
7481
|
continue;
|
|
6977
7482
|
addRegistryEntries(property.initializer, framework, imports, definitions, registry2);
|
|
6978
7483
|
}
|
|
6979
7484
|
}, walkRegistryNode = (node, imports, registryFactoryNames, registryNamespaceNames, definitions, registry2) => {
|
|
6980
|
-
if (
|
|
7485
|
+
if (ts2.isCallExpression(node) && isDefineIslandRegistryCall(node.expression, registryFactoryNames, registryNamespaceNames)) {
|
|
6981
7486
|
processDefineIslandRegistry(node, imports, definitions, registry2);
|
|
6982
7487
|
}
|
|
6983
|
-
|
|
7488
|
+
ts2.forEachChild(node, (child) => walkRegistryNode(child, imports, registryFactoryNames, registryNamespaceNames, definitions, registry2));
|
|
6984
7489
|
}, isDefineIslandRegistryCall = (expression, registryFactoryNames, registryNamespaceNames) => {
|
|
6985
|
-
if (
|
|
7490
|
+
if (ts2.isIdentifier(expression)) {
|
|
6986
7491
|
return registryFactoryNames.has(expression.text);
|
|
6987
7492
|
}
|
|
6988
|
-
return
|
|
7493
|
+
return ts2.isPropertyAccessExpression(expression) && expression.name.text === "defineIslandRegistry" && ts2.isIdentifier(expression.expression) && registryNamespaceNames.has(expression.expression.text);
|
|
6989
7494
|
}, hasIslandRegistryNamedExport = (sourceFile) => {
|
|
6990
7495
|
for (const statement of sourceFile.statements) {
|
|
6991
|
-
if (
|
|
7496
|
+
if (ts2.isVariableStatement(statement) && statement.modifiers?.some((modifier) => modifier.kind === ts2.SyntaxKind.ExportKeyword) && statement.declarationList.declarations.some((declaration) => ts2.isIdentifier(declaration.name) && declaration.name.text === "islandRegistry")) {
|
|
6992
7497
|
return true;
|
|
6993
7498
|
}
|
|
6994
|
-
if (!
|
|
7499
|
+
if (!ts2.isExportDeclaration(statement) || !statement.exportClause)
|
|
6995
7500
|
continue;
|
|
6996
|
-
if (!
|
|
7501
|
+
if (!ts2.isNamedExports(statement.exportClause))
|
|
6997
7502
|
continue;
|
|
6998
7503
|
if (statement.exportClause.elements.some((element) => element.name.text === "islandRegistry")) {
|
|
6999
7504
|
return true;
|
|
@@ -7002,7 +7507,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7002
7507
|
return false;
|
|
7003
7508
|
}, collectImportDeclarations = (sourceFile, registryPath, imports, registryFactoryNames, registryNamespaceNames) => {
|
|
7004
7509
|
for (const statement of sourceFile.statements) {
|
|
7005
|
-
if (!
|
|
7510
|
+
if (!ts2.isImportDeclaration(statement) || !ts2.isStringLiteral(statement.moduleSpecifier))
|
|
7006
7511
|
continue;
|
|
7007
7512
|
const { importClause } = statement;
|
|
7008
7513
|
if (!importClause)
|
|
@@ -7013,7 +7518,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7013
7518
|
collectRegistryHelperImports(importClause, statement.moduleSpecifier.text, registryFactoryNames, registryNamespaceNames);
|
|
7014
7519
|
}
|
|
7015
7520
|
}, parseIslandRegistryBuildInfo = (registrySource, registryPath) => {
|
|
7016
|
-
const sourceFile =
|
|
7521
|
+
const sourceFile = ts2.createSourceFile(registryPath, registrySource, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
|
|
7017
7522
|
const imports = new Map;
|
|
7018
7523
|
const registryFactoryNames = new Set(["defineIslandRegistry"]);
|
|
7019
7524
|
const registryNamespaceNames = new Set;
|
|
@@ -7045,7 +7550,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7045
7550
|
registry: registry2
|
|
7046
7551
|
};
|
|
7047
7552
|
}, loadIslandRegistryBuildInfo = async (registryPath) => {
|
|
7048
|
-
const resolvedRegistryPath =
|
|
7553
|
+
const resolvedRegistryPath = resolve14(registryPath);
|
|
7049
7554
|
const registrySource = Bun.file(resolvedRegistryPath);
|
|
7050
7555
|
const registrySourceText = await registrySource.text();
|
|
7051
7556
|
const parsedInfo = parseIslandRegistryBuildInfo(registrySourceText, resolvedRegistryPath);
|
|
@@ -7075,25 +7580,25 @@ var init_islandEntries = __esm(() => {
|
|
|
7075
7580
|
|
|
7076
7581
|
// src/build/islandRegistryTransform.ts
|
|
7077
7582
|
import { basename as basename6 } from "path";
|
|
7078
|
-
import
|
|
7079
|
-
var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) =>
|
|
7583
|
+
import ts3 from "typescript";
|
|
7584
|
+
var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts3.isIdentifier(name) || ts3.isStringLiteral(name) ? name.text : null, isIslandRegistryHelperImport2 = (source) => source === "@absolutejs/absolute/islands" || source.endsWith("/islands") || source.endsWith("/core/islands"), collectRegistryFactory = (sourceFile) => {
|
|
7080
7585
|
const factoryNames = new Set;
|
|
7081
7586
|
const namespaceNames = new Set;
|
|
7082
7587
|
for (const statement of sourceFile.statements) {
|
|
7083
|
-
if (!
|
|
7588
|
+
if (!ts3.isImportDeclaration(statement))
|
|
7084
7589
|
continue;
|
|
7085
|
-
if (!
|
|
7590
|
+
if (!ts3.isStringLiteral(statement.moduleSpecifier))
|
|
7086
7591
|
continue;
|
|
7087
7592
|
if (!isIslandRegistryHelperImport2(statement.moduleSpecifier.text))
|
|
7088
7593
|
continue;
|
|
7089
7594
|
const bindings = statement.importClause?.namedBindings;
|
|
7090
7595
|
if (!bindings)
|
|
7091
7596
|
continue;
|
|
7092
|
-
if (
|
|
7597
|
+
if (ts3.isNamespaceImport(bindings)) {
|
|
7093
7598
|
namespaceNames.add(bindings.name.text);
|
|
7094
7599
|
continue;
|
|
7095
7600
|
}
|
|
7096
|
-
if (!
|
|
7601
|
+
if (!ts3.isNamedImports(bindings))
|
|
7097
7602
|
continue;
|
|
7098
7603
|
for (const element of bindings.elements) {
|
|
7099
7604
|
const imported = element.propertyName?.text ?? element.name.text;
|
|
@@ -7104,20 +7609,20 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7104
7609
|
}
|
|
7105
7610
|
return { factoryNames, namespaceNames };
|
|
7106
7611
|
}, isDefineIslandRegistryCall2 = (expression, factoryNames, namespaceNames) => {
|
|
7107
|
-
if (
|
|
7612
|
+
if (ts3.isIdentifier(expression))
|
|
7108
7613
|
return factoryNames.has(expression.text);
|
|
7109
|
-
return
|
|
7614
|
+
return ts3.isPropertyAccessExpression(expression) && expression.name.text === "defineIslandRegistry" && ts3.isIdentifier(expression.expression) && namespaceNames.has(expression.expression.text);
|
|
7110
7615
|
}, findDefineIslandRegistryCall = (sourceFile, factoryNames, namespaceNames) => {
|
|
7111
7616
|
let found = null;
|
|
7112
7617
|
const visit = (node) => {
|
|
7113
7618
|
if (found)
|
|
7114
7619
|
return;
|
|
7115
|
-
const [firstArg] =
|
|
7116
|
-
if (
|
|
7620
|
+
const [firstArg] = ts3.isCallExpression(node) ? node.arguments : [];
|
|
7621
|
+
if (ts3.isCallExpression(node) && isDefineIslandRegistryCall2(node.expression, factoryNames, namespaceNames) && firstArg && ts3.isObjectLiteralExpression(firstArg)) {
|
|
7117
7622
|
found = node;
|
|
7118
7623
|
return;
|
|
7119
7624
|
}
|
|
7120
|
-
|
|
7625
|
+
ts3.forEachChild(node, visit);
|
|
7121
7626
|
};
|
|
7122
7627
|
visit(sourceFile);
|
|
7123
7628
|
return found;
|
|
@@ -7127,8 +7632,8 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7127
7632
|
}, transformIslandRegistrySource = (source, filePath, info2) => {
|
|
7128
7633
|
if (!source.includes("defineIslandRegistry"))
|
|
7129
7634
|
return null;
|
|
7130
|
-
const scriptKind = filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ?
|
|
7131
|
-
const sourceFile =
|
|
7635
|
+
const scriptKind = filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ? ts3.ScriptKind.TSX : ts3.ScriptKind.TS;
|
|
7636
|
+
const sourceFile = ts3.createSourceFile(filePath, source, ts3.ScriptTarget.Latest, true, scriptKind);
|
|
7132
7637
|
const { factoryNames, namespaceNames } = collectRegistryFactory(sourceFile);
|
|
7133
7638
|
if (factoryNames.size === 0 && namespaceNames.size === 0)
|
|
7134
7639
|
return null;
|
|
@@ -7136,7 +7641,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7136
7641
|
if (!call)
|
|
7137
7642
|
return null;
|
|
7138
7643
|
const [objectLiteral] = call.arguments;
|
|
7139
|
-
if (!objectLiteral || !
|
|
7644
|
+
if (!objectLiteral || !ts3.isObjectLiteralExpression(objectLiteral)) {
|
|
7140
7645
|
return null;
|
|
7141
7646
|
}
|
|
7142
7647
|
const definitionLookup = new Map;
|
|
@@ -7151,20 +7656,20 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7151
7656
|
const edits = [];
|
|
7152
7657
|
const replacedLocals = new Set;
|
|
7153
7658
|
for (const frameworkProperty of objectLiteral.properties) {
|
|
7154
|
-
if (!
|
|
7659
|
+
if (!ts3.isPropertyAssignment(frameworkProperty))
|
|
7155
7660
|
continue;
|
|
7156
7661
|
const frameworkName = getObjectPropertyName2(frameworkProperty.name);
|
|
7157
7662
|
const framework = VALID_FRAMEWORKS.find((f) => f === frameworkName);
|
|
7158
7663
|
if (!framework)
|
|
7159
7664
|
continue;
|
|
7160
|
-
if (!
|
|
7665
|
+
if (!ts3.isObjectLiteralExpression(frameworkProperty.initializer))
|
|
7161
7666
|
continue;
|
|
7162
7667
|
for (const componentProperty of frameworkProperty.initializer.properties) {
|
|
7163
7668
|
let componentKey = null;
|
|
7164
7669
|
let localName = null;
|
|
7165
7670
|
let replaceNode = null;
|
|
7166
7671
|
let replacementText = "";
|
|
7167
|
-
if (
|
|
7672
|
+
if (ts3.isShorthandPropertyAssignment(componentProperty)) {
|
|
7168
7673
|
componentKey = componentProperty.name.text;
|
|
7169
7674
|
localName = componentProperty.name.text;
|
|
7170
7675
|
const reference = definitionLookup.get(`${framework}:${componentKey}`);
|
|
@@ -7172,7 +7677,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7172
7677
|
continue;
|
|
7173
7678
|
replaceNode = componentProperty;
|
|
7174
7679
|
replacementText = `${quoteKey(componentKey)}: ${definitionLiteral(reference)}`;
|
|
7175
|
-
} else if (
|
|
7680
|
+
} else if (ts3.isPropertyAssignment(componentProperty) && ts3.isIdentifier(componentProperty.initializer)) {
|
|
7176
7681
|
componentKey = getObjectPropertyName2(componentProperty.name);
|
|
7177
7682
|
localName = componentProperty.initializer.text;
|
|
7178
7683
|
if (!componentKey)
|
|
@@ -7196,7 +7701,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7196
7701
|
if (edits.length === 0)
|
|
7197
7702
|
return null;
|
|
7198
7703
|
for (const statement of sourceFile.statements) {
|
|
7199
|
-
if (!
|
|
7704
|
+
if (!ts3.isImportDeclaration(statement))
|
|
7200
7705
|
continue;
|
|
7201
7706
|
const clause = statement.importClause;
|
|
7202
7707
|
if (!clause)
|
|
@@ -7205,11 +7710,11 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7205
7710
|
if (clause.name)
|
|
7206
7711
|
localNames.push(clause.name.text);
|
|
7207
7712
|
const bindings = clause.namedBindings;
|
|
7208
|
-
if (bindings &&
|
|
7713
|
+
if (bindings && ts3.isNamedImports(bindings)) {
|
|
7209
7714
|
for (const element of bindings.elements) {
|
|
7210
7715
|
localNames.push(element.name.text);
|
|
7211
7716
|
}
|
|
7212
|
-
} else if (bindings &&
|
|
7717
|
+
} else if (bindings && ts3.isNamespaceImport(bindings)) {
|
|
7213
7718
|
localNames.push(bindings.name.text);
|
|
7214
7719
|
}
|
|
7215
7720
|
if (localNames.length === 0)
|
|
@@ -7266,18 +7771,18 @@ var init_islandRegistryTransform = __esm(() => {
|
|
|
7266
7771
|
});
|
|
7267
7772
|
|
|
7268
7773
|
// src/build/bunStringRawUnicodePlugin.ts
|
|
7269
|
-
import { extname as
|
|
7270
|
-
import
|
|
7774
|
+
import { extname as extname3 } from "path";
|
|
7775
|
+
import ts4 from "typescript";
|
|
7271
7776
|
var NON_ASCII, getScriptKind = (filePath) => {
|
|
7272
7777
|
if (/\.[cm]?tsx$/.test(filePath))
|
|
7273
|
-
return
|
|
7778
|
+
return ts4.ScriptKind.TSX;
|
|
7274
7779
|
if (/\.[cm]?jsx$/.test(filePath))
|
|
7275
|
-
return
|
|
7780
|
+
return ts4.ScriptKind.JSX;
|
|
7276
7781
|
if (/\.[cm]?ts$/.test(filePath))
|
|
7277
|
-
return
|
|
7278
|
-
return
|
|
7782
|
+
return ts4.ScriptKind.TS;
|
|
7783
|
+
return ts4.ScriptKind.JS;
|
|
7279
7784
|
}, getLoader = (filePath) => {
|
|
7280
|
-
const extension =
|
|
7785
|
+
const extension = extname3(filePath);
|
|
7281
7786
|
if (extension === ".tsx")
|
|
7282
7787
|
return "tsx";
|
|
7283
7788
|
if (extension === ".jsx")
|
|
@@ -7286,24 +7791,24 @@ var NON_ASCII, getScriptKind = (filePath) => {
|
|
|
7286
7791
|
return "ts";
|
|
7287
7792
|
}
|
|
7288
7793
|
return "js";
|
|
7289
|
-
}, isStringRawTag = (node) =>
|
|
7794
|
+
}, isStringRawTag = (node) => ts4.isPropertyAccessExpression(node.tag) && ts4.isIdentifier(node.tag.expression) && node.tag.expression.text === "String" && node.tag.name.text === "raw", getRawText = (node) => node.rawText ?? node.text, rewriteBunStringRawUnicode = (source, filePath = "input.ts") => {
|
|
7290
7795
|
if (!source.includes("String.raw") || !NON_ASCII.test(source))
|
|
7291
7796
|
return source;
|
|
7292
|
-
const sourceFile =
|
|
7797
|
+
const sourceFile = ts4.createSourceFile(filePath, source, ts4.ScriptTarget.Latest, true, getScriptKind(filePath));
|
|
7293
7798
|
const replacements = [];
|
|
7294
7799
|
const visit = (node) => {
|
|
7295
|
-
if (
|
|
7296
|
-
const rawSegments =
|
|
7800
|
+
if (ts4.isTaggedTemplateExpression(node) && isStringRawTag(node)) {
|
|
7801
|
+
const rawSegments = ts4.isNoSubstitutionTemplateLiteral(node.template) ? [getRawText(node.template)] : [
|
|
7297
7802
|
getRawText(node.template.head),
|
|
7298
7803
|
...node.template.templateSpans.map((span) => getRawText(span.literal))
|
|
7299
7804
|
];
|
|
7300
7805
|
if (rawSegments.some((segment) => NON_ASCII.test(segment))) {
|
|
7301
|
-
const expressions =
|
|
7806
|
+
const expressions = ts4.isTemplateExpression(node.template) ? node.template.templateSpans.map((span) => {
|
|
7302
7807
|
const expression = source.slice(span.expression.getStart(sourceFile), span.expression.end);
|
|
7303
7808
|
return rewriteBunStringRawUnicode(expression, filePath);
|
|
7304
7809
|
}) : [];
|
|
7305
7810
|
const args = [
|
|
7306
|
-
`{ raw: [${rawSegments.map((
|
|
7811
|
+
`{ raw: [${rawSegments.map((text2) => JSON.stringify(text2)).join(", ")}] }`,
|
|
7307
7812
|
...expressions
|
|
7308
7813
|
];
|
|
7309
7814
|
replacements.push({
|
|
@@ -7314,7 +7819,7 @@ var NON_ASCII, getScriptKind = (filePath) => {
|
|
|
7314
7819
|
return;
|
|
7315
7820
|
}
|
|
7316
7821
|
}
|
|
7317
|
-
|
|
7822
|
+
ts4.forEachChild(node, visit);
|
|
7318
7823
|
};
|
|
7319
7824
|
visit(sourceFile);
|
|
7320
7825
|
let result = source;
|
|
@@ -7579,20 +8084,20 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
|
|
|
7579
8084
|
// src/mobile/buildRelease.ts
|
|
7580
8085
|
import { createHash as createHash9 } from "crypto";
|
|
7581
8086
|
import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
7582
|
-
import { basename as basename7, dirname as dirname11, extname as
|
|
8087
|
+
import { basename as basename7, dirname as dirname11, extname as extname4, join as join20, relative as relative11, resolve as resolve15 } from "path";
|
|
7583
8088
|
var sha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex"), STATIC_SCRIPT_PATTERN, rewriteStaticScriptPaths = (source, manifest) => source.replace(STATIC_SCRIPT_PATTERN, (match, prefix, path, suffix) => {
|
|
7584
8089
|
if (path.endsWith("/htmx.min.js"))
|
|
7585
8090
|
return match;
|
|
7586
|
-
const key = toPascal(basename7(path,
|
|
8091
|
+
const key = toPascal(basename7(path, extname4(path)));
|
|
7587
8092
|
const builtPath = manifest[key];
|
|
7588
8093
|
return builtPath ? `${prefix}${builtPath}${suffix}` : match;
|
|
7589
8094
|
}), readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]), resolveAssetPath = (buildDirectory, assetPath) => {
|
|
7590
|
-
const resolvedBuildDirectory =
|
|
7591
|
-
const resolvedAsset =
|
|
8095
|
+
const resolvedBuildDirectory = resolve15(buildDirectory);
|
|
8096
|
+
const resolvedAsset = resolve15(assetPath);
|
|
7592
8097
|
if (resolvedAsset.startsWith(`${resolvedBuildDirectory}/`)) {
|
|
7593
8098
|
return resolvedAsset;
|
|
7594
8099
|
}
|
|
7595
|
-
return
|
|
8100
|
+
return join20(buildDirectory, assetPath.replace(/^\/+/, ""));
|
|
7596
8101
|
}, pageFor = async (metadata, manifest, buildDirectory) => {
|
|
7597
8102
|
const assetPath = manifest[metadata.bundleKey];
|
|
7598
8103
|
if (!assetPath) {
|
|
@@ -7603,7 +8108,7 @@ var sha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex"), STATI
|
|
|
7603
8108
|
const source = await readFile9(resolvedAssetPath, "utf8");
|
|
7604
8109
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
7605
8110
|
const documentHash = sha256(new TextEncoder().encode(rewritten));
|
|
7606
|
-
resolvedAssetPath =
|
|
8111
|
+
resolvedAssetPath = join20(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
7607
8112
|
await mkdir8(dirname11(resolvedAssetPath), { recursive: true });
|
|
7608
8113
|
await writeFile7(resolvedAssetPath, rewritten);
|
|
7609
8114
|
}
|
|
@@ -7617,8 +8122,8 @@ var sha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex"), STATI
|
|
|
7617
8122
|
readFile9(resolvedAssetPath),
|
|
7618
8123
|
resolvedStylePath ? readFile9(resolvedStylePath) : undefined
|
|
7619
8124
|
]);
|
|
7620
|
-
const bundlePath = `/${
|
|
7621
|
-
const styleBundlePath = resolvedStylePath ? `/${
|
|
8125
|
+
const bundlePath = `/${relative11(resolve15(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
8126
|
+
const styleBundlePath = resolvedStylePath ? `/${relative11(resolve15(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
7622
8127
|
return {
|
|
7623
8128
|
bundleHash: sha256(bytes),
|
|
7624
8129
|
bundlePath,
|
|
@@ -7819,40 +8324,40 @@ import {
|
|
|
7819
8324
|
rm as rm6,
|
|
7820
8325
|
writeFile as writeFile8
|
|
7821
8326
|
} from "fs/promises";
|
|
7822
|
-
import { existsSync as
|
|
7823
|
-
import { basename as basename8, dirname as dirname12, extname as
|
|
8327
|
+
import { existsSync as existsSync10 } from "fs";
|
|
8328
|
+
import { basename as basename8, dirname as dirname12, extname as extname5, join as join21, relative as relative12, resolve as resolve16 } from "path";
|
|
7824
8329
|
var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-mobile-bootstrap.js", INDEX_FILE = "index.html", CLIENT_CSS_DEPENDENCY_PATTERN, CLIENT_MARKUP_DEPENDENCY_PATTERN, CAPACITOR_CLIENT_FRAMEWORKS, CLIENT_ASSET_DIRECTORIES, errorHasCode = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, shellBootstrapModule = () => {
|
|
7825
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8330
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync10);
|
|
7826
8331
|
if (candidate)
|
|
7827
8332
|
return candidate;
|
|
7828
8333
|
throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
|
|
7829
8334
|
}, shellAuthModule = () => {
|
|
7830
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8335
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellAuth.${extension}`)).find(existsSync10);
|
|
7831
8336
|
if (candidate)
|
|
7832
8337
|
return candidate;
|
|
7833
8338
|
throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
|
|
7834
8339
|
}, shellExpoAuthModule = () => {
|
|
7835
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8340
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync10);
|
|
7836
8341
|
if (candidate)
|
|
7837
8342
|
return candidate;
|
|
7838
8343
|
throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
|
|
7839
8344
|
}, shellSyncModule = () => {
|
|
7840
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8345
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellSync.${extension}`)).find(existsSync10);
|
|
7841
8346
|
if (candidate)
|
|
7842
8347
|
return candidate;
|
|
7843
8348
|
throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
|
|
7844
8349
|
}, shellExpoSyncModule = () => {
|
|
7845
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8350
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync10);
|
|
7846
8351
|
if (candidate)
|
|
7847
8352
|
return candidate;
|
|
7848
8353
|
throw new TypeError("AbsoluteJS Expo Sync bridge module is missing.");
|
|
7849
8354
|
}, shellPushModule = () => {
|
|
7850
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8355
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellPush.${extension}`)).find(existsSync10);
|
|
7851
8356
|
if (candidate)
|
|
7852
8357
|
return candidate;
|
|
7853
8358
|
throw new TypeError("AbsoluteJS mobile push shell module is missing.");
|
|
7854
8359
|
}, shellExpoDevicesModule = () => {
|
|
7855
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8360
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoDevices.${extension}`)).find(existsSync10);
|
|
7856
8361
|
if (candidate)
|
|
7857
8362
|
return candidate;
|
|
7858
8363
|
throw new TypeError("AbsoluteJS Expo device bridge module is missing.");
|
|
@@ -7883,8 +8388,8 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7883
8388
|
</body>
|
|
7884
8389
|
</html>
|
|
7885
8390
|
`, sourceAssetPath = (buildDirectory, bundlePath) => {
|
|
7886
|
-
const root =
|
|
7887
|
-
const asset =
|
|
8391
|
+
const root = resolve16(buildDirectory);
|
|
8392
|
+
const asset = resolve16(root, bundlePath.replace(/^\/+/, ""));
|
|
7888
8393
|
if (!asset.startsWith(`${root}/`)) {
|
|
7889
8394
|
throw new TypeError("Mobile page bundle escaped the build directory.");
|
|
7890
8395
|
}
|
|
@@ -7899,15 +8404,15 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7899
8404
|
const segments = specifier.split("/");
|
|
7900
8405
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
7901
8406
|
const subpath = specifier.slice(packageName.length);
|
|
7902
|
-
const packageDirectory =
|
|
7903
|
-
const manifest = JSON.parse(await readFile10(
|
|
8407
|
+
const packageDirectory = join21(resolve16(projectRoot), "node_modules", packageName);
|
|
8408
|
+
const manifest = JSON.parse(await readFile10(join21(packageDirectory, "package.json"), "utf8"));
|
|
7904
8409
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
7905
8410
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
7906
8411
|
const target = importEntryTarget(entry);
|
|
7907
8412
|
if (typeof target !== "string" || !target.startsWith("./"))
|
|
7908
8413
|
throw new TypeError(`${specifier} does not publish an import entry.`);
|
|
7909
|
-
const resolved =
|
|
7910
|
-
if (!resolved.startsWith(`${
|
|
8414
|
+
const resolved = resolve16(packageDirectory, target);
|
|
8415
|
+
if (!resolved.startsWith(`${resolve16(packageDirectory)}/`))
|
|
7911
8416
|
throw new TypeError(`${specifier} has an unsafe import entry.`);
|
|
7912
8417
|
return resolved;
|
|
7913
8418
|
}, buildShellBootstrap = async (staging, auth, sync, storagePrefix, engine, deviceCapabilities, projectRoot) => {
|
|
@@ -7936,10 +8441,10 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7936
8441
|
const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absoluteMobilePush.capabilityOptions);
|
|
7937
8442
|
` : "";
|
|
7938
8443
|
const capabilityOptions = shellCapabilities.map((name, index) => `${JSON.stringify(name)}: ${name === "pushNotifications" ? "absoluteMobilePushCapability" : `absoluteDeviceCapability${index}()`}`).join(", ");
|
|
7939
|
-
const entryPath =
|
|
8444
|
+
const entryPath = join21(staging, ".absolute-mobile-entry.ts");
|
|
7940
8445
|
const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
|
|
7941
8446
|
const adapterImport = capacitor ? `import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};` : `import { createAbsoluteExpoBridgeFetch, installAbsoluteExpoWebDeviceAdapter } from ${JSON.stringify(baseAdapterModule)};`;
|
|
7942
|
-
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` :
|
|
8447
|
+
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : `installAbsoluteExpoWebDeviceAdapter(${JSON.stringify(deviceCapabilities.capabilities)});`;
|
|
7943
8448
|
let shellOptions = auth ? options : "{ createFetch: createAbsoluteExpoBridgeFetch }";
|
|
7944
8449
|
if (capacitor)
|
|
7945
8450
|
shellOptions = options;
|
|
@@ -7961,7 +8466,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
7961
8466
|
if (!build.success || build.outputs.length !== 1) {
|
|
7962
8467
|
throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
|
|
7963
8468
|
}
|
|
7964
|
-
await rename7(build.outputs[0]?.path ?? "",
|
|
8469
|
+
await rename7(build.outputs[0]?.path ?? "", join21(staging, BOOTSTRAP_FILE));
|
|
7965
8470
|
await rm6(entryPath, { force: true });
|
|
7966
8471
|
}, removePreviousBundle = async (backup, moved) => {
|
|
7967
8472
|
if (!moved)
|
|
@@ -7992,20 +8497,20 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
7992
8497
|
if (!CAPACITOR_CLIENT_FRAMEWORKS.has(page.framework)) {
|
|
7993
8498
|
throw new TypeError(`Capacitor client rendering does not yet support ${page.framework} page ${page.pageId}.`);
|
|
7994
8499
|
}
|
|
7995
|
-
const extension =
|
|
8500
|
+
const extension = extname5(page.bundlePath) || ".js";
|
|
7996
8501
|
const localBundlePath = `./pages/${page.bundleHash}${extension}`;
|
|
7997
8502
|
const source = sourceAssetPath(buildDirectory, page.bundlePath);
|
|
7998
|
-
await copyFile4(source,
|
|
8503
|
+
await copyFile4(source, join21(staging, localBundlePath));
|
|
7999
8504
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
|
|
8000
8505
|
let localStylePath;
|
|
8001
8506
|
if (page.styleBundlePath && page.styleBundleHash) {
|
|
8002
|
-
const styleExtension =
|
|
8507
|
+
const styleExtension = extname5(page.styleBundlePath) || ".css";
|
|
8003
8508
|
localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
|
|
8004
8509
|
const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
|
|
8005
|
-
await mkdir9(dirname12(
|
|
8510
|
+
await mkdir9(dirname12(join21(staging, localStylePath)), {
|
|
8006
8511
|
recursive: true
|
|
8007
8512
|
});
|
|
8008
|
-
await copyFile4(styleSource,
|
|
8513
|
+
await copyFile4(styleSource, join21(staging, localStylePath));
|
|
8009
8514
|
await copyAbsoluteClientDependencies(styleSource, buildDirectory, staging, copiedDependencies);
|
|
8010
8515
|
}
|
|
8011
8516
|
return {
|
|
@@ -8015,7 +8520,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8015
8520
|
};
|
|
8016
8521
|
}, absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
8017
8522
|
const source = await readFile10(sourcePath, "utf8");
|
|
8018
|
-
const extension =
|
|
8523
|
+
const extension = extname5(sourcePath).toLowerCase();
|
|
8019
8524
|
let scriptLoader;
|
|
8020
8525
|
if (extension === ".tsx")
|
|
8021
8526
|
scriptLoader = "tsx";
|
|
@@ -8037,9 +8542,9 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8037
8542
|
const clean = specifier.split(/[?#]/u, 1)[0] ?? specifier;
|
|
8038
8543
|
if (clean.startsWith("/"))
|
|
8039
8544
|
return [clean];
|
|
8040
|
-
const resolved =
|
|
8041
|
-
const root =
|
|
8042
|
-
const relativePath =
|
|
8545
|
+
const resolved = resolve16(dirname12(sourcePath), clean);
|
|
8546
|
+
const root = resolve16(buildDirectory);
|
|
8547
|
+
const relativePath = relative12(root, resolved).replaceAll("\\", "/");
|
|
8043
8548
|
if (relativePath === ".." || relativePath.startsWith("../")) {
|
|
8044
8549
|
throw new TypeError(`Mobile client dependency escaped the build directory: ${specifier}`);
|
|
8045
8550
|
}
|
|
@@ -8050,7 +8555,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8050
8555
|
return;
|
|
8051
8556
|
copied.add(specifier);
|
|
8052
8557
|
const source = sourceAssetPath(buildDirectory, specifier);
|
|
8053
|
-
const destination =
|
|
8558
|
+
const destination = join21(staging, specifier.replace(/^\/+/, ""));
|
|
8054
8559
|
await mkdir9(dirname12(destination), { recursive: true });
|
|
8055
8560
|
await copyFile4(source, destination);
|
|
8056
8561
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
|
|
@@ -8063,14 +8568,14 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8063
8568
|
}
|
|
8064
8569
|
const destination = options.config.bundleDirectory;
|
|
8065
8570
|
await mkdir9(dirname12(destination), { recursive: true });
|
|
8066
|
-
const staging = await mkdtemp4(
|
|
8571
|
+
const staging = await mkdtemp4(join21(dirname12(destination), `.${basename8(destination)}.stage-`));
|
|
8067
8572
|
try {
|
|
8068
|
-
const pageDirectory =
|
|
8573
|
+
const pageDirectory = join21(staging, "pages");
|
|
8069
8574
|
await mkdir9(pageDirectory, { recursive: true });
|
|
8070
8575
|
await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
|
|
8071
|
-
destination:
|
|
8072
|
-
source:
|
|
8073
|
-
})).filter(({ source }) =>
|
|
8576
|
+
destination: join21(staging, directory),
|
|
8577
|
+
source: join21(options.buildDirectory, directory)
|
|
8578
|
+
})).filter(({ source }) => existsSync10(source)).map(({ destination: assetDestination, source }) => cp3(source, assetDestination, { recursive: true })));
|
|
8074
8579
|
const copiedDependencies = new Set;
|
|
8075
8580
|
const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
|
|
8076
8581
|
const manifest = {
|
|
@@ -8103,9 +8608,9 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8103
8608
|
} : {}
|
|
8104
8609
|
};
|
|
8105
8610
|
await Promise.all([
|
|
8106
|
-
writeFile8(
|
|
8611
|
+
writeFile8(join21(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
8107
8612
|
`),
|
|
8108
|
-
writeFile8(
|
|
8613
|
+
writeFile8(join21(staging, INDEX_FILE), indexHtml(options.config.appName, options.config.productionOrigin)),
|
|
8109
8614
|
buildShellBootstrap(staging, options.auth !== undefined, options.auth !== undefined && options.sync === true, `absolutejs.${options.auth?.clientId ?? options.config.appId}.`, options.config.engine, options.deviceCapabilities, options.projectRoot)
|
|
8110
8615
|
]);
|
|
8111
8616
|
await installBundle(staging, destination);
|
|
@@ -8161,7 +8666,7 @@ import {
|
|
|
8161
8666
|
rm as rm7,
|
|
8162
8667
|
writeFile as writeFile9
|
|
8163
8668
|
} from "fs/promises";
|
|
8164
|
-
import { dirname as dirname13, join as
|
|
8669
|
+
import { dirname as dirname13, join as join22, resolve as resolvePath3 } from "path";
|
|
8165
8670
|
var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE = "artifact.json", BUNDLE_ID_PATTERN, isRecord7 = (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) => {
|
|
8166
8671
|
const identity = JSON.stringify({
|
|
8167
8672
|
currentReleaseId,
|
|
@@ -8191,16 +8696,16 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8191
8696
|
releases
|
|
8192
8697
|
};
|
|
8193
8698
|
}, writeRelease = async (root, release) => {
|
|
8194
|
-
const directory =
|
|
8195
|
-
const producerPath =
|
|
8699
|
+
const directory = join22(root, release.artifact.releaseId);
|
|
8700
|
+
const producerPath = join22(directory, release.artifact.producer.module);
|
|
8196
8701
|
await mkdir10(dirname13(producerPath), { recursive: true });
|
|
8197
8702
|
await Promise.all([
|
|
8198
|
-
writeFile9(
|
|
8703
|
+
writeFile9(join22(directory, ARTIFACT_FILE), `${JSON.stringify(release.artifact, null, "\t")}
|
|
8199
8704
|
`),
|
|
8200
8705
|
writeFile9(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
|
|
8201
8706
|
]);
|
|
8202
8707
|
}, installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
|
|
8203
|
-
const destination =
|
|
8708
|
+
const destination = join22(bundlesRoot, bundleId);
|
|
8204
8709
|
try {
|
|
8205
8710
|
await access8(destination);
|
|
8206
8711
|
return destination;
|
|
@@ -8208,7 +8713,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8208
8713
|
if (!errorHasCode2(error, "ENOENT"))
|
|
8209
8714
|
throw error;
|
|
8210
8715
|
}
|
|
8211
|
-
const staging = await mkdtemp5(
|
|
8716
|
+
const staging = await mkdtemp5(join22(bundlesRoot, ".stage-"));
|
|
8212
8717
|
try {
|
|
8213
8718
|
await Promise.all(releases.map((release) => writeRelease(staging, release)));
|
|
8214
8719
|
await rename8(staging, destination);
|
|
@@ -8237,7 +8742,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8237
8742
|
return release;
|
|
8238
8743
|
});
|
|
8239
8744
|
const root = resolvePath3(input.root);
|
|
8240
|
-
const bundlesRoot =
|
|
8745
|
+
const bundlesRoot = join22(root, BUNDLES_DIRECTORY);
|
|
8241
8746
|
await mkdir10(bundlesRoot, { recursive: true });
|
|
8242
8747
|
const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
|
|
8243
8748
|
await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
|
|
@@ -8247,8 +8752,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8247
8752
|
format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
|
|
8248
8753
|
releases: artifacts
|
|
8249
8754
|
};
|
|
8250
|
-
const pointerPath =
|
|
8251
|
-
const temporaryPointerPath =
|
|
8755
|
+
const pointerPath = join22(root, CURRENT_BUNDLE_FILE);
|
|
8756
|
+
const temporaryPointerPath = join22(root, `.current-${crypto.randomUUID()}.json`);
|
|
8252
8757
|
await writeFile9(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
|
|
8253
8758
|
`, { flag: "wx" });
|
|
8254
8759
|
await rename8(temporaryPointerPath, pointerPath);
|
|
@@ -8256,12 +8761,12 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8256
8761
|
}, readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
8257
8762
|
const resolvedRoot = resolvePath3(root);
|
|
8258
8763
|
try {
|
|
8259
|
-
const serialized = await readFile11(
|
|
8764
|
+
const serialized = await readFile11(join22(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
8260
8765
|
const parsed = JSON.parse(serialized);
|
|
8261
8766
|
const index = parseBundleIndex(parsed);
|
|
8262
|
-
const bundleRoot =
|
|
8767
|
+
const bundleRoot = join22(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
8263
8768
|
return Promise.all(index.releases.map(async (artifact) => {
|
|
8264
|
-
const producer = Bun.file(
|
|
8769
|
+
const producer = Bun.file(join22(bundleRoot, artifact.releaseId, artifact.producer.module));
|
|
8265
8770
|
await verifyAbsoluteMobileCompatibilityProducer({
|
|
8266
8771
|
artifact,
|
|
8267
8772
|
producer
|
|
@@ -8280,261 +8785,6 @@ var init_materializedBundle = __esm(() => {
|
|
|
8280
8785
|
BUNDLE_ID_PATTERN = /^amb_[a-f0-9]{64}$/;
|
|
8281
8786
|
});
|
|
8282
8787
|
|
|
8283
|
-
// src/mobile/deviceCapabilities.ts
|
|
8284
|
-
import { readFileSync as readFileSync12 } from "fs";
|
|
8285
|
-
import { extname as extname5, join as join22, relative as relative12, resolve as resolve16 } from "path";
|
|
8286
|
-
import ts4 from "typescript";
|
|
8287
|
-
var DEVICES_PACKAGE = "@absolutejs/devices", CAPACITOR_ADAPTER = "@absolutejs/devices-capacitor", SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, CAPACITOR_MODULE_PATTERN, CAPACITOR_PACKAGE_PATTERN, ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
|
|
8288
|
-
const value = JSON.parse(readFileSync12(path, "utf8"));
|
|
8289
|
-
if (!object2(value))
|
|
8290
|
-
throw new TypeError(`${path} must contain an object.`);
|
|
8291
|
-
return value;
|
|
8292
|
-
}, text = (value, field) => {
|
|
8293
|
-
if (typeof value !== "string" || value.length === 0)
|
|
8294
|
-
throw new TypeError(`${field} must be a non-empty string.`);
|
|
8295
|
-
return value;
|
|
8296
|
-
}, androidPermissions = (value, field) => {
|
|
8297
|
-
if (value === undefined)
|
|
8298
|
-
return;
|
|
8299
|
-
if (!object2(value))
|
|
8300
|
-
throw new TypeError(`${field} must be an object.`);
|
|
8301
|
-
const { permissions } = value;
|
|
8302
|
-
if (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string" && ANDROID_PERMISSION_PATTERN.test(permission)))
|
|
8303
|
-
throw new TypeError(`${field}.permissions must contain Android permission names.`);
|
|
8304
|
-
return [...permissions];
|
|
8305
|
-
}, iosPrivacyAccessedApis = (value, field) => {
|
|
8306
|
-
if (value === undefined)
|
|
8307
|
-
return;
|
|
8308
|
-
if (!object2(value))
|
|
8309
|
-
throw new TypeError(`${field} must be an object.`);
|
|
8310
|
-
const privacy = {};
|
|
8311
|
-
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
8312
|
-
const reasons = value[api];
|
|
8313
|
-
if (reasons === undefined)
|
|
8314
|
-
continue;
|
|
8315
|
-
const supported = IOS_PRIVACY_ACCESSED_API_REASONS[api];
|
|
8316
|
-
if (!Array.isArray(reasons) || reasons.length === 0 || !reasons.every((reason) => typeof reason === "string" && supported.has(reason)))
|
|
8317
|
-
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
8318
|
-
privacy[api] = [...reasons];
|
|
8319
|
-
}
|
|
8320
|
-
if (Object.keys(value).some((api) => !IOS_PRIVACY_ACCESSED_APIS.some((known) => known === api)))
|
|
8321
|
-
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
8322
|
-
return privacy;
|
|
8323
|
-
}, iosNativeRequirements = (value, field) => {
|
|
8324
|
-
if (value === undefined)
|
|
8325
|
-
return;
|
|
8326
|
-
if (!object2(value))
|
|
8327
|
-
throw new TypeError(`${field} must be an object.`);
|
|
8328
|
-
const {
|
|
8329
|
-
privacyAccessedApis,
|
|
8330
|
-
pushNotifications,
|
|
8331
|
-
systemBars,
|
|
8332
|
-
usageDescriptions
|
|
8333
|
-
} = value;
|
|
8334
|
-
if (pushNotifications !== undefined && pushNotifications !== true)
|
|
8335
|
-
throw new TypeError(`${field}.pushNotifications must be true.`);
|
|
8336
|
-
if (systemBars !== undefined && systemBars !== true)
|
|
8337
|
-
throw new TypeError(`${field}.systemBars must be true.`);
|
|
8338
|
-
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
8339
|
-
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
8340
|
-
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
8341
|
-
return {
|
|
8342
|
-
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
8343
|
-
...pushNotifications === true ? { pushNotifications: true } : {},
|
|
8344
|
-
...systemBars === true ? { systemBars: true } : {},
|
|
8345
|
-
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
8346
|
-
};
|
|
8347
|
-
}, parseProvider = (name, value) => {
|
|
8348
|
-
if (!IDENTIFIER_PATTERN.test(name))
|
|
8349
|
-
throw new TypeError("Device capability names must be identifiers.");
|
|
8350
|
-
if (!object2(value))
|
|
8351
|
-
throw new TypeError(`Device capability ${name} must be an object.`);
|
|
8352
|
-
const factory = text(value.factory, `${name}.factory`);
|
|
8353
|
-
const module = text(value.module, `${name}.module`);
|
|
8354
|
-
if (!IDENTIFIER_PATTERN.test(factory))
|
|
8355
|
-
throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
|
|
8356
|
-
if (!CAPACITOR_MODULE_PATTERN.test(module))
|
|
8357
|
-
throw new TypeError(`${name}.module must be an official devices-capacitor subpath.`);
|
|
8358
|
-
if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && CAPACITOR_PACKAGE_PATTERN.test(spec)))
|
|
8359
|
-
throw new TypeError(`${name}.packages must contain exact official Capacitor package versions.`);
|
|
8360
|
-
let native;
|
|
8361
|
-
const { native: nativeMetadata } = value;
|
|
8362
|
-
if (nativeMetadata !== undefined) {
|
|
8363
|
-
if (!object2(nativeMetadata))
|
|
8364
|
-
throw new TypeError(`${name}.native must be an object.`);
|
|
8365
|
-
const { android, ios } = nativeMetadata;
|
|
8366
|
-
const permissions = androidPermissions(android, `${name}.native.android`);
|
|
8367
|
-
const iosRequirements = iosNativeRequirements(ios, `${name}.native.ios`);
|
|
8368
|
-
native = {
|
|
8369
|
-
...permissions === undefined ? {} : { android: { permissions } },
|
|
8370
|
-
...iosRequirements === undefined ? {} : { ios: iosRequirements }
|
|
8371
|
-
};
|
|
8372
|
-
}
|
|
8373
|
-
return {
|
|
8374
|
-
factory,
|
|
8375
|
-
module,
|
|
8376
|
-
...native === undefined ? {} : { native },
|
|
8377
|
-
packages: [...value.packages]
|
|
8378
|
-
};
|
|
8379
|
-
}, absoluteDeviceNativeRequirements = (plan) => {
|
|
8380
|
-
const privacy = plan.capabilities.reduce((requirements, name) => {
|
|
8381
|
-
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
8382
|
-
const reasons = plan.providers[name]?.native?.ios?.privacyAccessedApis?.[api] ?? [];
|
|
8383
|
-
if (reasons.length === 0)
|
|
8384
|
-
continue;
|
|
8385
|
-
const current = requirements[api] ?? new Set;
|
|
8386
|
-
for (const reason of reasons)
|
|
8387
|
-
current.add(reason);
|
|
8388
|
-
requirements[api] = current;
|
|
8389
|
-
}
|
|
8390
|
-
return requirements;
|
|
8391
|
-
}, {});
|
|
8392
|
-
return {
|
|
8393
|
-
androidPermissions: [
|
|
8394
|
-
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
|
|
8395
|
-
].sort(),
|
|
8396
|
-
iosPrivacyAccessedApis: IOS_PRIVACY_ACCESSED_APIS.flatMap((api) => {
|
|
8397
|
-
const reasons = privacy[api];
|
|
8398
|
-
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
8399
|
-
}),
|
|
8400
|
-
iosPushNotifications: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.pushNotifications === true),
|
|
8401
|
-
iosSystemBars: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.systemBars === true),
|
|
8402
|
-
iosUsageDescriptions: [
|
|
8403
|
-
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
8404
|
-
].sort()
|
|
8405
|
-
};
|
|
8406
|
-
}, loadAbsoluteDeviceCapabilityProviders = (projectRoot) => {
|
|
8407
|
-
const path = join22(resolve16(projectRoot), "node_modules", CAPACITOR_ADAPTER, "package.json");
|
|
8408
|
-
const manifest = readJson(path);
|
|
8409
|
-
const { absolutejs } = manifest;
|
|
8410
|
-
const devices = object2(absolutejs) ? absolutejs.devices : undefined;
|
|
8411
|
-
if (!object2(devices) || devices.format !== 1 || devices.provider !== "capacitor" || !object2(devices.capabilities))
|
|
8412
|
-
throw new TypeError(`${CAPACITOR_ADAPTER} does not publish supported capability metadata.`);
|
|
8413
|
-
const entries = Object.entries(devices.capabilities).map(([name, provider]) => ({
|
|
8414
|
-
name,
|
|
8415
|
-
provider: parseProvider(name, provider)
|
|
8416
|
-
}));
|
|
8417
|
-
return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider }) => [name, provider]));
|
|
8418
|
-
}, isIgnored2 = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment)), importedCapabilities = (source, file) => {
|
|
8419
|
-
const names = new Set;
|
|
8420
|
-
const namespaces = new Set;
|
|
8421
|
-
const visit = (node) => {
|
|
8422
|
-
if (ts4.isImportDeclaration(node) && ts4.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
|
|
8423
|
-
const bindings = node.importClause?.namedBindings;
|
|
8424
|
-
if (bindings && ts4.isNamedImports(bindings)) {
|
|
8425
|
-
for (const element of bindings.elements)
|
|
8426
|
-
if (!element.isTypeOnly)
|
|
8427
|
-
names.add((element.propertyName ?? element.name).text);
|
|
8428
|
-
}
|
|
8429
|
-
if (bindings && ts4.isNamespaceImport(bindings))
|
|
8430
|
-
namespaces.add(bindings.name.text);
|
|
8431
|
-
}
|
|
8432
|
-
if (ts4.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && ts4.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && ts4.isNamedExports(node.exportClause)) {
|
|
8433
|
-
for (const element of node.exportClause.elements)
|
|
8434
|
-
if (!element.isTypeOnly)
|
|
8435
|
-
names.add((element.propertyName ?? element.name).text);
|
|
8436
|
-
}
|
|
8437
|
-
if (ts4.isPropertyAccessExpression(node) && ts4.isIdentifier(node.expression) && namespaces.has(node.expression.text))
|
|
8438
|
-
names.add(node.name.text);
|
|
8439
|
-
ts4.forEachChild(node, visit);
|
|
8440
|
-
};
|
|
8441
|
-
const extension = extname5(file).toLowerCase();
|
|
8442
|
-
const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
|
|
8443
|
-
for (const [index, script] of sources.entries())
|
|
8444
|
-
visit(ts4.createSourceFile(`${file}#script-${index}`, script, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TSX));
|
|
8445
|
-
return names;
|
|
8446
|
-
}, assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
|
|
8447
|
-
const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
|
|
8448
|
-
const mismatched = plan.requiredPackages.filter((spec) => {
|
|
8449
|
-
const separator = spec.lastIndexOf("@");
|
|
8450
|
-
const packageName = spec.slice(0, separator);
|
|
8451
|
-
if (missing.includes(spec))
|
|
8452
|
-
return false;
|
|
8453
|
-
try {
|
|
8454
|
-
return readJson(join22(resolve16(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
|
|
8455
|
-
} catch {
|
|
8456
|
-
return true;
|
|
8457
|
-
}
|
|
8458
|
-
});
|
|
8459
|
-
const unmet = [...missing, ...mismatched];
|
|
8460
|
-
if (unmet.length > 0)
|
|
8461
|
-
throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
|
|
8462
|
-
}, directAbsoluteProjectPackages = (projectRoot) => {
|
|
8463
|
-
const manifest = readJson(join22(resolve16(projectRoot), "package.json"));
|
|
8464
|
-
const packages = new Set;
|
|
8465
|
-
for (const field of ["dependencies", "devDependencies"]) {
|
|
8466
|
-
const dependencies = manifest[field];
|
|
8467
|
-
if (object2(dependencies))
|
|
8468
|
-
for (const name of Object.keys(dependencies))
|
|
8469
|
-
packages.add(name);
|
|
8470
|
-
}
|
|
8471
|
-
return packages;
|
|
8472
|
-
}, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
|
|
8473
|
-
const root = resolve16(projectRoot);
|
|
8474
|
-
const known = new Set(Object.keys(providers));
|
|
8475
|
-
const capabilities = new Set;
|
|
8476
|
-
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
8477
|
-
const portable = relative12(root, resolve16(root, path)).replaceAll("\\", "/");
|
|
8478
|
-
if (isIgnored2(portable))
|
|
8479
|
-
continue;
|
|
8480
|
-
const source = readFileSync12(resolve16(root, portable), "utf8");
|
|
8481
|
-
for (const name of importedCapabilities(source, portable))
|
|
8482
|
-
if (known.has(name))
|
|
8483
|
-
capabilities.add(name);
|
|
8484
|
-
}
|
|
8485
|
-
return [...capabilities].sort();
|
|
8486
|
-
}, missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
|
|
8487
|
-
const packageName = spec.slice(0, spec.lastIndexOf("@"));
|
|
8488
|
-
return !directPackages.has(packageName);
|
|
8489
|
-
}), resolveAbsoluteDeviceCapabilityPlan = (projectRoot) => {
|
|
8490
|
-
const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot);
|
|
8491
|
-
const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
|
|
8492
|
-
const providers = {};
|
|
8493
|
-
for (const name of capabilities) {
|
|
8494
|
-
const provider = allProviders[name];
|
|
8495
|
-
if (provider)
|
|
8496
|
-
providers[name] = provider;
|
|
8497
|
-
}
|
|
8498
|
-
return {
|
|
8499
|
-
capabilities,
|
|
8500
|
-
providers,
|
|
8501
|
-
requiredPackages: [
|
|
8502
|
-
...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
|
|
8503
|
-
].sort()
|
|
8504
|
-
};
|
|
8505
|
-
};
|
|
8506
|
-
var init_deviceCapabilities = __esm(() => {
|
|
8507
|
-
SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
|
|
8508
|
-
IGNORED_DIRECTORIES = new Set([
|
|
8509
|
-
".absolutejs",
|
|
8510
|
-
".git",
|
|
8511
|
-
".test-builds",
|
|
8512
|
-
".test-shards",
|
|
8513
|
-
"build",
|
|
8514
|
-
"dist",
|
|
8515
|
-
"node_modules",
|
|
8516
|
-
"test",
|
|
8517
|
-
"tests"
|
|
8518
|
-
]);
|
|
8519
|
-
IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
|
|
8520
|
-
CAPACITOR_MODULE_PATTERN = /^@absolutejs\/devices-capacitor\/[a-z][a-z0-9-]*$/u;
|
|
8521
|
-
CAPACITOR_PACKAGE_PATTERN = /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u;
|
|
8522
|
-
ANDROID_PERMISSION_PATTERN = /^android\.permission\.[A-Z][A-Z0-9_]*$/u;
|
|
8523
|
-
IOS_USAGE_DESCRIPTIONS = new Set([
|
|
8524
|
-
"camera",
|
|
8525
|
-
"location-always",
|
|
8526
|
-
"location-when-in-use",
|
|
8527
|
-
"photo-library",
|
|
8528
|
-
"photo-library-add"
|
|
8529
|
-
]);
|
|
8530
|
-
IOS_PRIVACY_ACCESSED_API_REASONS = {
|
|
8531
|
-
NSPrivacyAccessedAPICategoryFileTimestamp: new Set(["C617.1"])
|
|
8532
|
-
};
|
|
8533
|
-
IOS_PRIVACY_ACCESSED_APIS = [
|
|
8534
|
-
"NSPrivacyAccessedAPICategoryFileTimestamp"
|
|
8535
|
-
];
|
|
8536
|
-
});
|
|
8537
|
-
|
|
8538
8788
|
// src/mobile/buildPipeline.ts
|
|
8539
8789
|
import { readFile as readFile12 } from "fs/promises";
|
|
8540
8790
|
import { join as join23, resolve as resolve17 } from "path";
|
|
@@ -8606,11 +8856,8 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
|
|
|
8606
8856
|
const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
|
|
8607
8857
|
const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
|
|
8608
8858
|
const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
|
|
8609
|
-
const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
|
|
8859
|
+
const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot, mobile.engine);
|
|
8610
8860
|
const usesPush = deviceCapabilities.capabilities.includes("pushNotifications");
|
|
8611
|
-
if (mobile.engine === "expo" && deviceCapabilities.capabilities.some((capability) => capability !== "haptics")) {
|
|
8612
|
-
throw new TypeError("Experimental Expo builds currently bridge only @absolutejs/devices haptics. Other detected device capabilities require their Expo adapters.");
|
|
8613
|
-
}
|
|
8614
8861
|
if (usesPush && !auth)
|
|
8615
8862
|
throw new TypeError("Portable push notifications require @absolutejs/auth so provider tokens can be registered without exposing identity controls to page code.");
|
|
8616
8863
|
if (usesPush && !loaded.app.routes.some((route) => route.path === "/auth/push" || route.path === "/auth/mobile/push"))
|
|
@@ -8663,10 +8910,10 @@ var init_buildPipeline = __esm(() => {
|
|
|
8663
8910
|
});
|
|
8664
8911
|
|
|
8665
8912
|
// src/mobile/routeMetadataTransform.ts
|
|
8666
|
-
import { existsSync as
|
|
8913
|
+
import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
|
|
8667
8914
|
import { dirname as dirname14, extname as extname6, relative as relative13, resolve as resolve18 } from "path";
|
|
8668
8915
|
import ts5 from "typescript";
|
|
8669
|
-
var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts5.findConfigFile(dirname14(entry),
|
|
8916
|
+
var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts5.findConfigFile(dirname14(entry), existsSync11, "tsconfig.json") ?? ts5.findConfigFile(projectRoot, existsSync11, "tsconfig.json"), createProgram = (entry, projectRoot) => {
|
|
8670
8917
|
const configPath2 = findTsconfig(entry, projectRoot);
|
|
8671
8918
|
if (!configPath2) {
|
|
8672
8919
|
return ts5.createProgram([entry], {
|
|
@@ -9934,7 +10181,7 @@ var init_rewriteImports = __esm(() => {
|
|
|
9934
10181
|
|
|
9935
10182
|
// src/cli/scripts/start.ts
|
|
9936
10183
|
var {env: env2 } = globalThis.Bun;
|
|
9937
|
-
import { existsSync as
|
|
10184
|
+
import { existsSync as existsSync12, readFileSync as readFileSync15, rmSync as rmSync4 } from "fs";
|
|
9938
10185
|
import { basename as basename9, join as join26, resolve as resolve21 } from "path";
|
|
9939
10186
|
var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, resolvePackageVersion = (candidates) => {
|
|
9940
10187
|
for (const candidate of candidates) {
|
|
@@ -9992,7 +10239,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
9992
10239
|
resolve21(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
|
|
9993
10240
|
];
|
|
9994
10241
|
for (const candidate of candidates) {
|
|
9995
|
-
if (
|
|
10242
|
+
if (existsSync12(candidate))
|
|
9996
10243
|
return candidate;
|
|
9997
10244
|
}
|
|
9998
10245
|
return resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
|
|
@@ -10029,7 +10276,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10029
10276
|
serverEntry,
|
|
10030
10277
|
totalDuration
|
|
10031
10278
|
}) => {
|
|
10032
|
-
const usesDocker =
|
|
10279
|
+
const usesDocker = existsSync12(resolve21(COMPOSE_PATH));
|
|
10033
10280
|
const scripts = usesDocker ? await readDbScripts() : null;
|
|
10034
10281
|
if (scripts)
|
|
10035
10282
|
await startDatabase(scripts);
|
|
@@ -10140,7 +10387,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10140
10387
|
].filter((val) => Boolean(val));
|
|
10141
10388
|
const outputPath = resolve21(resolvedOutdir, `${entryName}.js`);
|
|
10142
10389
|
if (options.prebuilt) {
|
|
10143
|
-
if (!
|
|
10390
|
+
if (!existsSync12(outputPath)) {
|
|
10144
10391
|
throw new Error(`Prepared production server not found: ${outputPath}`);
|
|
10145
10392
|
}
|
|
10146
10393
|
return runPreparedServer({
|
|
@@ -10267,11 +10514,11 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10267
10514
|
if (!serverBundle.success) {
|
|
10268
10515
|
handleBundleFailure(serverBundle, bundleStart, serverEntry);
|
|
10269
10516
|
}
|
|
10270
|
-
if (!
|
|
10517
|
+
if (!existsSync12(outputPath)) {
|
|
10271
10518
|
console.error(cliTag2("\x1B[31m", `Expected output not found: ${outputPath}`));
|
|
10272
10519
|
process.exit(1);
|
|
10273
10520
|
}
|
|
10274
|
-
if (
|
|
10521
|
+
if (existsSync12(resolve21(resolvedOutdir, "angular", "vendor", "server"))) {
|
|
10275
10522
|
const { readdirSync: readdirSync2 } = await import("fs");
|
|
10276
10523
|
const vendorDir = resolve21(resolvedOutdir, "angular", "vendor", "server");
|
|
10277
10524
|
const vendorEntries = readdirSync2(vendorDir).filter((fileName) => fileName.endsWith(".js"));
|
|
@@ -10470,11 +10717,11 @@ var exports_build = {};
|
|
|
10470
10717
|
__export(exports_build, {
|
|
10471
10718
|
build: () => build
|
|
10472
10719
|
});
|
|
10473
|
-
import { existsSync as
|
|
10720
|
+
import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync as readFileSync17 } from "fs";
|
|
10474
10721
|
import { join as join27, resolve as resolve23 } from "path";
|
|
10475
10722
|
var PROFILE_TOP = 15, PROFILE_COL = 8, FRAMEWORK_KEYS, cliTag3 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, printProfile = (buildDir) => {
|
|
10476
10723
|
const traceDir = join27(buildDir, ".absolute-trace");
|
|
10477
|
-
if (!
|
|
10724
|
+
if (!existsSync14(traceDir))
|
|
10478
10725
|
return;
|
|
10479
10726
|
const files = readdirSync3(traceDir).filter((file) => file.endsWith(".json")).sort();
|
|
10480
10727
|
const latest = files[files.length - 1];
|
|
@@ -10573,7 +10820,7 @@ import {
|
|
|
10573
10820
|
verify
|
|
10574
10821
|
} from "crypto";
|
|
10575
10822
|
import {
|
|
10576
|
-
existsSync as
|
|
10823
|
+
existsSync as existsSync15,
|
|
10577
10824
|
lstatSync,
|
|
10578
10825
|
mkdirSync as mkdirSync8,
|
|
10579
10826
|
mkdtempSync,
|
|
@@ -10773,7 +11020,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
|
|
|
10773
11020
|
const cwd = options.cwd ?? process.cwd();
|
|
10774
11021
|
const proofLocation = options.proofLocation ?? DEFAULT_PROOF_LOCATION;
|
|
10775
11022
|
const path = resolve24(cwd, proofLocation);
|
|
10776
|
-
if (!
|
|
11023
|
+
if (!existsSync15(path))
|
|
10777
11024
|
return { reason: `missing lint proof: ${proofLocation}`, valid: false };
|
|
10778
11025
|
let proof;
|
|
10779
11026
|
try {
|
|
@@ -10890,7 +11137,7 @@ var init_lintProof = __esm(() => {
|
|
|
10890
11137
|
// src/build/scanConventions.ts
|
|
10891
11138
|
import { basename as basename10 } from "path";
|
|
10892
11139
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
10893
|
-
import { existsSync as
|
|
11140
|
+
import { existsSync as existsSync16 } from "fs";
|
|
10894
11141
|
var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
|
|
10895
11142
|
const fileName = basename10(file);
|
|
10896
11143
|
const match = CONVENTION_RE.exec(fileName);
|
|
@@ -10915,7 +11162,7 @@ var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
|
|
|
10915
11162
|
else if (kind === "loading")
|
|
10916
11163
|
pages[pageName].loading = file;
|
|
10917
11164
|
}, scanConventions = async (pagesDir, pattern) => {
|
|
10918
|
-
if (!
|
|
11165
|
+
if (!existsSync16(pagesDir)) {
|
|
10919
11166
|
const pageFiles2 = [];
|
|
10920
11167
|
return { conventions: undefined, pageFiles: pageFiles2 };
|
|
10921
11168
|
}
|
|
@@ -10942,7 +11189,7 @@ var exports_ls = {};
|
|
|
10942
11189
|
__export(exports_ls, {
|
|
10943
11190
|
runLs: () => runLs
|
|
10944
11191
|
});
|
|
10945
|
-
import { existsSync as
|
|
11192
|
+
import { existsSync as existsSync17, readFileSync as readFileSync19, statSync } from "fs";
|
|
10946
11193
|
import { basename as basename11, extname as extname7, join as join28, relative as relative15 } from "path";
|
|
10947
11194
|
var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELDS, readStringField = (source, key) => {
|
|
10948
11195
|
const value = Reflect.get(source, key);
|
|
@@ -10993,10 +11240,10 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
|
|
|
10993
11240
|
return pages ? [{ label, pages: sortPages(pages) }] : [];
|
|
10994
11241
|
});
|
|
10995
11242
|
}, resolveDiskPath = (buildDir, value) => {
|
|
10996
|
-
if (
|
|
11243
|
+
if (existsSync17(value))
|
|
10997
11244
|
return value;
|
|
10998
11245
|
const underBuild = join28(buildDir, value);
|
|
10999
|
-
if (
|
|
11246
|
+
if (existsSync17(underBuild))
|
|
11000
11247
|
return underBuild;
|
|
11001
11248
|
return join28(process.cwd(), value);
|
|
11002
11249
|
}, fileSize = (diskPath) => {
|
|
@@ -11124,7 +11371,7 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
|
|
|
11124
11371
|
}
|
|
11125
11372
|
const sizesDir = resolveSizesDir(args, candidates);
|
|
11126
11373
|
const manifestPath = join28(sizesDir, "manifest.json");
|
|
11127
|
-
if (!
|
|
11374
|
+
if (!existsSync17(manifestPath)) {
|
|
11128
11375
|
printDim(`No build at ${relativeOrSelf(manifestPath)}. Run \`absolute build\` first, or pass \`--outdir <dir>\`.`);
|
|
11129
11376
|
return;
|
|
11130
11377
|
}
|
|
@@ -11974,7 +12221,7 @@ var exports_heapDiff = {};
|
|
|
11974
12221
|
__export(exports_heapDiff, {
|
|
11975
12222
|
runHeapDiff: () => runHeapDiff
|
|
11976
12223
|
});
|
|
11977
|
-
import { existsSync as
|
|
12224
|
+
import { existsSync as existsSync18, readFileSync as readFileSync20 } from "fs";
|
|
11978
12225
|
var TOP = 15, STRING_TYPES, aggregate = (path) => {
|
|
11979
12226
|
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
11980
12227
|
const { nodes, strings } = data;
|
|
@@ -12005,7 +12252,7 @@ var TOP = 15, STRING_TYPES, aggregate = (path) => {
|
|
|
12005
12252
|
return;
|
|
12006
12253
|
}
|
|
12007
12254
|
for (const path of [beforePath, afterPath]) {
|
|
12008
|
-
if (
|
|
12255
|
+
if (existsSync18(path))
|
|
12009
12256
|
continue;
|
|
12010
12257
|
process.stdout.write(`${colors.red}No such file: ${path}${colors.reset}
|
|
12011
12258
|
`);
|
|
@@ -12126,7 +12373,7 @@ var isRecord9 = (value) => typeof value === "object" && value !== null && !Array
|
|
|
12126
12373
|
// src/cli/config/schema/fromType.ts
|
|
12127
12374
|
import ts6 from "typescript";
|
|
12128
12375
|
import {
|
|
12129
|
-
existsSync as
|
|
12376
|
+
existsSync as existsSync19,
|
|
12130
12377
|
mkdirSync as mkdirSync9,
|
|
12131
12378
|
readFileSync as readFileSync21,
|
|
12132
12379
|
statSync as statSync2,
|
|
@@ -12321,7 +12568,7 @@ export { value };
|
|
|
12321
12568
|
const cached = cache.get(cacheKey);
|
|
12322
12569
|
if (cached)
|
|
12323
12570
|
return cached;
|
|
12324
|
-
const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) &&
|
|
12571
|
+
const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) && existsSync19(resolve25(cwd, "types/index.ts"));
|
|
12325
12572
|
const signature = cacheSignature(cwd, typeName, local, specifier);
|
|
12326
12573
|
const fromDisk = readDiskCache(cwd, typeName, signature, specifier);
|
|
12327
12574
|
if (fromDisk) {
|
|
@@ -12349,16 +12596,16 @@ var init_fromType = __esm(() => {
|
|
|
12349
12596
|
|
|
12350
12597
|
// src/cli/config/absolute/resolveAbsoluteConfig.ts
|
|
12351
12598
|
import ts7 from "typescript";
|
|
12352
|
-
import { existsSync as
|
|
12599
|
+
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "fs";
|
|
12353
12600
|
import { resolve as resolve26 } from "path";
|
|
12354
12601
|
var CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath = (cwd, override) => {
|
|
12355
12602
|
if (override) {
|
|
12356
12603
|
const resolved = resolve26(cwd, override);
|
|
12357
|
-
return
|
|
12604
|
+
return existsSync20(resolved) ? resolved : null;
|
|
12358
12605
|
}
|
|
12359
12606
|
for (const name of CONFIG_CANDIDATES2) {
|
|
12360
12607
|
const candidate = resolve26(cwd, name);
|
|
12361
|
-
if (
|
|
12608
|
+
if (existsSync20(candidate))
|
|
12362
12609
|
return candidate;
|
|
12363
12610
|
}
|
|
12364
12611
|
return null;
|
|
@@ -12682,7 +12929,7 @@ var emptyOutcome = () => ({
|
|
|
12682
12929
|
|
|
12683
12930
|
// src/cli/generate/routeWiring.ts
|
|
12684
12931
|
import ts8 from "typescript";
|
|
12685
|
-
import { existsSync as
|
|
12932
|
+
import { existsSync as existsSync21, readFileSync as readFileSync23, readdirSync as readdirSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
12686
12933
|
import { dirname as dirname18, join as join30 } from "path";
|
|
12687
12934
|
var DEFAULT_SEPARATOR = `
|
|
12688
12935
|
`, BOUNDARY_USE, applyEdits = (text2, edits) => {
|
|
@@ -12831,13 +13078,13 @@ ${newLines.join(`
|
|
|
12831
13078
|
return lines.join(`
|
|
12832
13079
|
`);
|
|
12833
13080
|
}, hasChain = (path) => {
|
|
12834
|
-
if (!
|
|
13081
|
+
if (!existsSync21(path))
|
|
12835
13082
|
return false;
|
|
12836
13083
|
const sourceFile = parse2(path, readFileSync23(path, "utf-8"));
|
|
12837
13084
|
const found = findElysiaNew(sourceFile);
|
|
12838
13085
|
return found !== null;
|
|
12839
13086
|
}, firstChainFile = (pluginsDir) => {
|
|
12840
|
-
if (!
|
|
13087
|
+
if (!existsSync21(pluginsDir))
|
|
12841
13088
|
return null;
|
|
12842
13089
|
for (const name of readdirSync4(pluginsDir)) {
|
|
12843
13090
|
if (!name.endsWith(".ts"))
|
|
@@ -12940,7 +13187,7 @@ var init_routeWiring = __esm(() => {
|
|
|
12940
13187
|
});
|
|
12941
13188
|
|
|
12942
13189
|
// src/cli/generate/generateApi.ts
|
|
12943
|
-
import { existsSync as
|
|
13190
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
12944
13191
|
import { dirname as dirname19, join as join31 } from "path";
|
|
12945
13192
|
var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
|
|
12946
13193
|
|
|
@@ -12955,7 +13202,7 @@ export const ${pluginName} = new Elysia()
|
|
|
12955
13202
|
const outcome = { ...emptyOutcome(), route: base };
|
|
12956
13203
|
const pluginsDir = join31(dirname19(project.serverEntry), "plugins");
|
|
12957
13204
|
const fileAbs = join31(pluginsDir, `${pluginName}.ts`);
|
|
12958
|
-
if (
|
|
13205
|
+
if (existsSync22(fileAbs)) {
|
|
12959
13206
|
outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
|
|
12960
13207
|
return outcome;
|
|
12961
13208
|
}
|
|
@@ -13028,7 +13275,7 @@ var init_componentTemplates = __esm(() => {
|
|
|
13028
13275
|
});
|
|
13029
13276
|
|
|
13030
13277
|
// src/cli/generate/generateComponent.ts
|
|
13031
|
-
import { existsSync as
|
|
13278
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
|
|
13032
13279
|
import { dirname as dirname20, join as join32 } from "path";
|
|
13033
13280
|
var generateComponent = (project, framework, rawName) => {
|
|
13034
13281
|
const def = frameworks6[framework];
|
|
@@ -13041,7 +13288,7 @@ var generateComponent = (project, framework, rawName) => {
|
|
|
13041
13288
|
return outcome;
|
|
13042
13289
|
}
|
|
13043
13290
|
const fileAbs = join32(frameworkDir, "components", def.componentFile({ kebab, pascal }));
|
|
13044
|
-
if (
|
|
13291
|
+
if (existsSync23(fileAbs)) {
|
|
13045
13292
|
outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
|
|
13046
13293
|
return outcome;
|
|
13047
13294
|
}
|
|
@@ -13061,7 +13308,7 @@ var init_generateComponent = __esm(() => {
|
|
|
13061
13308
|
|
|
13062
13309
|
// src/cli/generate/cssStrategy.ts
|
|
13063
13310
|
import ts9 from "typescript";
|
|
13064
|
-
import { existsSync as
|
|
13311
|
+
import { existsSync as existsSync24 } from "fs";
|
|
13065
13312
|
import { join as join33 } from "path";
|
|
13066
13313
|
var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
13067
13314
|
margin: 0 auto;
|
|
@@ -13109,7 +13356,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
|
13109
13356
|
return {
|
|
13110
13357
|
assetKey: sharedKey,
|
|
13111
13358
|
contents: DEFAULT_CSS,
|
|
13112
|
-
create: !
|
|
13359
|
+
create: !existsSync24(cssFileAbs2),
|
|
13113
13360
|
cssFileAbs: cssFileAbs2,
|
|
13114
13361
|
shared: true
|
|
13115
13362
|
};
|
|
@@ -13118,7 +13365,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
|
13118
13365
|
return {
|
|
13119
13366
|
assetKey: `${pascal}${CSS_SUFFIX}`,
|
|
13120
13367
|
contents: DEFAULT_CSS,
|
|
13121
|
-
create: !
|
|
13368
|
+
create: !existsSync24(cssFileAbs),
|
|
13122
13369
|
cssFileAbs,
|
|
13123
13370
|
shared: false
|
|
13124
13371
|
};
|
|
@@ -13127,7 +13374,7 @@ var init_cssStrategy = () => {};
|
|
|
13127
13374
|
|
|
13128
13375
|
// src/cli/generate/navData.ts
|
|
13129
13376
|
import ts10 from "typescript";
|
|
13130
|
-
import { existsSync as
|
|
13377
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "fs";
|
|
13131
13378
|
import { dirname as dirname21 } from "path";
|
|
13132
13379
|
var NAV_DATA_TEMPLATE = `type NavItem = {
|
|
13133
13380
|
href: string;
|
|
@@ -13166,7 +13413,7 @@ export const navData: NavItem[] = [];
|
|
|
13166
13413
|
}
|
|
13167
13414
|
return items;
|
|
13168
13415
|
}, readNavItems = (navDataPath) => {
|
|
13169
|
-
if (!
|
|
13416
|
+
if (!existsSync25(navDataPath))
|
|
13170
13417
|
return [];
|
|
13171
13418
|
const text2 = readFileSync24(navDataPath, "utf-8");
|
|
13172
13419
|
const sourceFile = ts10.createSourceFile(navDataPath, text2, ts10.ScriptTarget.Latest, true);
|
|
@@ -13203,7 +13450,7 @@ ${indentOf(text2, array.getStart(sourceFile))}`;
|
|
|
13203
13450
|
${indent}${entry}`;
|
|
13204
13451
|
return text2.slice(0, insertAt) + insertion + text2.slice(insertAt);
|
|
13205
13452
|
}, upsertNavItem = (navDataPath, item) => {
|
|
13206
|
-
const created = !
|
|
13453
|
+
const created = !existsSync25(navDataPath);
|
|
13207
13454
|
if (created) {
|
|
13208
13455
|
mkdirSync12(dirname21(navDataPath), { recursive: true });
|
|
13209
13456
|
writeFileSync12(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
|
|
@@ -13369,7 +13616,7 @@ var init_pageTemplates = __esm(() => {
|
|
|
13369
13616
|
|
|
13370
13617
|
// src/cli/generate/generatePage.ts
|
|
13371
13618
|
import {
|
|
13372
|
-
existsSync as
|
|
13619
|
+
existsSync as existsSync26,
|
|
13373
13620
|
mkdirSync as mkdirSync13,
|
|
13374
13621
|
readFileSync as readFileSync25,
|
|
13375
13622
|
readdirSync as readdirSync5,
|
|
@@ -13382,7 +13629,7 @@ var writeNew = (path, contents) => {
|
|
|
13382
13629
|
}, toHref = (fromDir, toFile) => {
|
|
13383
13630
|
const rel = relative17(fromDir, toFile).split("\\").join("/");
|
|
13384
13631
|
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
13385
|
-
}, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join34(dir, "pages") : null).filter((pagesDir) => pagesDir !== null &&
|
|
13632
|
+
}, staticPageFiles = (project) => ["html", "htmx"].map((key) => project.frameworkDirs[key]).map((dir) => dir ? join34(dir, "pages") : null).filter((pagesDir) => pagesDir !== null && existsSync26(pagesDir)).flatMap((pagesDir) => readdirSync5(pagesDir).filter((name) => name.endsWith(".html")).map((name) => join34(pagesDir, name))), resyncPage = (file, items) => {
|
|
13386
13633
|
const html = readFileSync25(file, "utf-8");
|
|
13387
13634
|
const synced = syncStaticNav(html, items);
|
|
13388
13635
|
if (synced === null || synced === html)
|
|
@@ -13411,7 +13658,7 @@ var writeNew = (path, contents) => {
|
|
|
13411
13658
|
return outcome;
|
|
13412
13659
|
}
|
|
13413
13660
|
const pageFileAbs = join34(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
|
|
13414
|
-
if (
|
|
13661
|
+
if (existsSync26(pageFileAbs)) {
|
|
13415
13662
|
outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
|
|
13416
13663
|
return outcome;
|
|
13417
13664
|
}
|
|
@@ -13797,11 +14044,11 @@ var init_catalog = __esm(() => {
|
|
|
13797
14044
|
});
|
|
13798
14045
|
|
|
13799
14046
|
// src/cli/integrations/addPlugin.ts
|
|
13800
|
-
import { existsSync as
|
|
14047
|
+
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "fs";
|
|
13801
14048
|
import { join as join35 } from "path";
|
|
13802
14049
|
var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
|
|
13803
14050
|
const path = join35(cwd, "package.json");
|
|
13804
|
-
if (!
|
|
14051
|
+
if (!existsSync27(path))
|
|
13805
14052
|
return null;
|
|
13806
14053
|
try {
|
|
13807
14054
|
const parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
@@ -14296,16 +14543,16 @@ var init_authCatalog = __esm(() => {
|
|
|
14296
14543
|
|
|
14297
14544
|
// src/cli/config/auth/resolveAuthSettings.ts
|
|
14298
14545
|
import ts12 from "typescript";
|
|
14299
|
-
import { existsSync as
|
|
14546
|
+
import { existsSync as existsSync28, readFileSync as readFileSync28 } from "fs";
|
|
14300
14547
|
import { resolve as resolve28 } from "path";
|
|
14301
14548
|
var AUTH_PACKAGE = "@absolutejs/auth", CONFIG_CANDIDATES3, findAuthSettingsPath = (cwd, override) => {
|
|
14302
14549
|
if (override) {
|
|
14303
14550
|
const resolved = resolve28(cwd, override);
|
|
14304
|
-
return
|
|
14551
|
+
return existsSync28(resolved) ? resolved : null;
|
|
14305
14552
|
}
|
|
14306
14553
|
for (const name of CONFIG_CANDIDATES3) {
|
|
14307
14554
|
const candidate = resolve28(cwd, name);
|
|
14308
|
-
if (
|
|
14555
|
+
if (existsSync28(candidate))
|
|
14309
14556
|
return candidate;
|
|
14310
14557
|
}
|
|
14311
14558
|
return null;
|
|
@@ -14401,10 +14648,10 @@ var init_resolveAuthSettings = __esm(() => {
|
|
|
14401
14648
|
|
|
14402
14649
|
// src/cli/config/auth/resolveAuthState.ts
|
|
14403
14650
|
import ts13 from "typescript";
|
|
14404
|
-
import { existsSync as
|
|
14651
|
+
import { existsSync as existsSync29, readdirSync as readdirSync6, readFileSync as readFileSync29 } from "fs";
|
|
14405
14652
|
import { join as join36, relative as relative19, resolve as resolve29 } from "path";
|
|
14406
14653
|
var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson2 = (path) => {
|
|
14407
|
-
if (!
|
|
14654
|
+
if (!existsSync29(path))
|
|
14408
14655
|
return null;
|
|
14409
14656
|
try {
|
|
14410
14657
|
const parsed = JSON.parse(readFileSync29(path, "utf-8"));
|
|
@@ -14533,7 +14780,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
|
|
|
14533
14780
|
scaffoldable: isScaffoldableFeature(feature.id)
|
|
14534
14781
|
})), resolveAuthState = (cwd) => {
|
|
14535
14782
|
const installedVersion = installedVersionFor(cwd);
|
|
14536
|
-
const root =
|
|
14783
|
+
const root = existsSync29(join36(cwd, "src")) ? join36(cwd, "src") : cwd;
|
|
14537
14784
|
let match = null;
|
|
14538
14785
|
let setupPath = null;
|
|
14539
14786
|
for (const file of candidateFiles(root)) {
|
|
@@ -14578,7 +14825,7 @@ var init_resolveAuthState = __esm(() => {
|
|
|
14578
14825
|
});
|
|
14579
14826
|
|
|
14580
14827
|
// src/cli/config/auth/scaffoldAuthFeature.ts
|
|
14581
|
-
import { existsSync as
|
|
14828
|
+
import { existsSync as existsSync30, writeFileSync as writeFileSync15 } from "fs";
|
|
14582
14829
|
import { dirname as dirname23, join as join37, relative as relative20, resolve as resolve30 } from "path";
|
|
14583
14830
|
var renderScaffold = (scaffold) => {
|
|
14584
14831
|
const importNames = [...scaffold.imports, `type ${scaffold.typeName}`];
|
|
@@ -14606,7 +14853,7 @@ ${body}
|
|
|
14606
14853
|
if (setupPath)
|
|
14607
14854
|
return dirname23(resolve30(cwd, setupPath));
|
|
14608
14855
|
const src = join37(cwd, "src");
|
|
14609
|
-
return
|
|
14856
|
+
return existsSync30(src) ? src : cwd;
|
|
14610
14857
|
}, spreadFor = (scaffold) => `import { ${scaffold.exportName} } from './${scaffold.exportName}';
|
|
14611
14858
|
// add to your auth() call:
|
|
14612
14859
|
${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
|
|
@@ -14621,7 +14868,7 @@ ${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
|
|
|
14621
14868
|
return failure2(`Unknown auth feature "${id}".`);
|
|
14622
14869
|
const filePath = join37(targetDir(cwd), `${scaffold.exportName}.ts`);
|
|
14623
14870
|
const relPath = relative20(cwd, filePath);
|
|
14624
|
-
if (
|
|
14871
|
+
if (existsSync30(filePath)) {
|
|
14625
14872
|
return {
|
|
14626
14873
|
created: null,
|
|
14627
14874
|
installed: false,
|
|
@@ -14648,13 +14895,13 @@ var init_scaffoldAuthFeature = __esm(() => {
|
|
|
14648
14895
|
});
|
|
14649
14896
|
|
|
14650
14897
|
// src/cli/htmx/install.ts
|
|
14651
|
-
import { existsSync as
|
|
14898
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync14, readFileSync as readFileSync30, writeFileSync as writeFileSync16 } from "fs";
|
|
14652
14899
|
import { join as join38 } from "path";
|
|
14653
14900
|
var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
|
|
14654
14901
|
join38(import.meta.dir, "htmx.min.js"),
|
|
14655
14902
|
join38(import.meta.dir, "htmx", "htmx.min.js"),
|
|
14656
14903
|
join38(import.meta.dir, "..", "htmx", "htmx.min.js")
|
|
14657
|
-
].find((path) =>
|
|
14904
|
+
].find((path) => existsSync31(path)) ?? null, detectHtmxVersion = (content) => {
|
|
14658
14905
|
const match = content.match(/version:"([0-9.]+)"/);
|
|
14659
14906
|
return match ? match[1] : null;
|
|
14660
14907
|
}, fetchHtmx = async (version2) => {
|
|
@@ -14666,7 +14913,7 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
|
|
|
14666
14913
|
return response.text();
|
|
14667
14914
|
}, installedHtmxVersion = (htmxDir) => {
|
|
14668
14915
|
const file = join38(htmxDir, "htmx.min.js");
|
|
14669
|
-
if (!
|
|
14916
|
+
if (!existsSync31(file))
|
|
14670
14917
|
return null;
|
|
14671
14918
|
return detectHtmxVersion(readFileSync30(file, "utf-8"));
|
|
14672
14919
|
}, readVendoredHtmx = () => {
|
|
@@ -14834,7 +15081,7 @@ var exports_analyze = {};
|
|
|
14834
15081
|
__export(exports_analyze, {
|
|
14835
15082
|
runAnalyze: () => runAnalyze
|
|
14836
15083
|
});
|
|
14837
|
-
import { existsSync as
|
|
15084
|
+
import { existsSync as existsSync32, readFileSync as readFileSync31, statSync as statSync3, writeFileSync as writeFileSync17 } from "fs";
|
|
14838
15085
|
import { join as join40, resolve as resolve31 } from "path";
|
|
14839
15086
|
var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_WIDTH = 16, SIZE_WIDTH = 12, CHANGE_WIDTH = 10, CATEGORY_ORDER, categoryOf = (key) => {
|
|
14840
15087
|
if (key.startsWith("Island"))
|
|
@@ -14856,7 +15103,7 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
|
|
|
14856
15103
|
}
|
|
14857
15104
|
}, readSizes = (manifestDir) => {
|
|
14858
15105
|
const manifestPath = join40(manifestDir, "manifest.json");
|
|
14859
|
-
if (!
|
|
15106
|
+
if (!existsSync32(manifestPath))
|
|
14860
15107
|
return null;
|
|
14861
15108
|
const manifest = JSON.parse(readFileSync31(manifestPath, "utf-8"));
|
|
14862
15109
|
const sizes = {};
|
|
@@ -14866,7 +15113,7 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
|
|
|
14866
15113
|
return sizes;
|
|
14867
15114
|
}, readBaseline = (cwd) => {
|
|
14868
15115
|
const path = join40(cwd, BASELINE_FILE);
|
|
14869
|
-
if (!
|
|
15116
|
+
if (!existsSync32(path))
|
|
14870
15117
|
return null;
|
|
14871
15118
|
try {
|
|
14872
15119
|
const parsed = JSON.parse(readFileSync31(path, "utf-8"));
|
|
@@ -15200,7 +15447,7 @@ var exports_remove = {};
|
|
|
15200
15447
|
__export(exports_remove, {
|
|
15201
15448
|
runRemove: () => runRemove
|
|
15202
15449
|
});
|
|
15203
|
-
import { existsSync as
|
|
15450
|
+
import { existsSync as existsSync33, readFileSync as readFileSync32 } from "fs";
|
|
15204
15451
|
import { relative as relative22 } from "path";
|
|
15205
15452
|
var write3 = (text2) => process.stdout.write(`${text2}
|
|
15206
15453
|
`), fail3 = (message) => {
|
|
@@ -15211,7 +15458,7 @@ var write3 = (text2) => process.stdout.write(`${text2}
|
|
|
15211
15458
|
const candidates = [findRoutingFile(serverEntry), serverEntry];
|
|
15212
15459
|
const seen = new Set;
|
|
15213
15460
|
return candidates.filter((file) => {
|
|
15214
|
-
if (file === null || seen.has(file) || !
|
|
15461
|
+
if (file === null || seen.has(file) || !existsSync33(file))
|
|
15215
15462
|
return false;
|
|
15216
15463
|
seen.add(file);
|
|
15217
15464
|
return readFileSync32(file, "utf-8").includes(handler);
|
|
@@ -15341,10 +15588,10 @@ __export(exports_env, {
|
|
|
15341
15588
|
runEnv: () => runEnv,
|
|
15342
15589
|
scanEnvUsage: () => scanEnvUsage
|
|
15343
15590
|
});
|
|
15344
|
-
import { existsSync as
|
|
15591
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33 } from "fs";
|
|
15345
15592
|
import { join as join41 } from "path";
|
|
15346
15593
|
var {env: env3, Glob: Glob3 } = globalThis.Bun;
|
|
15347
|
-
var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text2) => [...text2.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () =>
|
|
15594
|
+
var EXTENSIONS = "ts,tsx,js,jsx,mjs,cjs,svelte,vue", STATUS_WIDTH2, keysInFile = (text2) => [...text2.matchAll(/getEnv\(\s*['"]([^'"]+)['"]\s*\)/g)].map((match) => match[1]).filter((key) => key !== undefined), scanPatterns = () => existsSync34(join41(process.cwd(), "src")) ? [`src/**/*.{${EXTENSIONS}}`] : [`*.{${EXTENSIONS}}`], scanEnvUsage = async () => {
|
|
15348
15595
|
const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
|
|
15349
15596
|
const files = (await Promise.all(scans)).flat();
|
|
15350
15597
|
const usage = new Map;
|
|
@@ -15410,7 +15657,7 @@ __export(exports_db, {
|
|
|
15410
15657
|
quoteIdent: () => quoteIdent,
|
|
15411
15658
|
runDb: () => runDb
|
|
15412
15659
|
});
|
|
15413
|
-
import { existsSync as
|
|
15660
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync18 } from "fs";
|
|
15414
15661
|
import { join as join42 } from "path";
|
|
15415
15662
|
var {env: env4, spawn: spawn3, SQL } = globalThis.Bun;
|
|
15416
15663
|
var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA_TYPES, SEED_CANDIDATES, VALUE_FLAGS, paint = (text2, color) => `${color}${text2}${colors.reset}`, chunkRows = (items, size) => Array.from({ length: Math.ceil(items.length / size) }, (_, idx) => items.slice(idx * size, idx * size + size)), quoteIdent = (name) => `"${name.replace(/"/g, '""')}"`, resolveUrl = (explicit) => {
|
|
@@ -15531,7 +15778,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
|
|
|
15531
15778
|
console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
|
|
15532
15779
|
console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
|
|
15533
15780
|
}, runRestore = async (file, options) => {
|
|
15534
|
-
if (!
|
|
15781
|
+
if (!existsSync35(file))
|
|
15535
15782
|
throw new Error(`Backup not found: ${file}`);
|
|
15536
15783
|
const payload = JSON.parse(readFileSync34(file, "utf-8"));
|
|
15537
15784
|
const names = Object.keys(payload.tables).filter((name) => keepTable(name, options));
|
|
@@ -15555,7 +15802,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
|
|
|
15555
15802
|
const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
|
|
15556
15803
|
console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
|
|
15557
15804
|
}, runSeed = async (entry) => {
|
|
15558
|
-
const target = entry ?? SEED_CANDIDATES.find((candidate) =>
|
|
15805
|
+
const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync35(join42(process.cwd(), candidate)));
|
|
15559
15806
|
if (target === undefined)
|
|
15560
15807
|
throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
|
|
15561
15808
|
console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
|
|
@@ -15616,7 +15863,7 @@ __export(exports_logs, {
|
|
|
15616
15863
|
});
|
|
15617
15864
|
import {
|
|
15618
15865
|
closeSync as closeSync2,
|
|
15619
|
-
existsSync as
|
|
15866
|
+
existsSync as existsSync36,
|
|
15620
15867
|
openSync as openSync4,
|
|
15621
15868
|
readSync as readSync2,
|
|
15622
15869
|
statSync as statSync4,
|
|
@@ -15683,7 +15930,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
|
|
|
15683
15930
|
printAvailable(instances);
|
|
15684
15931
|
return;
|
|
15685
15932
|
}
|
|
15686
|
-
if (match.logFile === null || !
|
|
15933
|
+
if (match.logFile === null || !existsSync36(match.logFile)) {
|
|
15687
15934
|
printDim3(`"${name}" has no captured log (untracked, or started outside the CLI).`);
|
|
15688
15935
|
return;
|
|
15689
15936
|
}
|
|
@@ -15703,14 +15950,14 @@ var init_logs = __esm(() => {
|
|
|
15703
15950
|
|
|
15704
15951
|
// src/cli/typeGraphCoherence.ts
|
|
15705
15952
|
import {
|
|
15706
|
-
existsSync as
|
|
15953
|
+
existsSync as existsSync37,
|
|
15707
15954
|
readFileSync as readFileSync35,
|
|
15708
15955
|
realpathSync as realpathSync2,
|
|
15709
15956
|
rmSync as rmSync6,
|
|
15710
15957
|
writeFileSync as writeFileSync19
|
|
15711
15958
|
} from "fs";
|
|
15712
15959
|
import { createRequire } from "module";
|
|
15713
|
-
import { dirname as dirname25, join as join43, resolve as resolve32, sep as
|
|
15960
|
+
import { dirname as dirname25, join as join43, resolve as resolve32, sep as sep6 } from "path";
|
|
15714
15961
|
var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
15715
15962
|
try {
|
|
15716
15963
|
const parsed = JSON.parse(readFileSync35(path, "utf-8"));
|
|
@@ -15754,7 +16001,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
15754
16001
|
}, findInstallRoot = (cwd) => {
|
|
15755
16002
|
let directory = resolve32(cwd);
|
|
15756
16003
|
for (;; ) {
|
|
15757
|
-
if (
|
|
16004
|
+
if (existsSync37(join43(directory, "bun.lock")) || existsSync37(join43(directory, "bun.lockb"))) {
|
|
15758
16005
|
return directory;
|
|
15759
16006
|
}
|
|
15760
16007
|
const parent = dirname25(directory);
|
|
@@ -15766,7 +16013,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
15766
16013
|
let directory = resolve32(cwd);
|
|
15767
16014
|
for (;; ) {
|
|
15768
16015
|
const candidate = join43(directory, "package.json");
|
|
15769
|
-
if (
|
|
16016
|
+
if (existsSync37(candidate))
|
|
15770
16017
|
return candidate;
|
|
15771
16018
|
if (directory === installRoot)
|
|
15772
16019
|
return join43(installRoot, "package.json");
|
|
@@ -15870,8 +16117,8 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
15870
16117
|
}, removeDuplicateTypeGraphPackages = (report) => {
|
|
15871
16118
|
const manifest = readManifest(join43(report.installRoot, "package.json")) ?? {};
|
|
15872
16119
|
const rootName = manifestName(manifest, "<workspace>");
|
|
15873
|
-
const installPrefix = `${realpathSync2(report.installRoot)}${
|
|
15874
|
-
const nodeModulesSegment = `${
|
|
16120
|
+
const installPrefix = `${realpathSync2(report.installRoot)}${sep6}`;
|
|
16121
|
+
const nodeModulesSegment = `${sep6}node_modules${sep6}`;
|
|
15875
16122
|
const removed = [];
|
|
15876
16123
|
const stalePaths = duplicateTypeGraphPackages(report).flatMap((duplicate) => {
|
|
15877
16124
|
const selected = preferredIdentity(duplicate, rootName);
|
|
@@ -15907,7 +16154,7 @@ var exports_doctor = {};
|
|
|
15907
16154
|
__export(exports_doctor, {
|
|
15908
16155
|
runDoctor: () => runDoctor
|
|
15909
16156
|
});
|
|
15910
|
-
import { existsSync as
|
|
16157
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync16, readFileSync as readFileSync36, writeFileSync as writeFileSync20 } from "fs";
|
|
15911
16158
|
import { createRequire as createRequire2 } from "module";
|
|
15912
16159
|
import { arch as arch4, platform as platform5 } from "os";
|
|
15913
16160
|
import { join as join44 } from "path";
|
|
@@ -15945,7 +16192,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
|
|
|
15945
16192
|
return [];
|
|
15946
16193
|
const label = `${field.replace("Directory", "")} pages`;
|
|
15947
16194
|
return [
|
|
15948
|
-
|
|
16195
|
+
existsSync38(join44(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
|
|
15949
16196
|
];
|
|
15950
16197
|
}), envCheck = async () => {
|
|
15951
16198
|
const vars = await collectEnvVars();
|
|
@@ -16007,7 +16254,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
|
|
|
16007
16254
|
const fixes = [];
|
|
16008
16255
|
for (const field of FRAMEWORK_FIELDS2) {
|
|
16009
16256
|
const dir = readString2(config, field);
|
|
16010
|
-
if (dir === undefined ||
|
|
16257
|
+
if (dir === undefined || existsSync38(join44(cwd, dir)))
|
|
16011
16258
|
continue;
|
|
16012
16259
|
mkdirSync16(join44(cwd, dir, "pages"), { recursive: true });
|
|
16013
16260
|
fixes.push(`created ${dir}/pages`);
|
|
@@ -16018,7 +16265,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
|
|
|
16018
16265
|
if (missing.length === 0)
|
|
16019
16266
|
return null;
|
|
16020
16267
|
const envExample = join44(cwd, ".env.example");
|
|
16021
|
-
const existing =
|
|
16268
|
+
const existing = existsSync38(envExample) ? readFileSync36(envExample, "utf-8") : "";
|
|
16022
16269
|
const existingKeys = new Set(existing.split(`
|
|
16023
16270
|
`).map((line) => line.split("=")[0]?.trim()));
|
|
16024
16271
|
const toAdd = missing.filter((entry) => !existingKeys.has(entry.key));
|
|
@@ -16392,10 +16639,10 @@ var init_inspect = __esm(() => {
|
|
|
16392
16639
|
});
|
|
16393
16640
|
|
|
16394
16641
|
// src/build/scanEntryPoints.ts
|
|
16395
|
-
import { existsSync as
|
|
16642
|
+
import { existsSync as existsSync39 } from "fs";
|
|
16396
16643
|
var {Glob: Glob4 } = globalThis.Bun;
|
|
16397
16644
|
var scanEntryPoints = async (dir, pattern) => {
|
|
16398
|
-
if (!
|
|
16645
|
+
if (!existsSync39(dir))
|
|
16399
16646
|
return [];
|
|
16400
16647
|
const entryPaths = [];
|
|
16401
16648
|
const glob = new Glob4(pattern);
|
|
@@ -16547,7 +16794,7 @@ var exports_islands = {};
|
|
|
16547
16794
|
__export(exports_islands, {
|
|
16548
16795
|
runIslands: () => runIslands
|
|
16549
16796
|
});
|
|
16550
|
-
import { existsSync as
|
|
16797
|
+
import { existsSync as existsSync40, readFileSync as readFileSync38, statSync as statSync5 } from "fs";
|
|
16551
16798
|
import { join as join45, relative as relative23, resolve as resolve34 } from "path";
|
|
16552
16799
|
var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
|
|
16553
16800
|
`), hostFrameworkOf = (pagePath, cwd, config) => {
|
|
@@ -16567,7 +16814,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
|
|
|
16567
16814
|
}
|
|
16568
16815
|
}, readManifestSizes2 = (manifestDir) => {
|
|
16569
16816
|
const manifestPath = join45(manifestDir, "manifest.json");
|
|
16570
|
-
if (!
|
|
16817
|
+
if (!existsSync40(manifestPath))
|
|
16571
16818
|
return null;
|
|
16572
16819
|
const manifest = JSON.parse(readFileSync38(manifestPath, "utf-8"));
|
|
16573
16820
|
const sizes = new Map;
|
|
@@ -16707,7 +16954,7 @@ var init_islands2 = __esm(() => {
|
|
|
16707
16954
|
});
|
|
16708
16955
|
|
|
16709
16956
|
// src/build/externalAssetPlugin.ts
|
|
16710
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
16957
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync41, mkdirSync as mkdirSync17, statSync as statSync6 } from "fs";
|
|
16711
16958
|
import { basename as basename12, dirname as dirname27, join as join46, resolve as resolve35 } from "path";
|
|
16712
16959
|
var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
|
|
16713
16960
|
name: "absolute-external-asset",
|
|
@@ -16729,12 +16976,12 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
|
|
|
16729
16976
|
if (!relPath)
|
|
16730
16977
|
continue;
|
|
16731
16978
|
const assetPath = resolve35(sourceDir, relPath);
|
|
16732
|
-
if (!
|
|
16979
|
+
if (!existsSync41(assetPath))
|
|
16733
16980
|
continue;
|
|
16734
16981
|
if (!statSync6(assetPath).isFile())
|
|
16735
16982
|
continue;
|
|
16736
16983
|
const targetPath = join46(outDir, basename12(assetPath));
|
|
16737
|
-
if (
|
|
16984
|
+
if (existsSync41(targetPath))
|
|
16738
16985
|
continue;
|
|
16739
16986
|
mkdirSync17(dirname27(targetPath), { recursive: true });
|
|
16740
16987
|
copyFileSync2(assetPath, targetPath);
|
|
@@ -16754,7 +17001,7 @@ __export(exports_compile, {
|
|
|
16754
17001
|
var {env: env5 } = globalThis.Bun;
|
|
16755
17002
|
import {
|
|
16756
17003
|
cpSync,
|
|
16757
|
-
existsSync as
|
|
17004
|
+
existsSync as existsSync42,
|
|
16758
17005
|
mkdirSync as mkdirSync18,
|
|
16759
17006
|
readdirSync as readdirSync7,
|
|
16760
17007
|
readFileSync as readFileSync39,
|
|
@@ -16845,7 +17092,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
16845
17092
|
const normalizedOutdir = resolve36(outdir);
|
|
16846
17093
|
const copyReference = (filePath, relPath) => {
|
|
16847
17094
|
const assetSource = resolve36(dirname28(filePath), relPath);
|
|
16848
|
-
if (!
|
|
17095
|
+
if (!existsSync42(assetSource) || !statSync7(assetSource).isFile())
|
|
16849
17096
|
return;
|
|
16850
17097
|
const assetTarget = resolve36(normalizedOutdir, relPath.replace(/^\.\//, ""));
|
|
16851
17098
|
if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
|
|
@@ -16929,7 +17176,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
16929
17176
|
resolve36(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
|
|
16930
17177
|
];
|
|
16931
17178
|
for (const candidate of candidates) {
|
|
16932
|
-
if (
|
|
17179
|
+
if (existsSync42(candidate))
|
|
16933
17180
|
return candidate;
|
|
16934
17181
|
}
|
|
16935
17182
|
return resolve36(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
|
|
@@ -17004,7 +17251,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17004
17251
|
if (!buildConfig.angularDirectory)
|
|
17005
17252
|
return;
|
|
17006
17253
|
const angularScopeDir = resolve36(process.cwd(), "node_modules", "@angular");
|
|
17007
|
-
const angularPackages =
|
|
17254
|
+
const angularPackages = existsSync42(angularScopeDir) ? readdirSync7(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
|
|
17008
17255
|
const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
|
|
17009
17256
|
const seen = new Set;
|
|
17010
17257
|
for (const specifier of roots) {
|
|
@@ -17023,7 +17270,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17023
17270
|
copyChunkReferencedPackages(outdir, seen);
|
|
17024
17271
|
}, collectRuntimePackageSpecifiers = (distDir) => {
|
|
17025
17272
|
const nodeModulesDir = join47(distDir, "node_modules");
|
|
17026
|
-
if (!
|
|
17273
|
+
if (!existsSync42(nodeModulesDir))
|
|
17027
17274
|
return [];
|
|
17028
17275
|
const specifiers = [];
|
|
17029
17276
|
for (const entry of readdirSync7(nodeModulesDir, { withFileTypes: true })) {
|
|
@@ -17064,9 +17311,9 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17064
17311
|
const packageDir = join47(distDir, "node_modules", ...packageSpecifier.split("/"));
|
|
17065
17312
|
const subpath = specifier.slice(packageSpecifier.length);
|
|
17066
17313
|
const subPackageDir = subpath ? join47(packageDir, ...subpath.slice(1).split("/")) : null;
|
|
17067
|
-
const resolvedPackageDir = subPackageDir &&
|
|
17314
|
+
const resolvedPackageDir = subPackageDir && existsSync42(join47(subPackageDir, "package.json")) ? subPackageDir : packageDir;
|
|
17068
17315
|
const packageJsonPath = join47(resolvedPackageDir, "package.json");
|
|
17069
|
-
if (!
|
|
17316
|
+
if (!existsSync42(packageJsonPath))
|
|
17070
17317
|
return null;
|
|
17071
17318
|
const pkg = JSON.parse(readFileSync39(packageJsonPath, "utf-8"));
|
|
17072
17319
|
const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
|
|
@@ -17091,7 +17338,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17091
17338
|
}, findContainingRuntimePackageDir = (filePath) => {
|
|
17092
17339
|
let dir = dirname28(filePath);
|
|
17093
17340
|
while (dir !== dirname28(dir)) {
|
|
17094
|
-
if (isNodeModulesPath(dir) &&
|
|
17341
|
+
if (isNodeModulesPath(dir) && existsSync42(join47(dir, "package.json"))) {
|
|
17095
17342
|
return dir;
|
|
17096
17343
|
}
|
|
17097
17344
|
dir = dirname28(dir);
|
|
@@ -17771,11 +18018,11 @@ export default server;
|
|
|
17771
18018
|
process.exit(1);
|
|
17772
18019
|
}
|
|
17773
18020
|
const outputPath = resolve36(resolvedOutdir, `${entryName}.js`);
|
|
17774
|
-
if (!
|
|
18021
|
+
if (!existsSync42(outputPath)) {
|
|
17775
18022
|
console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
|
|
17776
18023
|
process.exit(1);
|
|
17777
18024
|
}
|
|
17778
|
-
if (
|
|
18025
|
+
if (existsSync42(resolve36(resolvedOutdir, "angular", "vendor", "server"))) {
|
|
17779
18026
|
const vendorDir = resolve36(resolvedOutdir, "angular", "vendor", "server");
|
|
17780
18027
|
const vendorEntries = readdirSync7(vendorDir).filter((fileName) => fileName.endsWith(".js"));
|
|
17781
18028
|
const angularServerVendorPaths = {};
|
|
@@ -19739,7 +19986,7 @@ import {
|
|
|
19739
19986
|
stat as stat3,
|
|
19740
19987
|
writeFile as writeFile15
|
|
19741
19988
|
} from "fs/promises";
|
|
19742
|
-
import { dirname as dirname31, isAbsolute as isAbsolute7, join as join53, relative as relative27, resolve as resolve40, sep as
|
|
19989
|
+
import { dirname as dirname31, isAbsolute as isAbsolute7, join as join53, relative as relative27, resolve as resolve40, sep as sep7 } from "path";
|
|
19743
19990
|
var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), requireManifest2 = (value) => {
|
|
19744
19991
|
if (!isRecord13(value) || typeof value.appBuild !== "string" || typeof value.appId !== "string" || typeof value.runtime !== "string") {
|
|
19745
19992
|
throw new TypeError("Invalid embedded AbsoluteJS mobile manifest.");
|
|
@@ -19807,7 +20054,7 @@ var ABSOLUTE_ANDROID_RELEASE_FORMAT = 1, isRecord13 = (value) => typeof value ==
|
|
|
19807
20054
|
const root = resolve40(projectRoot);
|
|
19808
20055
|
const output = resolve40(root, requested ?? ".absolutejs/mobile/releases/android");
|
|
19809
20056
|
const projectRelative = relative27(root, output);
|
|
19810
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
20057
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep7}`) || isAbsolute7(projectRelative)) {
|
|
19811
20058
|
throw new TypeError("mobile build --outdir must remain inside the project.");
|
|
19812
20059
|
}
|
|
19813
20060
|
return output;
|
|
@@ -20393,7 +20640,7 @@ var init_androidTestReport = __esm(() => {
|
|
|
20393
20640
|
|
|
20394
20641
|
// src/mobile/releasePublisher.ts
|
|
20395
20642
|
import { access as access13 } from "fs/promises";
|
|
20396
|
-
import { isAbsolute as isAbsolute8, relative as relative28, resolve as resolve41, sep as
|
|
20643
|
+
import { isAbsolute as isAbsolute8, relative as relative28, resolve as resolve41, sep as sep8 } from "path";
|
|
20397
20644
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
20398
20645
|
var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
20399
20646
|
if (typeof publisher.prepareIosRelease !== "function") {
|
|
@@ -20418,7 +20665,7 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
|
20418
20665
|
const root = resolve41(projectRoot);
|
|
20419
20666
|
const path = resolve41(root, requested);
|
|
20420
20667
|
const projectRelative = relative28(root, path);
|
|
20421
|
-
if (projectRelative === ".." || projectRelative.startsWith(`..${
|
|
20668
|
+
if (projectRelative === ".." || projectRelative.startsWith(`..${sep8}`) || isAbsolute8(projectRelative)) {
|
|
20422
20669
|
throw new TypeError("mobile publish --registry must remain inside the project.");
|
|
20423
20670
|
}
|
|
20424
20671
|
return path;
|
|
@@ -20633,9 +20880,9 @@ var init_mobileInspect = __esm(() => {
|
|
|
20633
20880
|
});
|
|
20634
20881
|
|
|
20635
20882
|
// src/mobile/ciWorkflow.ts
|
|
20636
|
-
import { existsSync as
|
|
20883
|
+
import { existsSync as existsSync43 } from "fs";
|
|
20637
20884
|
import { access as access15, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile17 } from "fs/promises";
|
|
20638
|
-
import { dirname as dirname32, extname as extname9, relative as relative30, resolve as resolve43, sep as
|
|
20885
|
+
import { dirname as dirname32, extname as extname9, relative as relative30, resolve as resolve43, sep as sep9 } from "path";
|
|
20639
20886
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTATION = 6, RESERVED_SECRET_NAMES, exists4 = async (path) => {
|
|
20640
20887
|
try {
|
|
20641
20888
|
await access15(path);
|
|
@@ -20647,12 +20894,12 @@ var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTAT
|
|
|
20647
20894
|
const root = resolve43(projectRoot);
|
|
20648
20895
|
const path = resolve43(root, value);
|
|
20649
20896
|
const portable = relative30(root, path).replaceAll("\\", "/");
|
|
20650
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
20897
|
+
if (portable === ".." || portable.startsWith(`..${sep9}`) || portable.startsWith("../") || portable === "") {
|
|
20651
20898
|
throw new TypeError(`${field} must remain inside the project root.`);
|
|
20652
20899
|
}
|
|
20653
20900
|
if (/\r|\n/u.test(portable) || portable.startsWith("-"))
|
|
20654
20901
|
throw new TypeError(`${field} contains an unsafe path.`);
|
|
20655
|
-
if (!options.allowMissing && !
|
|
20902
|
+
if (!options.allowMissing && !existsSync43(path))
|
|
20656
20903
|
throw new TypeError(`${field} does not exist inside the project.`);
|
|
20657
20904
|
return portable;
|
|
20658
20905
|
}, workflowOutputPath = (projectRoot, value) => {
|
|
@@ -20660,7 +20907,7 @@ var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTAT
|
|
|
20660
20907
|
const workflows = resolve43(root, ".github/workflows");
|
|
20661
20908
|
const path = resolve43(root, value ?? ".github/workflows/absolute-mobile.yml");
|
|
20662
20909
|
const portable = relative30(workflows, path);
|
|
20663
|
-
if (portable === ".." || portable.startsWith(`..${
|
|
20910
|
+
if (portable === ".." || portable.startsWith(`..${sep9}`) || extname9(path) !== ".yml" && extname9(path) !== ".yaml") {
|
|
20664
20911
|
throw new TypeError("mobile ci github --output must be a .yml or .yaml file inside .github/workflows.");
|
|
20665
20912
|
}
|
|
20666
20913
|
return path;
|
|
@@ -21213,7 +21460,26 @@ var NOT_FOUND4 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
21213
21460
|
throw new TypeError(`Expo exited with status ${exitCode}.`);
|
|
21214
21461
|
}, ensureExpoPackages = async (project, args) => {
|
|
21215
21462
|
try {
|
|
21216
|
-
await
|
|
21463
|
+
const manifest = JSON.parse(await readFile24(join56(project, "package.json"), "utf8"));
|
|
21464
|
+
const dependencies = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "dependencies") : undefined;
|
|
21465
|
+
if (typeof dependencies !== "object" || dependencies === null || Array.isArray(dependencies))
|
|
21466
|
+
throw new TypeError("Generated Expo dependencies are invalid.");
|
|
21467
|
+
await Promise.all(Object.entries(dependencies).map(async ([name, expected]) => {
|
|
21468
|
+
if (typeof expected !== "string")
|
|
21469
|
+
throw new TypeError("Generated Expo dependency version is invalid.");
|
|
21470
|
+
const installed = JSON.parse(await readFile24(join56(project, "node_modules", name, "package.json"), "utf8"));
|
|
21471
|
+
const actual = typeof installed === "object" && installed !== null ? Reflect.get(installed, "version") : undefined;
|
|
21472
|
+
if (typeof actual !== "string")
|
|
21473
|
+
throw new TypeError("Installed Expo dependency version is invalid.");
|
|
21474
|
+
if (/^\d+\.\d+\.\d+$/u.test(expected) && actual !== expected)
|
|
21475
|
+
throw new TypeError("Installed Expo dependency is outdated.");
|
|
21476
|
+
if (expected.startsWith("~")) {
|
|
21477
|
+
const wanted = expected.slice(1).split(".").map(Number);
|
|
21478
|
+
const found = actual.split(".").map(Number);
|
|
21479
|
+
if (found[0] !== wanted[0] || found[1] !== wanted[1] || (found[2] ?? -1) < (wanted[2] ?? 0))
|
|
21480
|
+
throw new TypeError("Installed Expo dependency is outdated.");
|
|
21481
|
+
}
|
|
21482
|
+
}));
|
|
21217
21483
|
return;
|
|
21218
21484
|
} catch {}
|
|
21219
21485
|
const approved = args.includes("--yes") || await confirmInstall("The experimental Expo shell dependencies are missing. Install the pinned Expo SDK 57 toolchain now?");
|
|
@@ -22779,10 +23045,10 @@ __export(exports_typecheck, {
|
|
|
22779
23045
|
typecheck: () => typecheck
|
|
22780
23046
|
});
|
|
22781
23047
|
import { resolve as resolve45, join as join57 } from "path";
|
|
22782
|
-
import { existsSync as
|
|
23048
|
+
import { existsSync as existsSync44, readFileSync as readFileSync40 } from "fs";
|
|
22783
23049
|
import { mkdir as mkdir17, writeFile as writeFile19 } from "fs/promises";
|
|
22784
23050
|
var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve45(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
|
|
22785
|
-
if (!
|
|
23051
|
+
if (!existsSync44(resolveConfigPath(configPath2))) {
|
|
22786
23052
|
const defaultService = {};
|
|
22787
23053
|
return [defaultService];
|
|
22788
23054
|
}
|
|
@@ -22804,7 +23070,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
22804
23070
|
return { exitCode, name, output: (stdout + stderr).trim() };
|
|
22805
23071
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
22806
23072
|
const local = resolve45("node_modules", ".bin", name);
|
|
22807
|
-
return
|
|
23073
|
+
return existsSync44(local) ? local : null;
|
|
22808
23074
|
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi4 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
22809
23075
|
const cwd = `${process.cwd()}/`;
|
|
22810
23076
|
const summaryMatch = stripAnsi4(output).match(/svelte-check found (\d+) error/);
|
|
@@ -22856,7 +23122,7 @@ Found ${errorCount} error${suffix}.`;
|
|
|
22856
23122
|
resolve45(import.meta.dir, "../../types", fileName),
|
|
22857
23123
|
resolve45(import.meta.dir, "../../../types", fileName)
|
|
22858
23124
|
];
|
|
22859
|
-
return candidates.find((candidate) =>
|
|
23125
|
+
return candidates.find((candidate) => existsSync44(candidate)) ?? candidates[0];
|
|
22860
23126
|
}, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
|
|
22861
23127
|
try {
|
|
22862
23128
|
return JSON.parse(readFileSync40(resolve45("tsconfig.json"), "utf-8"));
|
|
@@ -23215,13 +23481,13 @@ var {$: $3, env } = globalThis.Bun;
|
|
|
23215
23481
|
import { spawn as nodeSpawn } from "child_process";
|
|
23216
23482
|
import {
|
|
23217
23483
|
createWriteStream,
|
|
23218
|
-
existsSync as
|
|
23219
|
-
readFileSync as
|
|
23484
|
+
existsSync as existsSync6,
|
|
23485
|
+
readFileSync as readFileSync10,
|
|
23220
23486
|
rmSync as rmSync2,
|
|
23221
23487
|
writeFileSync as writeFileSync4
|
|
23222
23488
|
} from "fs";
|
|
23223
23489
|
import { tmpdir as tmpdir2 } from "os";
|
|
23224
|
-
import { join as
|
|
23490
|
+
import { join as join17, resolve as resolvePath2 } from "path";
|
|
23225
23491
|
|
|
23226
23492
|
// src/dev/tunnel/client.ts
|
|
23227
23493
|
var RECONNECT_DELAY_MS = 2000;
|
|
@@ -23731,7 +23997,7 @@ init_expoProject();
|
|
|
23731
23997
|
init_iosPhysicalDeviceTransport();
|
|
23732
23998
|
import { spawn } from "child_process";
|
|
23733
23999
|
import { access as access2 } from "fs/promises";
|
|
23734
|
-
import { join as
|
|
24000
|
+
import { join as join9 } from "path";
|
|
23735
24001
|
var METRO_READY_TIMEOUT_MS = 60000;
|
|
23736
24002
|
var PROCESS_CLOSE_TIMEOUT_MS = 2000;
|
|
23737
24003
|
var commandEnvironment = (options) => ({
|
|
@@ -23744,7 +24010,7 @@ var commandEnvironment = (options) => ({
|
|
|
23744
24010
|
...options.metroHost ? { REACT_NATIVE_PACKAGER_HOSTNAME: options.metroHost } : {}
|
|
23745
24011
|
});
|
|
23746
24012
|
var absoluteExpoExecutable = async (project) => {
|
|
23747
|
-
const executable =
|
|
24013
|
+
const executable = join9(project, "node_modules", ".bin", "expo");
|
|
23748
24014
|
try {
|
|
23749
24015
|
await access2(executable);
|
|
23750
24016
|
return executable;
|
|
@@ -23840,18 +24106,18 @@ var stopProcess = async (process2) => {
|
|
|
23840
24106
|
return;
|
|
23841
24107
|
process2.kill("SIGTERM");
|
|
23842
24108
|
await Promise.race([
|
|
23843
|
-
new Promise((
|
|
23844
|
-
new Promise((
|
|
24109
|
+
new Promise((resolve6) => process2.once("exit", () => resolve6())),
|
|
24110
|
+
new Promise((resolve6) => setTimeout(resolve6, PROCESS_CLOSE_TIMEOUT_MS))
|
|
23845
24111
|
]);
|
|
23846
24112
|
if (process2.exitCode === null)
|
|
23847
24113
|
process2.kill("SIGKILL");
|
|
23848
24114
|
};
|
|
23849
|
-
var waitForExit = (process2) => new Promise((
|
|
24115
|
+
var waitForExit = (process2) => new Promise((resolve6) => {
|
|
23850
24116
|
if (process2.exitCode !== null) {
|
|
23851
|
-
|
|
24117
|
+
resolve6(process2.exitCode);
|
|
23852
24118
|
return;
|
|
23853
24119
|
}
|
|
23854
|
-
process2.once("exit", (code) =>
|
|
24120
|
+
process2.once("exit", (code) => resolve6(code ?? 1));
|
|
23855
24121
|
});
|
|
23856
24122
|
var runUtilityCommand = async (run, command, args, options) => {
|
|
23857
24123
|
const child = run(command, args, {
|
|
@@ -23931,9 +24197,9 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
23931
24197
|
}) : undefined;
|
|
23932
24198
|
let metroReady = false;
|
|
23933
24199
|
let resolveMetro;
|
|
23934
|
-
const metroPromise = new Promise((
|
|
24200
|
+
const metroPromise = new Promise((resolve6, reject) => {
|
|
23935
24201
|
if (!metro) {
|
|
23936
|
-
|
|
24202
|
+
resolve6();
|
|
23937
24203
|
return;
|
|
23938
24204
|
}
|
|
23939
24205
|
const timeout = setTimeout(() => {
|
|
@@ -23941,7 +24207,7 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
23941
24207
|
}, METRO_READY_TIMEOUT_MS);
|
|
23942
24208
|
resolveMetro = () => {
|
|
23943
24209
|
clearTimeout(timeout);
|
|
23944
|
-
|
|
24210
|
+
resolve6();
|
|
23945
24211
|
};
|
|
23946
24212
|
metro.once("exit", (code) => {
|
|
23947
24213
|
if (!metroReady) {
|
|
@@ -24306,7 +24572,7 @@ var DEFAULT_PORT_RANGE = 10;
|
|
|
24306
24572
|
var RESTART_PARK_POLL_MS = 20;
|
|
24307
24573
|
var NODE_API_IMPORT_ERROR = "To load Node-API modules, use require() or process.dlopen instead of import.";
|
|
24308
24574
|
var sourceServerBootstrap = resolvePath2(import.meta.dir, "../../dev/serverBootstrap.ts");
|
|
24309
|
-
var serverBootstrap =
|
|
24575
|
+
var serverBootstrap = existsSync6(sourceServerBootstrap) ? sourceServerBootstrap : resolvePath2(import.meta.dir, "../dev/serverBootstrap.js");
|
|
24310
24576
|
var formatServerBootDiagnostic = (output, serverEntry) => {
|
|
24311
24577
|
if (!output.includes(NODE_API_IMPORT_ERROR))
|
|
24312
24578
|
return null;
|
|
@@ -24496,7 +24762,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24496
24762
|
const generated = await writeAbsoluteExpoProject(normalized, {
|
|
24497
24763
|
projectRoot: process.cwd()
|
|
24498
24764
|
});
|
|
24499
|
-
const dependenciesReady =
|
|
24765
|
+
const dependenciesReady = existsSync6(join17(generated.path, "node_modules", "expo", "package.json")) && existsSync6(join17(generated.path, "node_modules", "expo-dev-client", "package.json"));
|
|
24500
24766
|
if (!dependenciesReady) {
|
|
24501
24767
|
const install = await confirmPrompt("Expo development dependencies are missing. Install the pinned SDK 57 development client now?");
|
|
24502
24768
|
if (!install) {
|
|
@@ -24506,7 +24772,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24506
24772
|
cwd: generated.path,
|
|
24507
24773
|
stdio: "inherit"
|
|
24508
24774
|
});
|
|
24509
|
-
const installExit = await new Promise((
|
|
24775
|
+
const installExit = await new Promise((resolve11) => installProcess.once("exit", (code) => resolve11(code ?? 1)));
|
|
24510
24776
|
if (installExit !== 0) {
|
|
24511
24777
|
throw new TypeError(`Expo dependency installation exited with status ${installExit}.`);
|
|
24512
24778
|
}
|
|
@@ -24575,12 +24841,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24575
24841
|
}
|
|
24576
24842
|
}
|
|
24577
24843
|
if (ready) {
|
|
24578
|
-
const nativeDirectory =
|
|
24844
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "android");
|
|
24579
24845
|
let createNativeProject = false;
|
|
24580
|
-
if (!
|
|
24846
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24581
24847
|
createNativeProject = await confirmPrompt("Create the managed Capacitor Android project now?");
|
|
24582
24848
|
}
|
|
24583
|
-
if (
|
|
24849
|
+
if (existsSync6(nativeDirectory) || createNativeProject) {
|
|
24584
24850
|
androidDevProject = await prepareAbsoluteAndroidDevProject(normalized, {
|
|
24585
24851
|
createNativeProject,
|
|
24586
24852
|
projectRoot: process.cwd(),
|
|
@@ -24595,8 +24861,8 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24595
24861
|
if (!remote) {
|
|
24596
24862
|
console.log(cliTag("\x1B[33m", "iOS target skipped. Pair a Mac with `absolute mobile pair mac <name> <user@host>`."));
|
|
24597
24863
|
} else {
|
|
24598
|
-
const nativeDirectory =
|
|
24599
|
-
if (!
|
|
24864
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "ios");
|
|
24865
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24600
24866
|
console.log(cliTag("\x1B[33m", "The iOS project is missing. Run `absolute mobile init` before remote development."));
|
|
24601
24867
|
} else {
|
|
24602
24868
|
iosDevProject = createAbsoluteRemoteIosDevProject(normalized, process.cwd(), remote);
|
|
@@ -24616,12 +24882,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24616
24882
|
}
|
|
24617
24883
|
}
|
|
24618
24884
|
if (ready) {
|
|
24619
|
-
const nativeDirectory =
|
|
24885
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "ios");
|
|
24620
24886
|
let createNativeProject = false;
|
|
24621
|
-
if (!
|
|
24887
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24622
24888
|
createNativeProject = await confirmPrompt("Create the managed Capacitor iOS project now?");
|
|
24623
24889
|
}
|
|
24624
|
-
if (
|
|
24890
|
+
if (existsSync6(nativeDirectory) || createNativeProject) {
|
|
24625
24891
|
iosDevProject = await prepareAbsoluteIosDevProject(normalized, {
|
|
24626
24892
|
createNativeProject,
|
|
24627
24893
|
projectRoot: process.cwd(),
|
|
@@ -24690,12 +24956,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24690
24956
|
startedAt: new Date().toISOString()
|
|
24691
24957
|
});
|
|
24692
24958
|
const instanceLog = createWriteStream(instanceLogFile, { flags: "w" });
|
|
24693
|
-
const writeInstanceLog = (
|
|
24959
|
+
const writeInstanceLog = (text2) => {
|
|
24694
24960
|
try {
|
|
24695
|
-
instanceLog.write(
|
|
24961
|
+
instanceLog.write(text2.replace(ANSI_LOG_REGEX, ""));
|
|
24696
24962
|
} catch {}
|
|
24697
24963
|
};
|
|
24698
|
-
const usesDocker =
|
|
24964
|
+
const usesDocker = existsSync6(resolvePath2(COMPOSE_PATH));
|
|
24699
24965
|
const scripts = usesDocker ? await readDbScripts() : null;
|
|
24700
24966
|
if (scripts)
|
|
24701
24967
|
await startDatabase(scripts);
|
|
@@ -25181,8 +25447,8 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25181
25447
|
const ANSI_COLOR_SEQUENCE_RE = new RegExp(`${ANSI_ESCAPE}\\[[0-9;]*m`, "g");
|
|
25182
25448
|
let restartScanBuffer = "";
|
|
25183
25449
|
const handleChunk = (value) => {
|
|
25184
|
-
const
|
|
25185
|
-
restartScanBuffer +=
|
|
25450
|
+
const text2 = value.toString("utf8");
|
|
25451
|
+
restartScanBuffer += text2;
|
|
25186
25452
|
let newlineIdx;
|
|
25187
25453
|
while ((newlineIdx = restartScanBuffer.indexOf(`
|
|
25188
25454
|
`)) !== -1) {
|
|
@@ -25250,13 +25516,13 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25250
25516
|
const merged = {};
|
|
25251
25517
|
const candidates = [".env", ".env.development", ".env.local"];
|
|
25252
25518
|
for (const name of candidates) {
|
|
25253
|
-
let
|
|
25519
|
+
let text2;
|
|
25254
25520
|
try {
|
|
25255
|
-
|
|
25521
|
+
text2 = readFileSync10(resolvePath2(process.cwd(), name), "utf8");
|
|
25256
25522
|
} catch {
|
|
25257
25523
|
continue;
|
|
25258
25524
|
}
|
|
25259
|
-
for (const rawLine of
|
|
25525
|
+
for (const rawLine of text2.split(`
|
|
25260
25526
|
`)) {
|
|
25261
25527
|
const line = rawLine.trim();
|
|
25262
25528
|
if (!line || line.startsWith("#"))
|
|
@@ -25274,7 +25540,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25274
25540
|
}
|
|
25275
25541
|
return merged;
|
|
25276
25542
|
};
|
|
25277
|
-
const heapPreloadPath =
|
|
25543
|
+
const heapPreloadPath = join17(tmpdir2(), `absolute-heap-${process.pid}.ts`);
|
|
25278
25544
|
let heapSnapshotEnabled = false;
|
|
25279
25545
|
try {
|
|
25280
25546
|
writeFileSync4(heapPreloadPath, DEV_CHILD_PRELOAD);
|
|
@@ -25407,7 +25673,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25407
25673
|
if (now - last < 100)
|
|
25408
25674
|
return;
|
|
25409
25675
|
recentlyHandled.set(filename, now);
|
|
25410
|
-
scheduleServerRestart(
|
|
25676
|
+
scheduleServerRestart(join17(serverEntryDir, filename));
|
|
25411
25677
|
};
|
|
25412
25678
|
const recoveryScan = async () => {
|
|
25413
25679
|
let entries;
|
|
@@ -25426,7 +25692,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25426
25692
|
continue;
|
|
25427
25693
|
let fileStat;
|
|
25428
25694
|
try {
|
|
25429
|
-
fileStat = statSync(
|
|
25695
|
+
fileStat = statSync(join17(serverEntryDir, entry.name));
|
|
25430
25696
|
} catch {
|
|
25431
25697
|
continue;
|
|
25432
25698
|
}
|
|
@@ -25814,9 +26080,9 @@ init_eslint();
|
|
|
25814
26080
|
init_constants();
|
|
25815
26081
|
init_utils();
|
|
25816
26082
|
import { execSync as execSync2 } from "child_process";
|
|
25817
|
-
import { existsSync as
|
|
26083
|
+
import { existsSync as existsSync9, readFileSync as readFileSync12 } from "fs";
|
|
25818
26084
|
import { arch as arch2, cpus, platform as platform3, totalmem, version } from "os";
|
|
25819
|
-
import { resolve as
|
|
26085
|
+
import { resolve as resolve13 } from "path";
|
|
25820
26086
|
var bold = (str) => `\x1B[1m${str}\x1B[0m`;
|
|
25821
26087
|
var getBinaryVersion = (binary, flag = "--version") => {
|
|
25822
26088
|
try {
|
|
@@ -25836,7 +26102,7 @@ var getPackageVersion = (packageName) => {
|
|
|
25836
26102
|
const pkgPath = __require.resolve(`${packageName}/package.json`, {
|
|
25837
26103
|
paths: [process.cwd()]
|
|
25838
26104
|
});
|
|
25839
|
-
const pkg = JSON.parse(
|
|
26105
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
25840
26106
|
const ver = pkg.version;
|
|
25841
26107
|
return ver;
|
|
25842
26108
|
} catch {
|
|
@@ -25846,10 +26112,10 @@ var getPackageVersion = (packageName) => {
|
|
|
25846
26112
|
var getAbsoluteVersion = () => {
|
|
25847
26113
|
try {
|
|
25848
26114
|
const candidates = [
|
|
25849
|
-
|
|
25850
|
-
|
|
26115
|
+
resolve13(import.meta.dir, "..", "..", "package.json"),
|
|
26116
|
+
resolve13(import.meta.dir, "..", "..", "..", "package.json")
|
|
25851
26117
|
];
|
|
25852
|
-
const pkgPath = candidates.find((candidate) =>
|
|
26118
|
+
const pkgPath = candidates.find((candidate) => existsSync9(candidate));
|
|
25853
26119
|
if (pkgPath)
|
|
25854
26120
|
return readPackageVersion(pkgPath);
|
|
25855
26121
|
} catch {
|
|
@@ -25858,7 +26124,7 @@ var getAbsoluteVersion = () => {
|
|
|
25858
26124
|
return getPackageVersion("@absolutejs/absolute");
|
|
25859
26125
|
};
|
|
25860
26126
|
var readPackageVersion = (pkgPath) => {
|
|
25861
|
-
const pkg = JSON.parse(
|
|
26127
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
25862
26128
|
const ver = pkg.version;
|
|
25863
26129
|
return ver;
|
|
25864
26130
|
};
|
|
@@ -25890,7 +26156,7 @@ var detectCI = () => {
|
|
|
25890
26156
|
};
|
|
25891
26157
|
var isDockerEnvironment = () => {
|
|
25892
26158
|
try {
|
|
25893
|
-
return
|
|
26159
|
+
return existsSync9("/.dockerenv");
|
|
25894
26160
|
} catch {
|
|
25895
26161
|
return false;
|
|
25896
26162
|
}
|
|
@@ -25960,11 +26226,11 @@ var info = () => {
|
|
|
25960
26226
|
// src/cli/cache.ts
|
|
25961
26227
|
init_constants();
|
|
25962
26228
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
25963
|
-
import { join as
|
|
26229
|
+
import { join as join18 } from "path";
|
|
25964
26230
|
var {Glob } = globalThis.Bun;
|
|
25965
26231
|
var CACHE_DIR = ".absolutejs";
|
|
25966
26232
|
var MAX_FILES_PER_BATCH = 200;
|
|
25967
|
-
var
|
|
26233
|
+
var isIgnored2 = (file, ignorePatterns) => ignorePatterns.some((pat) => new Glob(pat).match(file));
|
|
25968
26234
|
var collectFiles = async (pattern, ignorePatterns) => {
|
|
25969
26235
|
const files = [];
|
|
25970
26236
|
const glob = new Glob(pattern);
|
|
@@ -25972,7 +26238,7 @@ var collectFiles = async (pattern, ignorePatterns) => {
|
|
|
25972
26238
|
cwd: ".",
|
|
25973
26239
|
dot: false
|
|
25974
26240
|
})) {
|
|
25975
|
-
if (!
|
|
26241
|
+
if (!isIgnored2(file, ignorePatterns))
|
|
25976
26242
|
files.push(file);
|
|
25977
26243
|
}
|
|
25978
26244
|
return files;
|
|
@@ -26012,7 +26278,7 @@ var hashFiles = async (paths) => {
|
|
|
26012
26278
|
};
|
|
26013
26279
|
var loadCache = async (tool) => {
|
|
26014
26280
|
try {
|
|
26015
|
-
const path =
|
|
26281
|
+
const path = join18(CACHE_DIR, `${tool}.cache.json`);
|
|
26016
26282
|
const data = await Bun.file(path).json();
|
|
26017
26283
|
const result = data;
|
|
26018
26284
|
return result;
|
|
@@ -26059,7 +26325,7 @@ var runTool = async (adapter, args) => {
|
|
|
26059
26325
|
};
|
|
26060
26326
|
var saveCache = async (tool, data) => {
|
|
26061
26327
|
await mkdir7(CACHE_DIR, { recursive: true });
|
|
26062
|
-
const path =
|
|
26328
|
+
const path = join18(CACHE_DIR, `${tool}.cache.json`);
|
|
26063
26329
|
await Bun.write(path, JSON.stringify(data, null, "\t"));
|
|
26064
26330
|
};
|
|
26065
26331
|
|
|
@@ -26152,7 +26418,7 @@ init_getDurationString();
|
|
|
26152
26418
|
init_instanceRegistry();
|
|
26153
26419
|
import {
|
|
26154
26420
|
appendFileSync,
|
|
26155
|
-
existsSync as
|
|
26421
|
+
existsSync as existsSync13,
|
|
26156
26422
|
mkdirSync as mkdirSync7,
|
|
26157
26423
|
readdirSync as readdirSync2,
|
|
26158
26424
|
readFileSync as readFileSync16,
|
|
@@ -26723,7 +26989,7 @@ var createWorkspaceTui = ({
|
|
|
26723
26989
|
// src/cli/scripts/workspace.ts
|
|
26724
26990
|
init_utils();
|
|
26725
26991
|
var sourceServerBootstrap2 = resolve22(import.meta.dir, "../../dev/serverBootstrap.ts");
|
|
26726
|
-
var serverBootstrap2 =
|
|
26992
|
+
var serverBootstrap2 = existsSync13(sourceServerBootstrap2) ? sourceServerBootstrap2 : resolve22(import.meta.dir, "../dev/serverBootstrap.js");
|
|
26727
26993
|
var ANSI_REGEX2 = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
26728
26994
|
var sleep = (durationMs) => Bun.sleep(durationMs);
|
|
26729
26995
|
var stripAnsi3 = (value) => value.replace(ANSI_REGEX2, "");
|
|
@@ -27370,7 +27636,7 @@ var workspace = async (subcommand, options) => {
|
|
|
27370
27636
|
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
27371
27637
|
const port = resolveWorkspaceServicePort(resolved.service, resolved.env);
|
|
27372
27638
|
killStaleServicePort(port);
|
|
27373
|
-
if (isAbsoluteService(resolved.service) && resolved.configPath && !
|
|
27639
|
+
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync13(resolved.configPath)) {
|
|
27374
27640
|
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
27375
27641
|
}
|
|
27376
27642
|
serviceBootStartedAt.set(name, performance.now());
|