@absolutejs/absolute 0.20.0-beta.45 → 0.20.0-beta.46
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 +967 -771
- package/dist/index.js +165 -146
- package/dist/index.js.map +4 -4
- package/dist/mobile/index.js +326 -90
- package/dist/mobile/index.js.map +7 -7
- package/dist/mobile/remoteMacAgentEntry.js +595 -84
- 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/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -1314,6 +1314,279 @@ var init_syncSchema = __esm(() => {
|
|
|
1314
1314
|
init_client();
|
|
1315
1315
|
});
|
|
1316
1316
|
|
|
1317
|
+
// src/mobile/deviceCapabilities.ts
|
|
1318
|
+
import { existsSync as existsSync3, readFileSync as readFileSync7 } from "fs";
|
|
1319
|
+
import { extname, join as join7, relative, resolve as resolve4 } from "path";
|
|
1320
|
+
import { fileURLToPath } from "url";
|
|
1321
|
+
import ts from "typescript";
|
|
1322
|
+
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) => {
|
|
1323
|
+
const value = JSON.parse(readFileSync7(path, "utf8"));
|
|
1324
|
+
if (!object2(value))
|
|
1325
|
+
throw new TypeError(`${path} must contain an object.`);
|
|
1326
|
+
return value;
|
|
1327
|
+
}, text = (value, field) => {
|
|
1328
|
+
if (typeof value !== "string" || value.length === 0)
|
|
1329
|
+
throw new TypeError(`${field} must be a non-empty string.`);
|
|
1330
|
+
return value;
|
|
1331
|
+
}, androidPermissions = (value, field) => {
|
|
1332
|
+
if (value === undefined)
|
|
1333
|
+
return;
|
|
1334
|
+
if (!object2(value))
|
|
1335
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1336
|
+
const { permissions } = value;
|
|
1337
|
+
if (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string" && ANDROID_PERMISSION_PATTERN.test(permission)))
|
|
1338
|
+
throw new TypeError(`${field}.permissions must contain Android permission names.`);
|
|
1339
|
+
return [...permissions];
|
|
1340
|
+
}, iosPrivacyAccessedApis = (value, field) => {
|
|
1341
|
+
if (value === undefined)
|
|
1342
|
+
return;
|
|
1343
|
+
if (!object2(value))
|
|
1344
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1345
|
+
const privacy = {};
|
|
1346
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
1347
|
+
const reasons = value[api];
|
|
1348
|
+
if (reasons === undefined)
|
|
1349
|
+
continue;
|
|
1350
|
+
const supported = IOS_PRIVACY_ACCESSED_API_REASONS[api];
|
|
1351
|
+
if (!Array.isArray(reasons) || reasons.length === 0 || !reasons.every((reason) => typeof reason === "string" && supported.has(reason)))
|
|
1352
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
1353
|
+
privacy[api] = [...reasons];
|
|
1354
|
+
}
|
|
1355
|
+
if (Object.keys(value).some((api) => !IOS_PRIVACY_ACCESSED_APIS.some((known) => known === api)))
|
|
1356
|
+
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
1357
|
+
return privacy;
|
|
1358
|
+
}, iosNativeRequirements = (value, field) => {
|
|
1359
|
+
if (value === undefined)
|
|
1360
|
+
return;
|
|
1361
|
+
if (!object2(value))
|
|
1362
|
+
throw new TypeError(`${field} must be an object.`);
|
|
1363
|
+
const {
|
|
1364
|
+
privacyAccessedApis,
|
|
1365
|
+
pushNotifications,
|
|
1366
|
+
systemBars,
|
|
1367
|
+
usageDescriptions
|
|
1368
|
+
} = value;
|
|
1369
|
+
if (pushNotifications !== undefined && pushNotifications !== true)
|
|
1370
|
+
throw new TypeError(`${field}.pushNotifications must be true.`);
|
|
1371
|
+
if (systemBars !== undefined && systemBars !== true)
|
|
1372
|
+
throw new TypeError(`${field}.systemBars must be true.`);
|
|
1373
|
+
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
1374
|
+
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
1375
|
+
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
1376
|
+
return {
|
|
1377
|
+
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
1378
|
+
...pushNotifications === true ? { pushNotifications: true } : {},
|
|
1379
|
+
...systemBars === true ? { systemBars: true } : {},
|
|
1380
|
+
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
1381
|
+
};
|
|
1382
|
+
}, parseProvider = (name, value, providerName) => {
|
|
1383
|
+
if (!IDENTIFIER_PATTERN.test(name))
|
|
1384
|
+
throw new TypeError("Device capability names must be identifiers.");
|
|
1385
|
+
if (!object2(value))
|
|
1386
|
+
throw new TypeError(`Device capability ${name} must be an object.`);
|
|
1387
|
+
const factory = text(value.factory, `${name}.factory`);
|
|
1388
|
+
const module = text(value.module, `${name}.module`);
|
|
1389
|
+
if (!IDENTIFIER_PATTERN.test(factory))
|
|
1390
|
+
throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
|
|
1391
|
+
if (!providerModulePattern(providerName).test(module))
|
|
1392
|
+
throw new TypeError(`${name}.module must be an official devices-${providerName} subpath.`);
|
|
1393
|
+
if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && providerPackagePattern(providerName).test(spec)))
|
|
1394
|
+
throw new TypeError(`${name}.packages must contain exact official ${providerLabel(providerName)} package versions.`);
|
|
1395
|
+
const { plugins } = value;
|
|
1396
|
+
if (plugins !== undefined && (!Array.isArray(plugins) || !plugins.every((plugin) => typeof plugin === "string" && /^expo-[a-z][a-z0-9-]*$/u.test(plugin))))
|
|
1397
|
+
throw new TypeError(`${name}.plugins must contain Expo config plugin names.`);
|
|
1398
|
+
let native;
|
|
1399
|
+
const { native: nativeMetadata } = value;
|
|
1400
|
+
if (nativeMetadata !== undefined) {
|
|
1401
|
+
if (!object2(nativeMetadata))
|
|
1402
|
+
throw new TypeError(`${name}.native must be an object.`);
|
|
1403
|
+
const { android, ios } = nativeMetadata;
|
|
1404
|
+
const permissions = androidPermissions(android, `${name}.native.android`);
|
|
1405
|
+
const iosRequirements = iosNativeRequirements(ios, `${name}.native.ios`);
|
|
1406
|
+
native = {
|
|
1407
|
+
...permissions === undefined ? {} : { android: { permissions } },
|
|
1408
|
+
...iosRequirements === undefined ? {} : { ios: iosRequirements }
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
return {
|
|
1412
|
+
factory,
|
|
1413
|
+
module,
|
|
1414
|
+
...native === undefined ? {} : { native },
|
|
1415
|
+
...plugins === undefined ? {} : { plugins: [...plugins] },
|
|
1416
|
+
packages: [...value.packages]
|
|
1417
|
+
};
|
|
1418
|
+
}, absoluteDeviceNativeRequirements = (plan) => {
|
|
1419
|
+
const privacy = plan.capabilities.reduce((requirements, name) => {
|
|
1420
|
+
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
1421
|
+
const reasons = plan.providers[name]?.native?.ios?.privacyAccessedApis?.[api] ?? [];
|
|
1422
|
+
if (reasons.length === 0)
|
|
1423
|
+
continue;
|
|
1424
|
+
const current = requirements[api] ?? new Set;
|
|
1425
|
+
for (const reason of reasons)
|
|
1426
|
+
current.add(reason);
|
|
1427
|
+
requirements[api] = current;
|
|
1428
|
+
}
|
|
1429
|
+
return requirements;
|
|
1430
|
+
}, {});
|
|
1431
|
+
return {
|
|
1432
|
+
androidPermissions: [
|
|
1433
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
|
|
1434
|
+
].sort(),
|
|
1435
|
+
iosPrivacyAccessedApis: IOS_PRIVACY_ACCESSED_APIS.flatMap((api) => {
|
|
1436
|
+
const reasons = privacy[api];
|
|
1437
|
+
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
1438
|
+
}),
|
|
1439
|
+
iosPushNotifications: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.pushNotifications === true),
|
|
1440
|
+
iosSystemBars: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.systemBars === true),
|
|
1441
|
+
iosUsageDescriptions: [
|
|
1442
|
+
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
1443
|
+
].sort()
|
|
1444
|
+
};
|
|
1445
|
+
}, loadAbsoluteDeviceCapabilityProviders = (projectRoot, provider = "capacitor") => {
|
|
1446
|
+
const adapter = ADAPTERS[provider];
|
|
1447
|
+
let path = join7(resolve4(projectRoot), "node_modules", adapter, "package.json");
|
|
1448
|
+
try {
|
|
1449
|
+
readFileSync7(path, "utf8");
|
|
1450
|
+
} catch {
|
|
1451
|
+
path = fileURLToPath(import.meta.resolve(`${adapter}/package.json`));
|
|
1452
|
+
}
|
|
1453
|
+
const manifest = readJson(path);
|
|
1454
|
+
const { absolutejs } = manifest;
|
|
1455
|
+
const devices = object2(absolutejs) ? absolutejs.devices : undefined;
|
|
1456
|
+
if (!object2(devices) || devices.format !== 1 || devices.provider !== provider || !object2(devices.capabilities))
|
|
1457
|
+
throw new TypeError(`${adapter} does not publish supported capability metadata.`);
|
|
1458
|
+
const entries = Object.entries(devices.capabilities).map(([name, capability]) => ({
|
|
1459
|
+
name,
|
|
1460
|
+
provider: parseProvider(name, capability, provider)
|
|
1461
|
+
}));
|
|
1462
|
+
return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider: capabilityProvider }) => [
|
|
1463
|
+
name,
|
|
1464
|
+
capabilityProvider
|
|
1465
|
+
]));
|
|
1466
|
+
}, isIgnored = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment)), importedCapabilities = (source, file) => {
|
|
1467
|
+
const names = new Set;
|
|
1468
|
+
const namespaces = new Set;
|
|
1469
|
+
const visit = (node) => {
|
|
1470
|
+
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
|
|
1471
|
+
const bindings = node.importClause?.namedBindings;
|
|
1472
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
1473
|
+
for (const element of bindings.elements)
|
|
1474
|
+
if (!element.isTypeOnly)
|
|
1475
|
+
names.add((element.propertyName ?? element.name).text);
|
|
1476
|
+
}
|
|
1477
|
+
if (bindings && ts.isNamespaceImport(bindings))
|
|
1478
|
+
namespaces.add(bindings.name.text);
|
|
1479
|
+
}
|
|
1480
|
+
if (ts.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
1481
|
+
for (const element of node.exportClause.elements)
|
|
1482
|
+
if (!element.isTypeOnly)
|
|
1483
|
+
names.add((element.propertyName ?? element.name).text);
|
|
1484
|
+
}
|
|
1485
|
+
if (ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && namespaces.has(node.expression.text))
|
|
1486
|
+
names.add(node.name.text);
|
|
1487
|
+
ts.forEachChild(node, visit);
|
|
1488
|
+
};
|
|
1489
|
+
const extension = extname(file).toLowerCase();
|
|
1490
|
+
const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
|
|
1491
|
+
for (const [index, script] of sources.entries())
|
|
1492
|
+
visit(ts.createSourceFile(`${file}#script-${index}`, script, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX));
|
|
1493
|
+
return names;
|
|
1494
|
+
}, assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
|
|
1495
|
+
const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
|
|
1496
|
+
const mismatched = plan.requiredPackages.filter((spec) => {
|
|
1497
|
+
const separator = spec.lastIndexOf("@");
|
|
1498
|
+
const packageName = spec.slice(0, separator);
|
|
1499
|
+
if (missing.includes(spec))
|
|
1500
|
+
return false;
|
|
1501
|
+
try {
|
|
1502
|
+
return readJson(join7(resolve4(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
|
|
1503
|
+
} catch {
|
|
1504
|
+
return true;
|
|
1505
|
+
}
|
|
1506
|
+
});
|
|
1507
|
+
const unmet = [...missing, ...mismatched];
|
|
1508
|
+
if (unmet.length > 0)
|
|
1509
|
+
throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
|
|
1510
|
+
}, directAbsoluteProjectPackages = (projectRoot) => {
|
|
1511
|
+
const manifest = readJson(join7(resolve4(projectRoot), "package.json"));
|
|
1512
|
+
const packages = new Set;
|
|
1513
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
1514
|
+
const dependencies = manifest[field];
|
|
1515
|
+
if (object2(dependencies))
|
|
1516
|
+
for (const name of Object.keys(dependencies))
|
|
1517
|
+
packages.add(name);
|
|
1518
|
+
}
|
|
1519
|
+
return packages;
|
|
1520
|
+
}, discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
|
|
1521
|
+
const root = resolve4(projectRoot);
|
|
1522
|
+
if (!existsSync3(root))
|
|
1523
|
+
return [];
|
|
1524
|
+
const known = new Set(Object.keys(providers));
|
|
1525
|
+
const capabilities = new Set;
|
|
1526
|
+
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
1527
|
+
const portable = relative(root, resolve4(root, path)).replaceAll("\\", "/");
|
|
1528
|
+
if (isIgnored(portable))
|
|
1529
|
+
continue;
|
|
1530
|
+
const source = readFileSync7(resolve4(root, portable), "utf8");
|
|
1531
|
+
for (const name of importedCapabilities(source, portable))
|
|
1532
|
+
if (known.has(name))
|
|
1533
|
+
capabilities.add(name);
|
|
1534
|
+
}
|
|
1535
|
+
return [...capabilities].sort();
|
|
1536
|
+
}, missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
|
|
1537
|
+
const packageName = spec.slice(0, spec.lastIndexOf("@"));
|
|
1538
|
+
return !directPackages.has(packageName);
|
|
1539
|
+
}), resolveAbsoluteDeviceCapabilityPlan = (projectRoot, provider = "capacitor") => {
|
|
1540
|
+
const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot, provider);
|
|
1541
|
+
const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
|
|
1542
|
+
const providers = {};
|
|
1543
|
+
for (const name of capabilities) {
|
|
1544
|
+
const capabilityProvider = allProviders[name];
|
|
1545
|
+
if (capabilityProvider)
|
|
1546
|
+
providers[name] = capabilityProvider;
|
|
1547
|
+
}
|
|
1548
|
+
return {
|
|
1549
|
+
capabilities,
|
|
1550
|
+
providers,
|
|
1551
|
+
requiredPackages: [
|
|
1552
|
+
...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
|
|
1553
|
+
].sort()
|
|
1554
|
+
};
|
|
1555
|
+
};
|
|
1556
|
+
var init_deviceCapabilities = __esm(() => {
|
|
1557
|
+
ADAPTERS = {
|
|
1558
|
+
capacitor: "@absolutejs/devices-capacitor",
|
|
1559
|
+
expo: "@absolutejs/devices-expo"
|
|
1560
|
+
};
|
|
1561
|
+
SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
|
|
1562
|
+
IGNORED_DIRECTORIES = new Set([
|
|
1563
|
+
".absolutejs",
|
|
1564
|
+
".git",
|
|
1565
|
+
".test-builds",
|
|
1566
|
+
".test-shards",
|
|
1567
|
+
"build",
|
|
1568
|
+
"dist",
|
|
1569
|
+
"node_modules",
|
|
1570
|
+
"test",
|
|
1571
|
+
"tests"
|
|
1572
|
+
]);
|
|
1573
|
+
IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
|
|
1574
|
+
ANDROID_PERMISSION_PATTERN = /^android\.permission\.[A-Z][A-Z0-9_]*$/u;
|
|
1575
|
+
IOS_USAGE_DESCRIPTIONS = new Set([
|
|
1576
|
+
"camera",
|
|
1577
|
+
"location-always",
|
|
1578
|
+
"location-when-in-use",
|
|
1579
|
+
"photo-library",
|
|
1580
|
+
"photo-library-add"
|
|
1581
|
+
]);
|
|
1582
|
+
IOS_PRIVACY_ACCESSED_API_REASONS = {
|
|
1583
|
+
NSPrivacyAccessedAPICategoryFileTimestamp: new Set(["C617.1"])
|
|
1584
|
+
};
|
|
1585
|
+
IOS_PRIVACY_ACCESSED_APIS = [
|
|
1586
|
+
"NSPrivacyAccessedAPICategoryFileTimestamp"
|
|
1587
|
+
];
|
|
1588
|
+
});
|
|
1589
|
+
|
|
1317
1590
|
// src/mobile/expoProject.ts
|
|
1318
1591
|
import {
|
|
1319
1592
|
access,
|
|
@@ -1327,7 +1600,7 @@ import {
|
|
|
1327
1600
|
writeFile
|
|
1328
1601
|
} from "fs/promises";
|
|
1329
1602
|
import { createHash } from "crypto";
|
|
1330
|
-
import { basename as basename2, dirname as dirname4, join as
|
|
1603
|
+
import { basename as basename2, dirname as dirname4, join as join8, relative as relative2, resolve as resolve5 } from "path";
|
|
1331
1604
|
var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1332
1605
|
`, EXPO_ASSET_EXTENSION = ".absasset", EXPO_PROJECT_MARKER = ".absolutejs-expo-project", exists = async (path) => {
|
|
1333
1606
|
try {
|
|
@@ -1337,7 +1610,7 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1337
1610
|
return false;
|
|
1338
1611
|
}
|
|
1339
1612
|
}, portableRelative = (from, destination) => {
|
|
1340
|
-
const value =
|
|
1613
|
+
const value = relative2(from, destination).replaceAll("\\", "/");
|
|
1341
1614
|
return value.startsWith(".") ? value : `./${value}`;
|
|
1342
1615
|
}, routeSegments = (route) => route.split("/").filter(Boolean).map((segment) => {
|
|
1343
1616
|
if (segment.startsWith(":"))
|
|
@@ -1346,8 +1619,13 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1346
1619
|
throw new TypeError(`Expo native route ${route} contains an unsupported segment ${segment}.`);
|
|
1347
1620
|
}
|
|
1348
1621
|
return segment;
|
|
1349
|
-
}), routeFile = (project, route) =>
|
|
1622
|
+
}), routeFile = (project, route) => join8(project, "app", ...routeSegments(route), "index.tsx"), packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
1623
|
+
const separator = spec.lastIndexOf("@");
|
|
1624
|
+
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
1625
|
+
})), expoPackage = (auth, sync, devices) => ({
|
|
1350
1626
|
dependencies: {
|
|
1627
|
+
"@absolutejs/devices": "0.7.0",
|
|
1628
|
+
"@absolutejs/devices-expo": "0.0.2",
|
|
1351
1629
|
...auth ? {
|
|
1352
1630
|
"@absolutejs/auth": ABSOLUTE_EXPO_AUTH_CORE_VERSION,
|
|
1353
1631
|
[ABSOLUTE_EXPO_AUTH_PACKAGE]: ABSOLUTE_EXPO_AUTH_VERSION
|
|
@@ -1379,7 +1657,8 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1379
1657
|
"react-native": "0.86.3",
|
|
1380
1658
|
"react-native-safe-area-context": "~5.7.0",
|
|
1381
1659
|
"react-native-screens": "4.26.0",
|
|
1382
|
-
"react-native-webview": "13.16.1"
|
|
1660
|
+
"react-native-webview": "13.16.1",
|
|
1661
|
+
...packageDependencies(devices)
|
|
1383
1662
|
},
|
|
1384
1663
|
devDependencies: {
|
|
1385
1664
|
"@types/react": "~19.2.2",
|
|
@@ -1394,36 +1673,107 @@ var EXPO_GENERATED_HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts
|
|
|
1394
1673
|
start: "expo start --dev-client"
|
|
1395
1674
|
},
|
|
1396
1675
|
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
|
-
|
|
1676
|
+
}), expoAppConfig = (config, auth, sync, devices) => {
|
|
1677
|
+
const requirements = absoluteDeviceNativeRequirements(devices);
|
|
1678
|
+
const usageKey = (purpose) => {
|
|
1679
|
+
if (purpose === "camera")
|
|
1680
|
+
return "NSCameraUsageDescription";
|
|
1681
|
+
if (purpose === "photo-library")
|
|
1682
|
+
return "NSPhotoLibraryUsageDescription";
|
|
1683
|
+
if (purpose === "photo-library-add")
|
|
1684
|
+
return "NSPhotoLibraryAddUsageDescription";
|
|
1685
|
+
if (purpose === "location-always")
|
|
1686
|
+
return "NSLocationAlwaysAndWhenInUseUsageDescription";
|
|
1687
|
+
return "NSLocationWhenInUseUsageDescription";
|
|
1688
|
+
};
|
|
1689
|
+
const usageDescription = (purpose) => {
|
|
1690
|
+
if (purpose === "camera")
|
|
1691
|
+
return `${config.appName} uses your camera when you choose to take a photo.`;
|
|
1692
|
+
if (purpose === "photo-library")
|
|
1693
|
+
return `${config.appName} accesses your photo library only for photo actions you choose.`;
|
|
1694
|
+
if (purpose.startsWith("location-"))
|
|
1695
|
+
return `${config.appName} uses your location only while you use the app and request a location-based action.`;
|
|
1696
|
+
return `${config.appName} adds to your photo library only for photo actions you choose.`;
|
|
1697
|
+
};
|
|
1698
|
+
const descriptions = Object.fromEntries(requirements.iosUsageDescriptions.map((purpose) => [
|
|
1699
|
+
usageKey(purpose),
|
|
1700
|
+
usageDescription(purpose)
|
|
1701
|
+
]));
|
|
1702
|
+
const devicePlugins = [
|
|
1703
|
+
...new Set(devices.capabilities.flatMap((name) => devices.providers[name]?.plugins ?? []))
|
|
1704
|
+
];
|
|
1705
|
+
const configuredPlugins = devicePlugins.map((plugin) => {
|
|
1706
|
+
if (plugin === "expo-image-picker")
|
|
1707
|
+
return [
|
|
1708
|
+
plugin,
|
|
1709
|
+
{
|
|
1710
|
+
cameraPermission: descriptions.NSCameraUsageDescription,
|
|
1711
|
+
microphonePermission: false,
|
|
1712
|
+
photosPermission: descriptions.NSPhotoLibraryUsageDescription
|
|
1713
|
+
}
|
|
1714
|
+
];
|
|
1715
|
+
if (plugin === "expo-location")
|
|
1716
|
+
return [
|
|
1717
|
+
plugin,
|
|
1718
|
+
{
|
|
1719
|
+
locationWhenInUsePermission: descriptions.NSLocationWhenInUseUsageDescription
|
|
1720
|
+
}
|
|
1721
|
+
];
|
|
1722
|
+
return plugin;
|
|
1723
|
+
});
|
|
1724
|
+
return {
|
|
1725
|
+
expo: {
|
|
1726
|
+
android: {
|
|
1727
|
+
...devicePlugins.includes("expo-image-picker") ? {
|
|
1728
|
+
blockedPermissions: [
|
|
1729
|
+
"android.permission.READ_EXTERNAL_STORAGE",
|
|
1730
|
+
"android.permission.RECORD_AUDIO",
|
|
1731
|
+
"android.permission.WRITE_EXTERNAL_STORAGE"
|
|
1732
|
+
]
|
|
1733
|
+
} : {},
|
|
1734
|
+
intentFilters: config.deepLinkHosts.map((host2) => ({
|
|
1735
|
+
action: "VIEW",
|
|
1736
|
+
autoVerify: true,
|
|
1737
|
+
category: ["BROWSABLE", "DEFAULT"],
|
|
1738
|
+
data: [{ host: host2, pathPrefix: "/", scheme: "https" }]
|
|
1739
|
+
})),
|
|
1740
|
+
package: config.appId,
|
|
1741
|
+
permissions: requirements.androidPermissions
|
|
1742
|
+
},
|
|
1743
|
+
experiments: { typedRoutes: true },
|
|
1744
|
+
ios: {
|
|
1745
|
+
associatedDomains: config.deepLinkHosts.map((host2) => `applinks:${host2}`),
|
|
1746
|
+
bundleIdentifier: config.appId,
|
|
1747
|
+
infoPlist: descriptions,
|
|
1748
|
+
...requirements.iosPrivacyAccessedApis.length > 0 ? {
|
|
1749
|
+
privacyManifests: {
|
|
1750
|
+
NSPrivacyAccessedAPITypes: requirements.iosPrivacyAccessedApis.map(({ api, reasons }) => ({
|
|
1751
|
+
NSPrivacyAccessedAPIType: api,
|
|
1752
|
+
NSPrivacyAccessedAPITypeReasons: reasons
|
|
1753
|
+
}))
|
|
1754
|
+
}
|
|
1755
|
+
} : {},
|
|
1756
|
+
...config.iosVersion ? { buildNumber: config.iosVersion } : {}
|
|
1757
|
+
},
|
|
1758
|
+
name: config.appName,
|
|
1759
|
+
plugins: [
|
|
1760
|
+
"expo-router",
|
|
1761
|
+
["expo-dev-client", { launchMode: "most-recent" }],
|
|
1762
|
+
...auth ? ["expo-secure-store"] : [],
|
|
1763
|
+
...sync ? [
|
|
1764
|
+
"expo-sqlite",
|
|
1765
|
+
"expo-background-task",
|
|
1766
|
+
"expo-task-manager"
|
|
1767
|
+
] : [],
|
|
1768
|
+
...configuredPlugins
|
|
1769
|
+
],
|
|
1770
|
+
runtimeVersion: { policy: "appVersion" },
|
|
1771
|
+
scheme: config.deepLinkScheme,
|
|
1772
|
+
slug: config.appId.toLowerCase().replaceAll(".", "-"),
|
|
1773
|
+
version: config.iosVersion ?? "0.1.0"
|
|
1774
|
+
}
|
|
1775
|
+
};
|
|
1776
|
+
}, expoDynamicAppConfig, expoDevelopmentCaPlugin, metroConfig = (projectRoot) => `${EXPO_GENERATED_HEADER}const { getDefaultConfig } = require('expo/metro-config');
|
|
1427
1777
|
const path = require('node:path');
|
|
1428
1778
|
|
|
1429
1779
|
const projectRoot = __dirname;
|
|
@@ -1438,6 +1788,7 @@ config.watchFolders = [appRoot];
|
|
|
1438
1788
|
|
|
1439
1789
|
module.exports = config;
|
|
1440
1790
|
`, layoutSource = (auth, sync) => `${EXPO_GENERATED_HEADER}import { Stack } from 'expo-router';
|
|
1791
|
+
import '../src/generated/AbsoluteDevices';
|
|
1441
1792
|
${auth ? `import { useEffect, useState } from 'react';
|
|
1442
1793
|
import { startAbsoluteExpoAuth } from '../src/generated/AbsoluteAuth';` : ""}
|
|
1443
1794
|
${sync ? "import { startAbsoluteExpoSync } from '../src/generated/AbsoluteSync';" : ""}
|
|
@@ -1452,7 +1803,76 @@ export default function AbsoluteLayout() {
|
|
|
1452
1803
|
if (!ready) return null;` : ""}
|
|
1453
1804
|
return <Stack screenOptions={{ headerShown: false }} />;
|
|
1454
1805
|
}
|
|
1455
|
-
`, nativeDiagnosticSource,
|
|
1806
|
+
`, nativeDiagnosticSource, devicesRuntimeSource = (config, plan, auth) => {
|
|
1807
|
+
const imports = plan.capabilities.map((name, index) => {
|
|
1808
|
+
const provider = plan.providers[name];
|
|
1809
|
+
if (!provider)
|
|
1810
|
+
throw new TypeError(`Missing Expo device capability provider ${name}.`);
|
|
1811
|
+
return `import { ${provider.factory} as absoluteExpoCapability${index} } from ${JSON.stringify(provider.module)};`;
|
|
1812
|
+
});
|
|
1813
|
+
const pushIndex = plan.capabilities.indexOf("pushNotifications");
|
|
1814
|
+
const push = pushIndex !== -1;
|
|
1815
|
+
if (push && !auth)
|
|
1816
|
+
throw new TypeError("Expo push notifications require the provisioned AbsoluteJS Auth runtime.");
|
|
1817
|
+
const entries = plan.capabilities.map((name, index) => `${JSON.stringify(name)}: absoluteExpoCapability${index}(${name === "pushNotifications" ? "absoluteExpoPushOptions" : ""})`).join(`,
|
|
1818
|
+
`);
|
|
1819
|
+
const pushSource = push ? `const INSTALLATION_KEY = 'absolutejs.push.installation-id';
|
|
1820
|
+
const requirePushResponse = async (response: Response, operation: string) => {
|
|
1821
|
+
if (!response.ok) throw new Error(\`AbsoluteJS native push \${operation} failed with HTTP \${response.status}.\`);
|
|
1822
|
+
return response.json() as Promise<Record<string, unknown>>;
|
|
1823
|
+
};
|
|
1824
|
+
const absoluteExpoPushOptions = {
|
|
1825
|
+
onRegistration: async (registration: { platform: 'apns' | 'fcm'; token: string }) => {
|
|
1826
|
+
const known = await absoluteExpoDevices.storage.get(INSTALLATION_KEY);
|
|
1827
|
+
const register = (installationId?: string | null) => absoluteExpoAuth.fetch('/auth/push', {
|
|
1828
|
+
body: JSON.stringify({ ...(installationId ? { installationId } : {}), platform: registration.platform, token: registration.token }),
|
|
1829
|
+
headers: { 'content-type': 'application/json' },
|
|
1830
|
+
method: 'POST'
|
|
1831
|
+
});
|
|
1832
|
+
let response = await register(known);
|
|
1833
|
+
const conflict = response.status === 409 && await response.clone().json().then(value => typeof value === 'object' && value !== null && Reflect.get(value, 'code') === 'installation-ownership').catch(() => false);
|
|
1834
|
+
if (known && conflict) {
|
|
1835
|
+
await absoluteExpoDevices.storage.remove(INSTALLATION_KEY);
|
|
1836
|
+
response = await register();
|
|
1837
|
+
}
|
|
1838
|
+
const result = await requirePushResponse(response, 'registration');
|
|
1839
|
+
if (typeof result.installationId !== 'string' || !result.installationId || result.installationId.length > 128) throw new Error('AbsoluteJS native push returned an invalid installation identity.');
|
|
1840
|
+
await absoluteExpoDevices.storage.set(INSTALLATION_KEY, result.installationId);
|
|
1841
|
+
},
|
|
1842
|
+
onUnregistration: async () => {
|
|
1843
|
+
const installationId = await absoluteExpoDevices.storage.get(INSTALLATION_KEY);
|
|
1844
|
+
if (!installationId) return;
|
|
1845
|
+
await requirePushResponse(await absoluteExpoAuth.fetch('/auth/push', {
|
|
1846
|
+
body: JSON.stringify({ installationId }),
|
|
1847
|
+
headers: { 'content-type': 'application/json' },
|
|
1848
|
+
method: 'DELETE'
|
|
1849
|
+
}), 'removal');
|
|
1850
|
+
await absoluteExpoDevices.storage.remove(INSTALLATION_KEY);
|
|
1851
|
+
}
|
|
1852
|
+
};` : "";
|
|
1853
|
+
return `${EXPO_GENERATED_HEADER}import { installDeviceAdapter } from '@absolutejs/devices/runtime';
|
|
1854
|
+
import { createExpoDeviceAdapter } from '@absolutejs/devices-expo';
|
|
1855
|
+
${push ? "import { absoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
1856
|
+
${imports.join(`
|
|
1857
|
+
`)}
|
|
1858
|
+
|
|
1859
|
+
${pushSource}
|
|
1860
|
+
|
|
1861
|
+
export const absoluteExpoDeviceCapabilities = ${JSON.stringify(plan.capabilities)} as const;
|
|
1862
|
+
export const absoluteExpoDevices = createExpoDeviceAdapter({
|
|
1863
|
+
storagePrefix: ${JSON.stringify(`absolutejs.${config.appId}.`)},
|
|
1864
|
+
${entries}
|
|
1865
|
+
});
|
|
1866
|
+
installDeviceAdapter(absoluteExpoDevices);
|
|
1867
|
+
export const beforeAbsoluteExpoDeviceSignOut = async () => {
|
|
1868
|
+
${push ? "await absoluteExpoDevices.pushNotifications?.disable();" : ""}
|
|
1869
|
+
};
|
|
1870
|
+
${push ? `absoluteExpoAuth.onPrincipalChange(principal => {
|
|
1871
|
+
if (!principal) return;
|
|
1872
|
+
void absoluteExpoDevices.pushNotifications?.queryPermission().then(permission => permission.state === 'granted' ? absoluteExpoDevices.pushNotifications?.enable() : undefined).catch(() => undefined);
|
|
1873
|
+
});` : ""}
|
|
1874
|
+
`;
|
|
1875
|
+
}, authRuntimeSource = (auth, appId) => {
|
|
1456
1876
|
const storageIdentity = createHash("sha256").update(appId).digest("hex").slice(0, 24);
|
|
1457
1877
|
return `${EXPO_GENERATED_HEADER}import { createAbsoluteExpoAuthClient } from '@absolutejs/auth-expo';
|
|
1458
1878
|
import { createMobileAuthTransport, installAuthClientRuntimeTransport } from '@absolutejs/auth/client/mobile';
|
|
@@ -1585,13 +2005,14 @@ export const createAbsoluteExpoSyncBridge = async (
|
|
|
1585
2005
|
"/__absolute/native",
|
|
1586
2006
|
...Object.keys(config.expoNativeRoutes)
|
|
1587
2007
|
];
|
|
1588
|
-
return `${EXPO_GENERATED_HEADER}import * as
|
|
1589
|
-
import * as Linking from 'expo-linking';
|
|
2008
|
+
return `${EXPO_GENERATED_HEADER}import * as Linking from 'expo-linking';
|
|
1590
2009
|
import { router, usePathname } from 'expo-router';
|
|
1591
2010
|
import { useEffect, useRef, useState } from 'react';
|
|
1592
2011
|
import { ActivityIndicator, BackHandler, Platform, StyleSheet, View } from 'react-native';
|
|
1593
2012
|
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
|
|
1594
2013
|
import { materializeAbsoluteWebBundle } from './webAssets';
|
|
2014
|
+
import { createExpoDevicesBridgeHost } from '@absolutejs/devices-expo/bridge';
|
|
2015
|
+
import { absoluteExpoDevices, beforeAbsoluteExpoDeviceSignOut } from './AbsoluteDevices';
|
|
1595
2016
|
${auth ? "import { absoluteExpoAuth, getAbsoluteExpoAuthPrincipal, startAbsoluteExpoAuth } from './AbsoluteAuth';" : ""}
|
|
1596
2017
|
${sync ? "import { createAbsoluteExpoSyncBridge, startAbsoluteExpoSync } from './AbsoluteSync';" : ""}
|
|
1597
2018
|
|
|
@@ -1647,10 +2068,11 @@ const bridgeBootstrap = (path: string) => {
|
|
|
1647
2068
|
const id = 'web_' + Date.now().toString(36) + '_' + (++sequence).toString(36);
|
|
1648
2069
|
send({ format: 3, id, kind: 'request', method, params, path: currentPath });
|
|
1649
2070
|
return new Promise((resolve, reject) => {
|
|
2071
|
+
const interactive = method.startsWith('devices.camera.') || method.startsWith('devices.photos.') || method.startsWith('devices.documents.') || method.endsWith('.requestPermission');
|
|
1650
2072
|
const timer = setTimeout(() => {
|
|
1651
2073
|
pending.delete(id);
|
|
1652
2074
|
reject(new Error('Expo bridge request timed out.'));
|
|
1653
|
-
},
|
|
2075
|
+
}, interactive ? 5 * 60 * 1000 : 30 * 1000);
|
|
1654
2076
|
pending.set(id, { reject, resolve, timer });
|
|
1655
2077
|
});
|
|
1656
2078
|
},
|
|
@@ -1689,17 +2111,6 @@ const bridgeBootstrap = (path: string) => {
|
|
|
1689
2111
|
})(); true;\`;
|
|
1690
2112
|
};
|
|
1691
2113
|
|
|
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
2114
|
const bridgeFetch = async (params: Record<string, unknown>) => {
|
|
1704
2115
|
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
2116
|
const url = new URL(params.url);
|
|
@@ -1731,10 +2142,12 @@ const authStatus = async () => {
|
|
|
1731
2142
|
export function AbsoluteWebHost() {
|
|
1732
2143
|
const pathname = usePathname() || '/';
|
|
1733
2144
|
const webView = useRef<WebView>(null);
|
|
2145
|
+
const devicesBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
1734
2146
|
const syncBridge = useRef<{ close(): void | Promise<void>; request(method: string, params: Record<string, unknown>): Promise<unknown> } | undefined>(undefined);
|
|
1735
2147
|
const [indexUri, setIndexUri] = useState<string>();
|
|
1736
2148
|
const [canGoBack, setCanGoBack] = useState(false);
|
|
1737
2149
|
const [runtimeReady, setRuntimeReady] = useState(!AUTH_ENABLED && !SYNC_ENABLED);
|
|
2150
|
+
const [devicesReady, setDevicesReady] = useState(false);
|
|
1738
2151
|
const activeWebPath = useRef(pathname);
|
|
1739
2152
|
|
|
1740
2153
|
useEffect(() => {
|
|
@@ -1784,6 +2197,23 @@ export function AbsoluteWebHost() {
|
|
|
1784
2197
|
if (new TextEncoder().encode(source).byteLength > MAX_MESSAGE_BYTES) throw new Error('Expo bridge response exceeds 64 KiB.');
|
|
1785
2198
|
webView.current?.injectJavaScript(\`globalThis.__absoluteExpoReceive(\${JSON.stringify(source)}); true;\`);
|
|
1786
2199
|
};
|
|
2200
|
+
useEffect(() => {
|
|
2201
|
+
let active = true;
|
|
2202
|
+
void createExpoDevicesBridgeHost(absoluteExpoDevices, (event, payload) => {
|
|
2203
|
+
if (!active) return;
|
|
2204
|
+
respond({ event, format: BRIDGE_FORMAT, kind: 'event', path: activeWebPath.current, payload });
|
|
2205
|
+
}).then(host => {
|
|
2206
|
+
if (!active) return void host.close();
|
|
2207
|
+
devicesBridge.current = host;
|
|
2208
|
+
setDevicesReady(true);
|
|
2209
|
+
});
|
|
2210
|
+
return () => {
|
|
2211
|
+
active = false;
|
|
2212
|
+
const host = devicesBridge.current;
|
|
2213
|
+
devicesBridge.current = undefined;
|
|
2214
|
+
void host?.close();
|
|
2215
|
+
};
|
|
2216
|
+
}, []);
|
|
1787
2217
|
const hasOrigin = (source: string, origin: string) => {
|
|
1788
2218
|
try { return new URL(source).origin === origin; } catch { return false; }
|
|
1789
2219
|
};
|
|
@@ -1803,11 +2233,9 @@ export function AbsoluteWebHost() {
|
|
|
1803
2233
|
if (message.kind !== 'request' || typeof message.id !== 'string' || message.path !== activeWebPath.current) return;
|
|
1804
2234
|
try {
|
|
1805
2235
|
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 });
|
|
2236
|
+
if (typeof message.method === 'string' && message.method.startsWith('devices.')) {
|
|
2237
|
+
if (!devicesBridge.current) throw new Error('Expo devices bridge is unavailable.');
|
|
2238
|
+
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await devicesBridge.current.request(message.method, message.params as Record<string, unknown>) });
|
|
1811
2239
|
} else if (message.method === 'http.fetch') {
|
|
1812
2240
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await bridgeFetch(message.params as Record<string, unknown>) });
|
|
1813
2241
|
} else if (message.method === 'auth.signIn') {
|
|
@@ -1816,7 +2244,8 @@ export function AbsoluteWebHost() {
|
|
|
1816
2244
|
await absoluteExpoAuth.signIn({ authorizationParameters: { login_hint: params.email, ...(params.signup ? { screen_hint: 'signup' } : {}) } });
|
|
1817
2245
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });` : "throw new Error('Expo Auth is not configured.');"}
|
|
1818
2246
|
} else if (message.method === 'auth.signOut') {
|
|
1819
|
-
${auth ? `await
|
|
2247
|
+
${auth ? `await beforeAbsoluteExpoDeviceSignOut();
|
|
2248
|
+
await absoluteExpoAuth.signOut();
|
|
1820
2249
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: null });` : "throw new Error('Expo Auth is not configured.');"}
|
|
1821
2250
|
} else if (message.method === 'auth.status') {
|
|
1822
2251
|
respond({ format: BRIDGE_FORMAT, id: message.id, kind: 'response', result: await authStatus() });
|
|
@@ -1831,7 +2260,7 @@ export function AbsoluteWebHost() {
|
|
|
1831
2260
|
}
|
|
1832
2261
|
};
|
|
1833
2262
|
|
|
1834
|
-
if (!indexUri || !runtimeReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
2263
|
+
if (!indexUri || !runtimeReady || !devicesReady) return <View style={styles.loading}><ActivityIndicator /></View>;
|
|
1835
2264
|
return <WebView
|
|
1836
2265
|
allowFileAccess
|
|
1837
2266
|
allowFileAccessFromFileURLs
|
|
@@ -1907,9 +2336,10 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1907
2336
|
`, emptyWebAssetsSource, writeAbsoluteExpoProject = async (config, options) => {
|
|
1908
2337
|
if (config.engine !== "expo")
|
|
1909
2338
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
1910
|
-
const projectRoot =
|
|
2339
|
+
const projectRoot = resolve5(options.projectRoot);
|
|
1911
2340
|
const project = config.nativeProjectDirectory;
|
|
1912
2341
|
const auth = resolveAbsoluteMobileAuthManifest(projectRoot, config);
|
|
2342
|
+
const devices = resolveAbsoluteDeviceCapabilityPlan(projectRoot, "expo");
|
|
1913
2343
|
const syncEnabled = Boolean(auth && projectUsesAbsoluteSync(projectRoot));
|
|
1914
2344
|
const syncSchema = syncEnabled ? { components: discoverAbsoluteSyncSchema(projectRoot).components } : undefined;
|
|
1915
2345
|
const routeModules = Object.entries(config.expoNativeRoutes);
|
|
@@ -1922,7 +2352,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1922
2352
|
if (missing) {
|
|
1923
2353
|
throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
|
|
1924
2354
|
}
|
|
1925
|
-
const marker =
|
|
2355
|
+
const marker = join8(project, EXPO_PROJECT_MARKER);
|
|
1926
2356
|
if (await exists(project) && !await exists(marker)) {
|
|
1927
2357
|
const entries = await readdir(project);
|
|
1928
2358
|
if (entries.length > 0 && !options.force) {
|
|
@@ -1935,7 +2365,7 @@ const styles = StyleSheet.create({ loading: { alignItems: 'center', flex: 1, jus
|
|
|
1935
2365
|
const authEnabled = Boolean(auth);
|
|
1936
2366
|
const files = new Map([
|
|
1937
2367
|
[
|
|
1938
|
-
|
|
2368
|
+
join8(project, ".gitignore"),
|
|
1939
2369
|
`.expo/
|
|
1940
2370
|
android/
|
|
1941
2371
|
ios/
|
|
@@ -1943,52 +2373,56 @@ node_modules/
|
|
|
1943
2373
|
`
|
|
1944
2374
|
],
|
|
1945
2375
|
[
|
|
1946
|
-
|
|
1947
|
-
jsonSource(expoAppConfig(config, authEnabled, syncEnabled))
|
|
2376
|
+
join8(project, "app.json"),
|
|
2377
|
+
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices))
|
|
1948
2378
|
],
|
|
1949
|
-
[
|
|
2379
|
+
[join8(project, "app.config.js"), expoDynamicAppConfig],
|
|
1950
2380
|
[
|
|
1951
|
-
|
|
1952
|
-
jsonSource(expoPackage(authEnabled, syncEnabled))
|
|
2381
|
+
join8(project, "package.json"),
|
|
2382
|
+
jsonSource(expoPackage(authEnabled, syncEnabled, devices))
|
|
1953
2383
|
],
|
|
1954
|
-
[
|
|
2384
|
+
[join8(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
1955
2385
|
[
|
|
1956
|
-
|
|
2386
|
+
join8(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
1957
2387
|
expoDevelopmentCaPlugin
|
|
1958
2388
|
],
|
|
1959
2389
|
[
|
|
1960
|
-
|
|
2390
|
+
join8(project, "tsconfig.json"),
|
|
1961
2391
|
jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
|
|
1962
2392
|
],
|
|
1963
2393
|
[
|
|
1964
|
-
|
|
2394
|
+
join8(project, "app", "_layout.tsx"),
|
|
1965
2395
|
layoutSource(authEnabled, syncEnabled)
|
|
1966
2396
|
],
|
|
1967
2397
|
[
|
|
1968
|
-
|
|
2398
|
+
join8(project, "app", "__absolute", "native", "index.tsx"),
|
|
1969
2399
|
nativeDiagnosticSource
|
|
1970
2400
|
],
|
|
1971
2401
|
[
|
|
1972
|
-
|
|
2402
|
+
join8(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
2403
|
+
devicesRuntimeSource(config, devices, authEnabled)
|
|
2404
|
+
],
|
|
2405
|
+
[
|
|
2406
|
+
join8(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
1973
2407
|
webHostSource(config, auth, syncEnabled)
|
|
1974
2408
|
]
|
|
1975
2409
|
]);
|
|
1976
2410
|
if (auth) {
|
|
1977
|
-
files.set(
|
|
2411
|
+
files.set(join8(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
1978
2412
|
}
|
|
1979
2413
|
if (syncSchema) {
|
|
1980
|
-
files.set(
|
|
2414
|
+
files.set(join8(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
1981
2415
|
}
|
|
1982
|
-
const webAssetsPath =
|
|
2416
|
+
const webAssetsPath = join8(project, "src", "generated", "webAssets.ts");
|
|
1983
2417
|
if (!await exists(webAssetsPath)) {
|
|
1984
2418
|
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
1985
2419
|
}
|
|
1986
2420
|
if (!config.expoNativeRoutes["/"]) {
|
|
1987
|
-
files.set(
|
|
2421
|
+
files.set(join8(project, "app", "index.tsx"), webRouteSource);
|
|
1988
2422
|
}
|
|
1989
|
-
files.set(
|
|
2423
|
+
files.set(join8(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
1990
2424
|
for (const [route, module] of routeModules) {
|
|
1991
|
-
const wrapper = route === "/" ?
|
|
2425
|
+
const wrapper = route === "/" ? join8(project, "app", "index.tsx") : routeFile(project, route);
|
|
1992
2426
|
files.set(wrapper, nativeWrapperSource(wrapper, module));
|
|
1993
2427
|
}
|
|
1994
2428
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
@@ -1997,7 +2431,7 @@ node_modules/
|
|
|
1997
2431
|
}, walkFiles = async (root, directory = root) => {
|
|
1998
2432
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
1999
2433
|
const nested = await Promise.all(entries.map((entry) => {
|
|
2000
|
-
const path =
|
|
2434
|
+
const path = join8(directory, entry.name);
|
|
2001
2435
|
if (entry.isDirectory())
|
|
2002
2436
|
return walkFiles(root, path);
|
|
2003
2437
|
if (entry.isFile())
|
|
@@ -2058,11 +2492,11 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2058
2492
|
`, syncAbsoluteExpoWebAssets = async (config) => {
|
|
2059
2493
|
if (config.engine !== "expo")
|
|
2060
2494
|
throw new TypeError("Expo asset sync requires mobile.engine: expo.");
|
|
2061
|
-
const marker =
|
|
2495
|
+
const marker = join8(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
|
|
2062
2496
|
if (!await exists(marker)) {
|
|
2063
2497
|
throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
|
|
2064
2498
|
}
|
|
2065
|
-
const manifestPath =
|
|
2499
|
+
const manifestPath = join8(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
2066
2500
|
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
2067
2501
|
const appBuild = typeof manifest === "object" && manifest !== null && typeof Reflect.get(manifest, "appBuild") === "string" ? String(Reflect.get(manifest, "appBuild")) : undefined;
|
|
2068
2502
|
if (!appBuild)
|
|
@@ -2071,23 +2505,23 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2071
2505
|
const bundleHash = createHash("sha256");
|
|
2072
2506
|
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile(file), file })));
|
|
2073
2507
|
filesWithContents.forEach(({ contents, file }) => {
|
|
2074
|
-
bundleHash.update(
|
|
2508
|
+
bundleHash.update(relative2(config.bundleDirectory, file).replaceAll("\\", "/"));
|
|
2075
2509
|
bundleHash.update("\x00");
|
|
2076
2510
|
bundleHash.update(contents);
|
|
2077
2511
|
bundleHash.update("\x00");
|
|
2078
2512
|
});
|
|
2079
2513
|
const bundleId = `amexpo_${bundleHash.digest("hex")}`;
|
|
2080
|
-
const destination =
|
|
2514
|
+
const destination = join8(config.nativeProjectDirectory, "assets", "absolute");
|
|
2081
2515
|
await mkdir(dirname4(destination), { recursive: true });
|
|
2082
|
-
const staging = await mkdtemp(
|
|
2516
|
+
const staging = await mkdtemp(join8(dirname4(destination), `.${basename2(destination)}.stage-`));
|
|
2083
2517
|
let assets;
|
|
2084
2518
|
try {
|
|
2085
2519
|
assets = await Promise.all(files.map(async (source, index) => {
|
|
2086
2520
|
const name = `${String(index).padStart(6, "0")}${EXPO_ASSET_EXTENSION}`;
|
|
2087
|
-
await cp(source,
|
|
2521
|
+
await cp(source, join8(staging, name));
|
|
2088
2522
|
return {
|
|
2089
|
-
asset: portableRelative(
|
|
2090
|
-
path:
|
|
2523
|
+
asset: portableRelative(join8(config.nativeProjectDirectory, "src", "generated"), join8(destination, name)),
|
|
2524
|
+
path: relative2(config.bundleDirectory, source).replaceAll("\\", "/")
|
|
2091
2525
|
};
|
|
2092
2526
|
}));
|
|
2093
2527
|
await installStagedDirectory(staging, destination);
|
|
@@ -2095,13 +2529,14 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
2095
2529
|
await rm(staging, { force: true, recursive: true });
|
|
2096
2530
|
throw error;
|
|
2097
2531
|
}
|
|
2098
|
-
const generated =
|
|
2532
|
+
const generated = join8(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
2099
2533
|
await writeManagedFile(generated, assetModuleSource(assets, bundleId), true);
|
|
2100
2534
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
2101
2535
|
};
|
|
2102
2536
|
var init_expoProject = __esm(() => {
|
|
2103
2537
|
init_nativeAuth();
|
|
2104
2538
|
init_syncSchema();
|
|
2539
|
+
init_deviceCapabilities();
|
|
2105
2540
|
expoDynamicAppConfig = `${EXPO_GENERATED_HEADER}const config = require('./app.json');
|
|
2106
2541
|
|
|
2107
2542
|
if (process.env.ABSOLUTE_EXPO_DEVELOPMENT === '1' && process.env.ABSOLUTE_EXPO_DEVELOPMENT_CA_PATH) {
|
|
@@ -2207,14 +2642,14 @@ import {
|
|
|
2207
2642
|
isIP
|
|
2208
2643
|
} from "net";
|
|
2209
2644
|
import { readFile as readFile2 } from "fs/promises";
|
|
2210
|
-
var closeServer = (server) => new Promise((
|
|
2645
|
+
var closeServer = (server) => new Promise((resolve6, reject) => {
|
|
2211
2646
|
server.close((error) => {
|
|
2212
2647
|
if (error)
|
|
2213
2648
|
reject(error);
|
|
2214
2649
|
else
|
|
2215
|
-
|
|
2650
|
+
resolve6();
|
|
2216
2651
|
});
|
|
2217
|
-
}), listen = (server, port) => new Promise((
|
|
2652
|
+
}), listen = (server, port) => new Promise((resolve6, reject) => {
|
|
2218
2653
|
server.once("error", reject);
|
|
2219
2654
|
server.listen(port, "0.0.0.0", () => {
|
|
2220
2655
|
server.off("error", reject);
|
|
@@ -2223,11 +2658,11 @@ var closeServer = (server) => new Promise((resolve5, reject) => {
|
|
|
2223
2658
|
reject(new Error("Could not determine the iOS device helper port."));
|
|
2224
2659
|
return;
|
|
2225
2660
|
}
|
|
2226
|
-
|
|
2661
|
+
resolve6(address.port);
|
|
2227
2662
|
});
|
|
2228
2663
|
}), findEphemeralPort = async () => {
|
|
2229
2664
|
const probe = createTcpServer();
|
|
2230
|
-
const port = await new Promise((
|
|
2665
|
+
const port = await new Promise((resolve6, reject) => {
|
|
2231
2666
|
probe.once("error", reject);
|
|
2232
2667
|
probe.listen(0, "127.0.0.1", () => {
|
|
2233
2668
|
const address = probe.address();
|
|
@@ -2235,7 +2670,7 @@ var closeServer = (server) => new Promise((resolve5, reject) => {
|
|
|
2235
2670
|
reject(new Error("Could not allocate the iOS CA enrollment port."));
|
|
2236
2671
|
return;
|
|
2237
2672
|
}
|
|
2238
|
-
|
|
2673
|
+
resolve6(address.port);
|
|
2239
2674
|
});
|
|
2240
2675
|
});
|
|
2241
2676
|
await closeServer(probe);
|
|
@@ -2292,12 +2727,12 @@ var init_iosPhysicalDeviceTransport = () => {};
|
|
|
2292
2727
|
// src/cli/utils.ts
|
|
2293
2728
|
var {$: $2 } = globalThis.Bun;
|
|
2294
2729
|
import { execSync } from "child_process";
|
|
2295
|
-
import { existsSync as
|
|
2730
|
+
import { existsSync as existsSync4, readFileSync as readFileSync8 } from "fs";
|
|
2296
2731
|
import { createServer as createServer3 } from "net";
|
|
2297
|
-
import { resolve as
|
|
2732
|
+
import { resolve as resolve6 } from "path";
|
|
2298
2733
|
var COMPOSE_PATH = "db/docker-compose.db.yml", DEFAULT_SERVER_ENTRY = "src/backend/server.ts", isWSLEnvironment = () => {
|
|
2299
2734
|
try {
|
|
2300
|
-
const release =
|
|
2735
|
+
const release = readFileSync8("/proc/version", "utf-8");
|
|
2301
2736
|
return /microsoft|wsl/i.test(release);
|
|
2302
2737
|
} catch {
|
|
2303
2738
|
return false;
|
|
@@ -2396,8 +2831,8 @@ var COMPOSE_PATH = "db/docker-compose.db.yml", DEFAULT_SERVER_ENTRY = "src/backe
|
|
|
2396
2831
|
}, printHint = () => {
|
|
2397
2832
|
console.log("\x1B[90mpress h + enter to show shortcuts\x1B[0m");
|
|
2398
2833
|
}, readDbScripts = async () => {
|
|
2399
|
-
const pkgPath =
|
|
2400
|
-
if (!
|
|
2834
|
+
const pkgPath = resolve6("package.json");
|
|
2835
|
+
if (!existsSync4(pkgPath))
|
|
2401
2836
|
return null;
|
|
2402
2837
|
const pkg = await Bun.file(pkgPath).json();
|
|
2403
2838
|
const upCommand = pkg.scripts?.["db:up"];
|
|
@@ -2431,7 +2866,7 @@ var init_utils = __esm(() => {
|
|
|
2431
2866
|
// src/mobile/emulatorDoctor.ts
|
|
2432
2867
|
import { access as access3 } from "fs/promises";
|
|
2433
2868
|
import { homedir as homedir3 } from "os";
|
|
2434
|
-
import { join as
|
|
2869
|
+
import { join as join10 } from "path";
|
|
2435
2870
|
var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command) => {
|
|
2436
2871
|
try {
|
|
2437
2872
|
const result = Bun.spawnSync(command, {
|
|
@@ -2476,15 +2911,15 @@ var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command)
|
|
|
2476
2911
|
}
|
|
2477
2912
|
}, absoluteManagedAndroidSdkRoot = (host2, env = process.env) => {
|
|
2478
2913
|
if (host2 === "windows") {
|
|
2479
|
-
return
|
|
2914
|
+
return join10(env.LOCALAPPDATA ?? join10(homedir3(), "AppData", "Local"), "AbsoluteJS", "Android", "Sdk");
|
|
2480
2915
|
}
|
|
2481
2916
|
if (host2 === "wsl") {
|
|
2482
2917
|
const localAppData = windowsLocalAppDataFromWsl();
|
|
2483
2918
|
if (localAppData) {
|
|
2484
|
-
return
|
|
2919
|
+
return join10(localAppData, "AbsoluteJS", "Android", "Sdk");
|
|
2485
2920
|
}
|
|
2486
2921
|
}
|
|
2487
|
-
return
|
|
2922
|
+
return join10(homedir3(), ".absolutejs", "android-sdk");
|
|
2488
2923
|
}, pathExists = async (path) => {
|
|
2489
2924
|
try {
|
|
2490
2925
|
await access3(path);
|
|
@@ -2537,7 +2972,7 @@ var ABSOLUTE_ANDROID_AVD_NAME = "AbsoluteJS_API_36", captureCommand = (command)
|
|
|
2537
2972
|
const capture = input.capture ?? captureCommand;
|
|
2538
2973
|
const androidRoot = input.androidRoot === null ? undefined : input.androidRoot ?? env.ANDROID_HOME ?? env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host2, env);
|
|
2539
2974
|
const windowsAndroidTools = host2 === "windows" || host2 === "wsl";
|
|
2540
|
-
const android = (segments) => androidRoot ?
|
|
2975
|
+
const android = (segments) => androidRoot ? join10(androidRoot, ...segments) : undefined;
|
|
2541
2976
|
const paths = (values) => values.filter((value) => Boolean(value));
|
|
2542
2977
|
const adb = await findExecutable("adb", paths([
|
|
2543
2978
|
android(["platform-tools", windowsAndroidTools ? "adb.exe" : "adb"])
|
|
@@ -2644,8 +3079,8 @@ var init_emulatorDoctor = __esm(() => {
|
|
|
2644
3079
|
|
|
2645
3080
|
// src/mobile/capacitorProject.ts
|
|
2646
3081
|
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) =>
|
|
3082
|
+
import { relative as relative3, resolve as resolve7 } from "path";
|
|
3083
|
+
var CONFIG_FILE = "capacitor.config.ts", portableRelative2 = (root, path) => relative3(root, path).replaceAll("\\", "/"), capacitorConfigSource = (config, projectRoot) => `import type { CapacitorConfig } from '@capacitor/cli';
|
|
2649
3084
|
|
|
2650
3085
|
const config: CapacitorConfig = {
|
|
2651
3086
|
appId: ${JSON.stringify(config.appId)},
|
|
@@ -2668,8 +3103,8 @@ export default config;
|
|
|
2668
3103
|
return false;
|
|
2669
3104
|
}
|
|
2670
3105
|
}, writeAbsoluteCapacitorConfig = async (config, options) => {
|
|
2671
|
-
const projectRoot =
|
|
2672
|
-
const destination =
|
|
3106
|
+
const projectRoot = resolve7(options.projectRoot);
|
|
3107
|
+
const destination = resolve7(projectRoot, CONFIG_FILE);
|
|
2673
3108
|
const source = capacitorConfigSource(config, projectRoot);
|
|
2674
3109
|
if (await exists2(destination)) {
|
|
2675
3110
|
const current = await readFile3(destination, "utf8");
|
|
@@ -2704,9 +3139,9 @@ import { createHash as createHash2, randomUUID as randomUUID2 } from "crypto";
|
|
|
2704
3139
|
import {
|
|
2705
3140
|
dirname as dirname5,
|
|
2706
3141
|
isAbsolute,
|
|
2707
|
-
join as
|
|
2708
|
-
relative as
|
|
2709
|
-
resolve as
|
|
3142
|
+
join as join11,
|
|
3143
|
+
relative as relative4,
|
|
3144
|
+
resolve as resolve8,
|
|
2710
3145
|
sep,
|
|
2711
3146
|
win32
|
|
2712
3147
|
} from "path";
|
|
@@ -2876,21 +3311,21 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2876
3311
|
return;
|
|
2877
3312
|
throw new DOMException("Android development startup was cancelled.", "AbortError");
|
|
2878
3313
|
}, journalPaths = (projectRoot) => {
|
|
2879
|
-
const root =
|
|
3314
|
+
const root = join11(projectRoot, ".absolutejs", "mobile", "dev-session");
|
|
2880
3315
|
return {
|
|
2881
|
-
backup:
|
|
2882
|
-
caBackup:
|
|
2883
|
-
journal:
|
|
2884
|
-
manifestBackup:
|
|
2885
|
-
networkConfigBackup:
|
|
3316
|
+
backup: join11(root, "capacitor.config.backup.json"),
|
|
3317
|
+
caBackup: join11(root, "absolutejs_dev_ca.backup.pem"),
|
|
3318
|
+
journal: join11(root, "journal.json"),
|
|
3319
|
+
manifestBackup: join11(root, "AndroidManifest.backup.xml"),
|
|
3320
|
+
networkConfigBackup: join11(root, "absolutejs_dev_network_security.backup.xml"),
|
|
2886
3321
|
root
|
|
2887
3322
|
};
|
|
2888
3323
|
}, isInside = (root, path) => {
|
|
2889
|
-
const resolvedRoot =
|
|
2890
|
-
const resolvedPath =
|
|
2891
|
-
const relativePath =
|
|
3324
|
+
const resolvedRoot = resolve8(root);
|
|
3325
|
+
const resolvedPath = resolve8(path);
|
|
3326
|
+
const relativePath = relative4(resolvedRoot, resolvedPath);
|
|
2892
3327
|
return relativePath === "" || relativePath !== ".." && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath);
|
|
2893
|
-
}, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), nativeCachePath = (projectRoot) =>
|
|
3328
|
+
}, isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value), nativeCachePath = (projectRoot) => join11(projectRoot, ".absolutejs", "mobile", "cache", "android-debug.json"), parseNativeCache = (value) => {
|
|
2894
3329
|
if (!isRecord(value))
|
|
2895
3330
|
return null;
|
|
2896
3331
|
const { appId, fingerprint, format, installations } = value;
|
|
@@ -2922,11 +3357,11 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2922
3357
|
});
|
|
2923
3358
|
}
|
|
2924
3359
|
}, nativeDependencySources = async (nativeDirectory) => {
|
|
2925
|
-
const settings = await readFile4(
|
|
3360
|
+
const settings = await readFile4(join11(nativeDirectory, "capacitor.settings.gradle"), "utf8");
|
|
2926
3361
|
const pattern = new RegExp(CAPACITOR_PROJECT_DIRECTORY_PATTERN.source, CAPACITOR_PROJECT_DIRECTORY_PATTERN.flags);
|
|
2927
3362
|
const dependencies = [...settings.matchAll(pattern)].map((match) => ({
|
|
2928
3363
|
name: (match[1] ?? "").slice(1).replaceAll(/[^a-zA-Z0-9_.-]/gu, "_"),
|
|
2929
|
-
source:
|
|
3364
|
+
source: resolve8(nativeDirectory, match[2] ?? "")
|
|
2930
3365
|
}));
|
|
2931
3366
|
if (dependencies.length === 0) {
|
|
2932
3367
|
throw new Error("Capacitor Android settings did not declare any native dependencies.");
|
|
@@ -2939,7 +3374,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2939
3374
|
}
|
|
2940
3375
|
return ignorePublicBundle && parts.slice(0, NATIVE_PUBLIC_PATH_SEGMENTS).join("/") === "app/src/main/assets/public";
|
|
2941
3376
|
}, collectNativePath = async (root, label, path, isDirectory, isFile, isSymbolicLink, ignorePublicBundle) => {
|
|
2942
|
-
const relativePath =
|
|
3377
|
+
const relativePath = relative4(root, path);
|
|
2943
3378
|
if (shouldIgnoreNativePath(relativePath, ignorePublicBundle))
|
|
2944
3379
|
return [];
|
|
2945
3380
|
const identity = `${label}:${relativePath.split(sep).join("/")}\x00`;
|
|
@@ -2962,7 +3397,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
2962
3397
|
}, collectNativeDirectory = async (root, label, directory, ignorePublicBundle) => {
|
|
2963
3398
|
const entries = await readdir2(directory, { withFileTypes: true });
|
|
2964
3399
|
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
2965
|
-
const records = await Promise.all(entries.map((entry) => collectNativePath(root, label,
|
|
3400
|
+
const records = await Promise.all(entries.map((entry) => collectNativePath(root, label, join11(directory, entry.name), entry.isDirectory(), entry.isFile(), entry.isSymbolicLink(), ignorePublicBundle)));
|
|
2966
3401
|
return records.flat();
|
|
2967
3402
|
}, hashNativeTree = async (root, label, ignorePublicBundle) => {
|
|
2968
3403
|
const resolvedRoot = await realpath(root);
|
|
@@ -3091,11 +3526,11 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3091
3526
|
await mkdir2(paths.root, { recursive: true });
|
|
3092
3527
|
await writeFile3(paths.backup, source, { flag: "wx" });
|
|
3093
3528
|
await writeFile3(paths.manifestBackup, manifestSource, { flag: "wx" });
|
|
3094
|
-
const resourceRoot =
|
|
3095
|
-
const caPath =
|
|
3529
|
+
const resourceRoot = join11(dirname5(nativeManifestPath), "res");
|
|
3530
|
+
const caPath = join11(resourceRoot, "raw", "absolutejs_dev_ca.pem");
|
|
3096
3531
|
const existingNetworkConfig = manifestSource.match(/android:networkSecurityConfig=["']@xml\/([a-z0-9_]+)["']/u)?.[1];
|
|
3097
3532
|
const networkConfigName = existingNetworkConfig ?? "absolutejs_dev_network_security";
|
|
3098
|
-
const networkConfigPath =
|
|
3533
|
+
const networkConfigPath = join11(resourceRoot, "xml", `${networkConfigName}.xml`);
|
|
3099
3534
|
const backupProjectedFile = async ([path, backupPath]) => {
|
|
3100
3535
|
if (!await pathExists2(path))
|
|
3101
3536
|
return { path };
|
|
@@ -3188,12 +3623,12 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3188
3623
|
}
|
|
3189
3624
|
return result.stdout.trim();
|
|
3190
3625
|
}, mirroredCapacitorDependencies = async (project, capture) => {
|
|
3191
|
-
const settingsPath =
|
|
3626
|
+
const settingsPath = join11(project.nativeDirectory, "capacitor.settings.gradle");
|
|
3192
3627
|
const settings = await readFile4(settingsPath, "utf8");
|
|
3193
3628
|
const dependencies = [];
|
|
3194
3629
|
const rewrittenSettings = settings.replace(CAPACITOR_PROJECT_DIRECTORY_PATTERN, (_statement, projectName, sourcePath) => {
|
|
3195
3630
|
const name = projectName.slice(1).replaceAll(/[^a-zA-Z0-9_.-]/gu, "_");
|
|
3196
|
-
const source =
|
|
3631
|
+
const source = resolve8(project.nativeDirectory, sourcePath);
|
|
3197
3632
|
dependencies.push({
|
|
3198
3633
|
name,
|
|
3199
3634
|
windowsSource: windowsPathFromWsl(source, capture)
|
|
@@ -3234,7 +3669,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3234
3669
|
].join("; ");
|
|
3235
3670
|
return Buffer.from(source, "utf16le").toString("base64");
|
|
3236
3671
|
}, gradleArtifactPath = (nativeDirectory, task, windows = false) => {
|
|
3237
|
-
const pathJoin = windows ? win32.join :
|
|
3672
|
+
const pathJoin = windows ? win32.join : join11;
|
|
3238
3673
|
if (task === "assembleDebug") {
|
|
3239
3674
|
return pathJoin(nativeDirectory, "app", "build", "outputs", "apk", "debug", "app-debug.apk");
|
|
3240
3675
|
}
|
|
@@ -3247,7 +3682,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3247
3682
|
if (task !== "assembleRelease" || await pathExists2(primary)) {
|
|
3248
3683
|
return primary;
|
|
3249
3684
|
}
|
|
3250
|
-
return
|
|
3685
|
+
return join11(nativeDirectory, "app", "build", "outputs", "apk", "release", "app-release-unsigned.apk");
|
|
3251
3686
|
}, buildAbsoluteAndroidGradleArtifact = async (options) => {
|
|
3252
3687
|
const { project, task } = options;
|
|
3253
3688
|
const capture = options.capture ?? captureCommand2;
|
|
@@ -3257,7 +3692,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3257
3692
|
if (project.host === "wsl") {
|
|
3258
3693
|
const windowsSource = windowsPathFromWsl(project.nativeDirectory, capture);
|
|
3259
3694
|
const buildId = Bun.hash(project.projectRoot).toString(HASH_RADIX);
|
|
3260
|
-
const managedBuildDirectory =
|
|
3695
|
+
const managedBuildDirectory = resolve8(project.androidRoot, "..", "..", "Builds", `${project.config.appId}-${buildId}`);
|
|
3261
3696
|
const windowsDirectory = windowsPathFromWsl(managedBuildDirectory, capture);
|
|
3262
3697
|
const windowsAndroidRoot = windowsPathFromWsl(project.androidRoot, capture);
|
|
3263
3698
|
const { dependencies, rewrittenSettings } = await mirroredCapacitorDependencies(project, capture);
|
|
@@ -3440,7 +3875,7 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3440
3875
|
"chromium:I"
|
|
3441
3876
|
], { env }, onLine);
|
|
3442
3877
|
}, prepareAbsoluteAndroidDevProject = async (config, options) => {
|
|
3443
|
-
const projectRoot =
|
|
3878
|
+
const projectRoot = resolve8(options.projectRoot);
|
|
3444
3879
|
const host2 = detectAbsoluteMobileHost();
|
|
3445
3880
|
const androidRoot = process.env.ANDROID_HOME ?? process.env.ANDROID_SDK_ROOT ?? absoluteManagedAndroidSdkRoot(host2);
|
|
3446
3881
|
const checks = await inspectAbsoluteMobileToolchain({ androidRoot, host: host2 });
|
|
@@ -3459,18 +3894,18 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3459
3894
|
if (!adb || options.target !== "device" && !emulator) {
|
|
3460
3895
|
throw new Error("Android SDK tools disappeared after readiness checks.");
|
|
3461
3896
|
}
|
|
3462
|
-
const cap =
|
|
3897
|
+
const cap = join11(projectRoot, "node_modules", ".bin", host2 === "windows" ? "cap.cmd" : "cap");
|
|
3463
3898
|
if (!await pathExists2(cap)) {
|
|
3464
3899
|
throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
|
|
3465
3900
|
}
|
|
3466
3901
|
await writeAbsoluteCapacitorConfig(config, { projectRoot });
|
|
3467
3902
|
await mkdir2(config.bundleDirectory, { recursive: true });
|
|
3468
|
-
const placeholder =
|
|
3903
|
+
const placeholder = join11(config.bundleDirectory, "index.html");
|
|
3469
3904
|
if (!await pathExists2(placeholder)) {
|
|
3470
3905
|
await writeFile3(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
|
|
3471
3906
|
`);
|
|
3472
3907
|
}
|
|
3473
|
-
const nativeDirectory =
|
|
3908
|
+
const nativeDirectory = join11(config.nativeProjectDirectory, "android");
|
|
3474
3909
|
if (!await pathExists2(nativeDirectory)) {
|
|
3475
3910
|
if (!options.createNativeProject) {
|
|
3476
3911
|
throw new Error("Android native project has not been created.");
|
|
@@ -3531,8 +3966,8 @@ var ANDROID_BOOT_TIMEOUT_MS = 180000, ANDROID_BOOT_POLL_MS = 1000, DEV_JOURNAL_F
|
|
|
3531
3966
|
await requireSuccess([project.cap, "sync", "android"], "Capacitor Android synchronization", run, { cwd: project.projectRoot, env, signal: options.signal });
|
|
3532
3967
|
throwIfAborted(options.signal);
|
|
3533
3968
|
transition("configuring");
|
|
3534
|
-
const nativeConfigPath =
|
|
3535
|
-
const nativeManifestPath =
|
|
3969
|
+
const nativeConfigPath = join11(project.nativeDirectory, "app", "src", "main", "assets", "capacitor.config.json");
|
|
3970
|
+
const nativeManifestPath = join11(project.nativeDirectory, "app", "src", "main", "AndroidManifest.xml");
|
|
3536
3971
|
let connectedSerial;
|
|
3537
3972
|
let nativeLogs = null;
|
|
3538
3973
|
const closeNativeLogs = async () => {
|
|
@@ -3691,7 +4126,7 @@ var init_androidEmulatorController = __esm(() => {
|
|
|
3691
4126
|
import { createHash as createHash3 } from "crypto";
|
|
3692
4127
|
import { cp as cp2, mkdir as mkdir3, mkdtemp as mkdtemp2, readFile as readFile5, rm as rm3 } from "fs/promises";
|
|
3693
4128
|
import { tmpdir } from "os";
|
|
3694
|
-
import { basename as basename3, join as
|
|
4129
|
+
import { basename as basename3, join as join12 } from "path";
|
|
3695
4130
|
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
4131
|
const subprocess = Bun.spawn(command, {
|
|
3697
4132
|
env: options.env,
|
|
@@ -3723,7 +4158,7 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3723
4158
|
exitCode: result.exitCode,
|
|
3724
4159
|
stdout: result.stdout.toString()
|
|
3725
4160
|
};
|
|
3726
|
-
}, commandPath = (root, host2, tool) =>
|
|
4161
|
+
}, 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
4162
|
const match = /^\/mnt\/([a-z])\/(.*)$/i.exec(path);
|
|
3728
4163
|
if (!match)
|
|
3729
4164
|
return path;
|
|
@@ -3797,10 +4232,10 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3797
4232
|
if (digest !== release.sha256) {
|
|
3798
4233
|
throw new Error(`Android command-line-tools checksum mismatch: expected ${release.sha256}, received ${digest}.`);
|
|
3799
4234
|
}
|
|
3800
|
-
const temporary = await mkdtemp2(
|
|
4235
|
+
const temporary = await mkdtemp2(join12(tmpdir(), "absolutejs-android-sdk-"));
|
|
3801
4236
|
try {
|
|
3802
|
-
const archive =
|
|
3803
|
-
const extracted =
|
|
4237
|
+
const archive = join12(temporary, "command-line-tools.zip");
|
|
4238
|
+
const extracted = join12(temporary, "extracted");
|
|
3804
4239
|
await Bun.write(archive, bytes);
|
|
3805
4240
|
await mkdir3(extracted, { recursive: true });
|
|
3806
4241
|
const extraction = plan.host === "windows" ? [
|
|
@@ -3817,12 +4252,12 @@ var ANDROID_API = 36, ANDROID_BUILD_TOOLS = "36.0.0", COMMAND_LINE_TOOLS_VERSION
|
|
|
3817
4252
|
if (await input.run(extraction) !== 0) {
|
|
3818
4253
|
throw new Error("Failed to extract Android command-line tools.");
|
|
3819
4254
|
}
|
|
3820
|
-
const destination =
|
|
3821
|
-
await mkdir3(
|
|
4255
|
+
const destination = join12(plan.androidRoot, "cmdline-tools", "latest");
|
|
4256
|
+
await mkdir3(join12(plan.androidRoot, "cmdline-tools"), {
|
|
3822
4257
|
recursive: true
|
|
3823
4258
|
});
|
|
3824
4259
|
await rm3(destination, { force: true, recursive: true });
|
|
3825
|
-
await cp2(
|
|
4260
|
+
await cp2(join12(extracted, "cmdline-tools"), destination, {
|
|
3826
4261
|
recursive: true
|
|
3827
4262
|
});
|
|
3828
4263
|
} finally {
|
|
@@ -4007,7 +4442,7 @@ import {
|
|
|
4007
4442
|
stat,
|
|
4008
4443
|
writeFile as writeFile4
|
|
4009
4444
|
} from "fs/promises";
|
|
4010
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as
|
|
4445
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join13, relative as relative5, resolve as resolve9, sep as sep2 } from "path";
|
|
4011
4446
|
var developmentTeamArgument = (value) => {
|
|
4012
4447
|
if (value === undefined)
|
|
4013
4448
|
return;
|
|
@@ -4064,8 +4499,8 @@ var developmentTeamArgument = (value) => {
|
|
|
4064
4499
|
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root, options = {}) => {
|
|
4065
4500
|
const entries = await readdir3(current, { withFileTypes: true });
|
|
4066
4501
|
const nested = await Promise.all(entries.sort((left, right) => left.name.localeCompare(right.name)).map(async (entry) => {
|
|
4067
|
-
const path =
|
|
4068
|
-
const projectRelative =
|
|
4502
|
+
const path = join13(current, entry.name);
|
|
4503
|
+
const projectRelative = relative5(root, path).replaceAll("\\", "/");
|
|
4069
4504
|
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public" && options.includePublicBundle !== true);
|
|
4070
4505
|
if (ignored)
|
|
4071
4506
|
return [];
|
|
@@ -4079,16 +4514,16 @@ var developmentTeamArgument = (value) => {
|
|
|
4079
4514
|
const files = await fingerprintFiles(nativeDirectory, nativeDirectory, options);
|
|
4080
4515
|
const contents = await Promise.all(files.map((file) => readFile6(file)));
|
|
4081
4516
|
files.forEach((file, index) => {
|
|
4082
|
-
hasher.update(
|
|
4517
|
+
hasher.update(relative5(nativeDirectory, file).replaceAll("\\", "/"));
|
|
4083
4518
|
hasher.update("\x00");
|
|
4084
4519
|
hasher.update(contents[index] ?? new Uint8Array);
|
|
4085
4520
|
hasher.update("\x00");
|
|
4086
4521
|
});
|
|
4087
4522
|
return hasher.digest("hex");
|
|
4088
4523
|
}, safeOutputDirectory = (projectRoot, requested) => {
|
|
4089
|
-
const root =
|
|
4090
|
-
const output =
|
|
4091
|
-
const projectRelative =
|
|
4524
|
+
const root = resolve9(projectRoot);
|
|
4525
|
+
const output = resolve9(root, requested ?? ".absolutejs/mobile/releases/ios");
|
|
4526
|
+
const projectRelative = relative5(root, output);
|
|
4092
4527
|
if (projectRelative === ".." || projectRelative.startsWith(`..${sep2}`) || isAbsolute2(projectRelative)) {
|
|
4093
4528
|
throw new TypeError("mobile build --outdir must remain inside the project.");
|
|
4094
4529
|
}
|
|
@@ -4098,7 +4533,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4098
4533
|
return;
|
|
4099
4534
|
const entries = await readdir3(root, { withFileTypes: true });
|
|
4100
4535
|
const matches = await Promise.all(entries.map(async (entry) => {
|
|
4101
|
-
const path =
|
|
4536
|
+
const path = join13(root, entry.name);
|
|
4102
4537
|
if (entry.isDirectory() && entry.name.endsWith(extension))
|
|
4103
4538
|
return path;
|
|
4104
4539
|
if (entry.isFile() && entry.name.endsWith(extension))
|
|
@@ -4121,10 +4556,10 @@ var developmentTeamArgument = (value) => {
|
|
|
4121
4556
|
throw new TypeError("iOS build number must be a positive integer.");
|
|
4122
4557
|
return value;
|
|
4123
4558
|
}, installRelease = async (artifactPath, metadata, outputRoot) => {
|
|
4124
|
-
const releaseRoot =
|
|
4125
|
-
const destination =
|
|
4559
|
+
const releaseRoot = join13(outputRoot, metadata.releaseId);
|
|
4560
|
+
const destination = join13(releaseRoot, "App.ipa");
|
|
4126
4561
|
if (await pathExists3(releaseRoot)) {
|
|
4127
|
-
const value = JSON.parse(await readFile6(
|
|
4562
|
+
const value = JSON.parse(await readFile6(join13(releaseRoot, "release.json"), "utf8"));
|
|
4128
4563
|
if (!isRecord2(value) || value.artifact !== "App.ipa" || Object.entries(metadata).some(([key, expected]) => Reflect.get(value, key) !== expected)) {
|
|
4129
4564
|
throw new TypeError(`Immutable iOS release ${metadata.releaseId} does not match its content.`);
|
|
4130
4565
|
}
|
|
@@ -4144,14 +4579,14 @@ var developmentTeamArgument = (value) => {
|
|
|
4144
4579
|
};
|
|
4145
4580
|
}
|
|
4146
4581
|
await mkdir4(dirname6(releaseRoot), { recursive: true });
|
|
4147
|
-
const staging = await mkdtemp3(
|
|
4582
|
+
const staging = await mkdtemp3(join13(dirname6(releaseRoot), ".ios-stage-"));
|
|
4148
4583
|
try {
|
|
4149
|
-
await copyFile2(artifactPath,
|
|
4584
|
+
await copyFile2(artifactPath, join13(staging, "App.ipa"));
|
|
4150
4585
|
const complete = {
|
|
4151
4586
|
...metadata,
|
|
4152
4587
|
artifact: "App.ipa"
|
|
4153
4588
|
};
|
|
4154
|
-
await writeFile4(
|
|
4589
|
+
await writeFile4(join13(staging, "release.json"), `${JSON.stringify(complete, null, "\t")}
|
|
4155
4590
|
`, { flag: "wx" });
|
|
4156
4591
|
await rename4(staging, releaseRoot);
|
|
4157
4592
|
return { artifactPath: destination, metadata: complete, releaseRoot };
|
|
@@ -4168,22 +4603,22 @@ var developmentTeamArgument = (value) => {
|
|
|
4168
4603
|
const marketingVersion = options.config.iosVersion;
|
|
4169
4604
|
if (!marketingVersion)
|
|
4170
4605
|
throw new TypeError("iOS release builds require mobile.ios.version in absolutejs.config.ts.");
|
|
4171
|
-
const manifest = requireManifest(JSON.parse(await readFile6(
|
|
4606
|
+
const manifest = requireManifest(JSON.parse(await readFile6(join13(options.config.bundleDirectory, "absolute-mobile-manifest.json"), "utf8")));
|
|
4172
4607
|
if (manifest.appId !== options.config.appId)
|
|
4173
4608
|
throw new TypeError("Embedded mobile manifest appId does not match mobile.appId.");
|
|
4174
|
-
const nativeDirectory =
|
|
4609
|
+
const nativeDirectory = join13(options.config.nativeProjectDirectory, "ios");
|
|
4175
4610
|
let buildNumber = requireBuildNumber(options.buildNumber);
|
|
4176
4611
|
if (options.prepareBuildNumber) {
|
|
4177
4612
|
const nativeFingerprint = await fingerprintAbsoluteIosNativeProject(nativeDirectory);
|
|
4178
4613
|
const buildIdentity = createHash4("sha256").update(`${manifest.appBuild}\x00${nativeFingerprint}\x00${marketingVersion}`).digest("hex");
|
|
4179
4614
|
buildNumber = requireBuildNumber(await options.prepareBuildNumber(buildIdentity));
|
|
4180
4615
|
}
|
|
4181
|
-
const stagingParent =
|
|
4616
|
+
const stagingParent = resolve9(options.projectRoot, ".absolutejs/mobile");
|
|
4182
4617
|
await mkdir4(stagingParent, { recursive: true });
|
|
4183
|
-
const staging = await mkdtemp3(
|
|
4184
|
-
const archivePath =
|
|
4185
|
-
const exportPath =
|
|
4186
|
-
const exportPlist =
|
|
4618
|
+
const staging = await mkdtemp3(join13(stagingParent, ".ios-build-"));
|
|
4619
|
+
const archivePath = join13(staging, "App.xcarchive");
|
|
4620
|
+
const exportPath = join13(staging, "export");
|
|
4621
|
+
const exportPlist = join13(staging, "ExportOptions.plist");
|
|
4187
4622
|
await mkdir4(exportPath, { recursive: true });
|
|
4188
4623
|
await writeFile4(exportPlist, exportOptions());
|
|
4189
4624
|
const run = options.run ?? defaultRun2;
|
|
@@ -4197,7 +4632,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4197
4632
|
const archiveExit = await run([
|
|
4198
4633
|
"xcodebuild",
|
|
4199
4634
|
"-workspace",
|
|
4200
|
-
|
|
4635
|
+
join13(nativeDirectory, "App", "App.xcworkspace"),
|
|
4201
4636
|
"-scheme",
|
|
4202
4637
|
"App",
|
|
4203
4638
|
"-configuration",
|
|
@@ -4211,7 +4646,7 @@ var developmentTeamArgument = (value) => {
|
|
|
4211
4646
|
], { cwd: nativeDirectory });
|
|
4212
4647
|
if (archiveExit !== 0)
|
|
4213
4648
|
throw new TypeError("Xcode failed to archive the iOS app.");
|
|
4214
|
-
const archivedApp = await findByExtension(
|
|
4649
|
+
const archivedApp = await findByExtension(join13(archivePath, "Products", "Applications"), ".app");
|
|
4215
4650
|
const capture = options.capture ?? defaultCapture2;
|
|
4216
4651
|
const signed = archivedApp ? capture([
|
|
4217
4652
|
"codesign",
|
|
@@ -4285,7 +4720,7 @@ import {
|
|
|
4285
4720
|
writeFile as writeFile5
|
|
4286
4721
|
} from "fs/promises";
|
|
4287
4722
|
import { isIP as isIP2 } from "net";
|
|
4288
|
-
import { dirname as dirname7, isAbsolute as isAbsolute3, join as
|
|
4723
|
+
import { dirname as dirname7, isAbsolute as isAbsolute3, join as join14, relative as relative6, resolve as resolve10, sep as sep3 } from "path";
|
|
4289
4724
|
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
4725
|
try {
|
|
4291
4726
|
await access7(path);
|
|
@@ -4503,15 +4938,15 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4503
4938
|
const leftPro = left.name.includes("Pro") ? 1 : 0;
|
|
4504
4939
|
return rightPro - leftPro;
|
|
4505
4940
|
})[0], journalPaths2 = (projectRoot) => {
|
|
4506
|
-
const root =
|
|
4941
|
+
const root = join14(projectRoot, ".absolutejs", "mobile", "ios-dev-session");
|
|
4507
4942
|
return {
|
|
4508
|
-
configBackup:
|
|
4509
|
-
infoBackup:
|
|
4510
|
-
journal:
|
|
4943
|
+
configBackup: join14(root, "capacitor-config.backup"),
|
|
4944
|
+
infoBackup: join14(root, "Info.plist.backup"),
|
|
4945
|
+
journal: join14(root, "journal.json"),
|
|
4511
4946
|
root
|
|
4512
4947
|
};
|
|
4513
|
-
}, nativeCachePath2 = (projectRoot) =>
|
|
4514
|
-
const value =
|
|
4948
|
+
}, nativeCachePath2 = (projectRoot) => join14(projectRoot, ".absolutejs", "mobile", "ios-native-cache.json"), isInside2 = (root, path) => {
|
|
4949
|
+
const value = relative6(resolve10(root), resolve10(path));
|
|
4515
4950
|
return value === "" || !value.startsWith(`..${sep3}`) && value !== ".." && !isAbsolute3(value);
|
|
4516
4951
|
}, parseJournal2 = (value) => {
|
|
4517
4952
|
if (!isRecord3(value) || value.format !== DEV_JOURNAL_FORMAT2)
|
|
@@ -4567,8 +5002,8 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4567
5002
|
}, writeDevProjection = async (project, port, https, serverHost = "localhost") => {
|
|
4568
5003
|
const paths = journalPaths2(project.projectRoot);
|
|
4569
5004
|
await repairAbsoluteIosDevSession(project.projectRoot);
|
|
4570
|
-
const nativeConfigPath =
|
|
4571
|
-
const infoPath =
|
|
5005
|
+
const nativeConfigPath = join14(project.nativeDirectory, "App", "App", "capacitor.config.json");
|
|
5006
|
+
const infoPath = join14(project.nativeDirectory, "App", "App", "Info.plist");
|
|
4572
5007
|
const [configSource, infoSource] = await Promise.all([
|
|
4573
5008
|
readFile7(nativeConfigPath, "utf8"),
|
|
4574
5009
|
readFile7(infoPath, "utf8")
|
|
@@ -4729,12 +5164,12 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4729
5164
|
]);
|
|
4730
5165
|
return result.exitCode === 0 && result.stdout.includes(project.config.appId);
|
|
4731
5166
|
}, buildIosDebugApp = async (project, udid, fingerprint, run, signal) => {
|
|
4732
|
-
const derivedDataPath =
|
|
5167
|
+
const derivedDataPath = join14(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash5("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
4733
5168
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
4734
5169
|
await requireSuccess2([
|
|
4735
5170
|
project.xcodebuild,
|
|
4736
5171
|
"-workspace",
|
|
4737
|
-
|
|
5172
|
+
join14(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
4738
5173
|
"-scheme",
|
|
4739
5174
|
"App",
|
|
4740
5175
|
"-configuration",
|
|
@@ -4745,17 +5180,17 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4745
5180
|
derivedDataPath,
|
|
4746
5181
|
"build"
|
|
4747
5182
|
], "iOS simulator build", run, { cwd: project.nativeDirectory, signal });
|
|
4748
|
-
const appPath =
|
|
5183
|
+
const appPath = join14(derivedDataPath, "Build", "Products", "Debug-iphonesimulator", "App.app");
|
|
4749
5184
|
if (!await pathExists4(appPath))
|
|
4750
5185
|
throw new Error(`Xcode did not produce the simulator app at ${appPath}.`);
|
|
4751
5186
|
return appPath;
|
|
4752
5187
|
}, buildPhysicalIosDebugApp = async (project, identifier, run, signal) => {
|
|
4753
|
-
const derivedDataPath =
|
|
5188
|
+
const derivedDataPath = join14(project.projectRoot, ".absolutejs", "mobile", "ios-derived-data", createHash5("sha256").update(project.config.appId).digest("hex").slice(0, 16));
|
|
4754
5189
|
await mkdir5(derivedDataPath, { recursive: true });
|
|
4755
5190
|
await requireSuccess2([
|
|
4756
5191
|
project.xcodebuild,
|
|
4757
5192
|
"-workspace",
|
|
4758
|
-
|
|
5193
|
+
join14(project.nativeDirectory, "App", "App.xcworkspace"),
|
|
4759
5194
|
"-scheme",
|
|
4760
5195
|
"App",
|
|
4761
5196
|
"-configuration",
|
|
@@ -4767,7 +5202,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4767
5202
|
"-allowProvisioningUpdates",
|
|
4768
5203
|
"build"
|
|
4769
5204
|
], "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 =
|
|
5205
|
+
const appPath = join14(derivedDataPath, "Build", "Products", "Debug-iphoneos", "App.app");
|
|
4771
5206
|
if (!await pathExists4(appPath))
|
|
4772
5207
|
throw new Error(`Xcode did not produce the physical-device app at ${appPath}.`);
|
|
4773
5208
|
return appPath;
|
|
@@ -4878,7 +5313,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4878
5313
|
if (detectAbsoluteMobileHost() !== "macos")
|
|
4879
5314
|
throw new Error("iOS development requires macOS and Xcode.");
|
|
4880
5315
|
const target = options.target ?? "simulator";
|
|
4881
|
-
const projectRoot =
|
|
5316
|
+
const projectRoot = resolve10(options.projectRoot);
|
|
4882
5317
|
const checks = await inspectAbsoluteMobileToolchain({ host: "macos" });
|
|
4883
5318
|
const failed = checks.filter((check) => check.platform === "ios" && !(target === "device" && check.id === "ios.runtime") && (check.status === "fail" || check.status === "warn"));
|
|
4884
5319
|
if (failed.length > 0)
|
|
@@ -4887,16 +5322,16 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
4887
5322
|
const xcodebuild = checks.find((check) => check.id === "ios.xcodebuild")?.path;
|
|
4888
5323
|
if (!xcrun || !xcodebuild)
|
|
4889
5324
|
throw new Error("Xcode tools disappeared after readiness checks.");
|
|
4890
|
-
const cap =
|
|
5325
|
+
const cap = join14(projectRoot, "node_modules", ".bin", "cap");
|
|
4891
5326
|
if (!await pathExists4(cap))
|
|
4892
5327
|
throw new Error("Capacitor CLI is not installed. Run absolute mobile init first.");
|
|
4893
5328
|
await writeAbsoluteCapacitorConfig(config, { projectRoot });
|
|
4894
5329
|
await mkdir5(config.bundleDirectory, { recursive: true });
|
|
4895
|
-
const placeholder =
|
|
5330
|
+
const placeholder = join14(config.bundleDirectory, "index.html");
|
|
4896
5331
|
if (!await pathExists4(placeholder))
|
|
4897
5332
|
await writeFile5(placeholder, `<!doctype html><title>AbsoluteJS mobile development</title>
|
|
4898
5333
|
`);
|
|
4899
|
-
const nativeDirectory =
|
|
5334
|
+
const nativeDirectory = join14(config.nativeProjectDirectory, "ios");
|
|
4900
5335
|
if (!await pathExists4(nativeDirectory)) {
|
|
4901
5336
|
if (!options.createNativeProject)
|
|
4902
5337
|
throw new Error("iOS native project has not been created.");
|
|
@@ -5121,7 +5556,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
5121
5556
|
screenshot: async (destination) => {
|
|
5122
5557
|
if (deviceIdentifier)
|
|
5123
5558
|
throw new Error("Physical iOS screenshots are captured in Xcode Device Hub; the CLI never records a device screen automatically.");
|
|
5124
|
-
const resolved =
|
|
5559
|
+
const resolved = resolve10(project.projectRoot, destination);
|
|
5125
5560
|
if (!isInside2(project.projectRoot, resolved))
|
|
5126
5561
|
throw new Error("iOS screenshot destination must remain inside the project.");
|
|
5127
5562
|
await mkdir5(dirname7(resolved), { recursive: true });
|
|
@@ -5185,13 +5620,13 @@ import { isIP as isIP3 } from "net";
|
|
|
5185
5620
|
import {
|
|
5186
5621
|
dirname as dirname8,
|
|
5187
5622
|
isAbsolute as isAbsolute4,
|
|
5188
|
-
join as
|
|
5623
|
+
join as join15,
|
|
5189
5624
|
posix,
|
|
5190
|
-
relative as
|
|
5625
|
+
relative as relative7,
|
|
5191
5626
|
resolve as resolvePath,
|
|
5192
5627
|
sep as sep4
|
|
5193
5628
|
} from "path";
|
|
5194
|
-
var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TIMEOUT_MS = 2000, PROFILE_NAME, SSH_DESTINATION, defaultProfilePath = () =>
|
|
5629
|
+
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
5630
|
format: PROFILE_FORMAT,
|
|
5196
5631
|
profiles: {}
|
|
5197
5632
|
}), loadStore = async (path = defaultProfilePath()) => {
|
|
@@ -5367,9 +5802,9 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5367
5802
|
throw new TypeError("Remote Expo execution requires mobile.engine: expo.");
|
|
5368
5803
|
return createAbsoluteRemoteIosDevProject(config, projectRoot, profile);
|
|
5369
5804
|
}, createAbsoluteRemoteIosDevProject = (config, projectRoot, profile) => ({
|
|
5370
|
-
cap:
|
|
5805
|
+
cap: join15(resolvePath(projectRoot), "node_modules", ".bin", "cap"),
|
|
5371
5806
|
config,
|
|
5372
|
-
nativeDirectory:
|
|
5807
|
+
nativeDirectory: join15(config.nativeProjectDirectory, "ios"),
|
|
5373
5808
|
profile,
|
|
5374
5809
|
projectRoot: resolvePath(projectRoot),
|
|
5375
5810
|
remote: true,
|
|
@@ -5416,8 +5851,8 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5416
5851
|
return { ...artifact, remotePath, uploaded: true };
|
|
5417
5852
|
}, materializeAbsoluteRemoteMacAgent = async (projectRoot) => {
|
|
5418
5853
|
const shippedCandidates = [
|
|
5419
|
-
|
|
5420
|
-
|
|
5854
|
+
join15(import.meta.dir, "remoteMacAgentEntry.js"),
|
|
5855
|
+
join15(import.meta.dir, "..", "mobile", "remoteMacAgentEntry.js")
|
|
5421
5856
|
];
|
|
5422
5857
|
let path;
|
|
5423
5858
|
for (const candidate of shippedCandidates) {
|
|
@@ -5428,13 +5863,13 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5428
5863
|
}
|
|
5429
5864
|
if (!path) {
|
|
5430
5865
|
const sourceCandidates = [
|
|
5431
|
-
|
|
5432
|
-
|
|
5866
|
+
join15(import.meta.dir, "remoteMacAgentEntry.ts"),
|
|
5867
|
+
join15(import.meta.dir, "..", "..", "src", "mobile", "remoteMacAgentEntry.ts")
|
|
5433
5868
|
];
|
|
5434
5869
|
const source = await sourceCandidates.reduce(async (found, candidate) => await found ?? (await Bun.file(candidate).exists() ? candidate : undefined), Promise.resolve(undefined));
|
|
5435
5870
|
if (!source)
|
|
5436
5871
|
throw new Error("The AbsoluteJS installation does not contain its remote Mac agent artifact.");
|
|
5437
|
-
const outdir =
|
|
5872
|
+
const outdir = join15(resolvePath(projectRoot), ".absolutejs", "mobile", "remote-agent");
|
|
5438
5873
|
await mkdir6(outdir, { recursive: true });
|
|
5439
5874
|
const result = await Bun.build({
|
|
5440
5875
|
entrypoints: [source],
|
|
@@ -5444,12 +5879,12 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5444
5879
|
});
|
|
5445
5880
|
if (!result.success)
|
|
5446
5881
|
throw new AggregateError(result.logs, "Failed to build the AbsoluteJS remote Mac agent.");
|
|
5447
|
-
path =
|
|
5882
|
+
path = join15(outdir, "remoteMacAgentEntry.js");
|
|
5448
5883
|
}
|
|
5449
5884
|
const bytes = await Bun.file(path).arrayBuffer();
|
|
5450
5885
|
const sha256 = createHash6("sha256").update(new Uint8Array(bytes)).digest("hex");
|
|
5451
5886
|
return { bytes: bytes.byteLength, path, sha256 };
|
|
5452
|
-
}, portableRelativePath = (root, path) =>
|
|
5887
|
+
}, portableRelativePath = (root, path) => relative7(root, path).split(sep4).join(posix.sep), portableMobileConfig = (project) => ({
|
|
5453
5888
|
appId: project.config.appId,
|
|
5454
5889
|
appName: project.config.appName,
|
|
5455
5890
|
bundleDirectory: portableRelativePath(project.projectRoot, project.config.bundleDirectory),
|
|
@@ -5665,8 +6100,8 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5665
6100
|
const pending = new Map;
|
|
5666
6101
|
let resolveReady;
|
|
5667
6102
|
let rejectReady;
|
|
5668
|
-
const readyPromise = new Promise((
|
|
5669
|
-
resolveReady =
|
|
6103
|
+
const readyPromise = new Promise((resolve11, reject) => {
|
|
6104
|
+
resolveReady = resolve11;
|
|
5670
6105
|
rejectReady = reject;
|
|
5671
6106
|
});
|
|
5672
6107
|
const handleEvent = (event) => {
|
|
@@ -5767,7 +6202,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5767
6202
|
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
6203
|
const request = (commandName) => {
|
|
5769
6204
|
const id = randomUUID4();
|
|
5770
|
-
const response = new Promise((
|
|
6205
|
+
const response = new Promise((resolve11, reject) => pending.set(id, { reject, resolve: resolve11 }));
|
|
5771
6206
|
process2.stdin.write(`${JSON.stringify({ command: commandName, id, v: ABSOLUTE_REMOTE_MAC_PROTOCOL_VERSION })}
|
|
5772
6207
|
`);
|
|
5773
6208
|
const flush = async () => {
|
|
@@ -5787,7 +6222,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5787
6222
|
if (closed)
|
|
5788
6223
|
return;
|
|
5789
6224
|
closed = true;
|
|
5790
|
-
const timeout = () => new Promise((
|
|
6225
|
+
const timeout = () => new Promise((resolve11) => setTimeout(() => resolve11("timeout"), REMOTE_SESSION_CLOSE_TIMEOUT_MS));
|
|
5791
6226
|
await Promise.race([
|
|
5792
6227
|
request("close").catch(() => {
|
|
5793
6228
|
return;
|
|
@@ -5835,7 +6270,7 @@ var PROFILE_FORMAT = 1, REMOTE_STDIN_FLUSH_ATTEMPTS = 3, REMOTE_SESSION_CLOSE_TI
|
|
|
5835
6270
|
screenshot: async (destination) => {
|
|
5836
6271
|
const result = await request("screenshot");
|
|
5837
6272
|
const target = resolvePath(options.project.projectRoot, destination);
|
|
5838
|
-
const targetRelative =
|
|
6273
|
+
const targetRelative = relative7(options.project.projectRoot, target);
|
|
5839
6274
|
if (targetRelative.startsWith("..") || isAbsolute4(targetRelative))
|
|
5840
6275
|
throw new Error("iOS screenshot must remain inside the project.");
|
|
5841
6276
|
await mkdir6(dirname8(target), { recursive: true });
|
|
@@ -5875,16 +6310,16 @@ __export(exports_devCert, {
|
|
|
5875
6310
|
});
|
|
5876
6311
|
import {
|
|
5877
6312
|
copyFileSync,
|
|
5878
|
-
existsSync as
|
|
6313
|
+
existsSync as existsSync5,
|
|
5879
6314
|
mkdirSync as mkdirSync4,
|
|
5880
|
-
readFileSync as
|
|
6315
|
+
readFileSync as readFileSync9,
|
|
5881
6316
|
rmSync
|
|
5882
6317
|
} from "fs";
|
|
5883
6318
|
import { X509Certificate as X509Certificate2 } from "crypto";
|
|
5884
6319
|
import { isIP as isIP4 } from "net";
|
|
5885
6320
|
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 = () =>
|
|
6321
|
+
import { join as join16 } from "path";
|
|
6322
|
+
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
6323
|
const normalized = new Set(DEFAULT_CERTIFICATE_HOSTS);
|
|
5889
6324
|
for (const host2 of hosts) {
|
|
5890
6325
|
const value = host2.trim().toLowerCase();
|
|
@@ -5898,7 +6333,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
5898
6333
|
return [...normalized];
|
|
5899
6334
|
}, certificateIsUsable = (hosts) => {
|
|
5900
6335
|
try {
|
|
5901
|
-
const certPem =
|
|
6336
|
+
const certPem = readFileSync9(CERT_PATH, "utf-8");
|
|
5902
6337
|
const certificate = new X509Certificate2(certPem);
|
|
5903
6338
|
if (new Date(certificate.validTo).getTime() <= Date.now())
|
|
5904
6339
|
return false;
|
|
@@ -5983,8 +6418,8 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
5983
6418
|
return null;
|
|
5984
6419
|
try {
|
|
5985
6420
|
return {
|
|
5986
|
-
cert:
|
|
5987
|
-
key:
|
|
6421
|
+
cert: readFileSync9(paths.cert, "utf-8"),
|
|
6422
|
+
key: readFileSync9(paths.key, "utf-8")
|
|
5988
6423
|
};
|
|
5989
6424
|
} catch {
|
|
5990
6425
|
return null;
|
|
@@ -6080,7 +6515,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6080
6515
|
if (platform2() !== "linux")
|
|
6081
6516
|
return false;
|
|
6082
6517
|
try {
|
|
6083
|
-
return /microsoft|wsl/i.test(
|
|
6518
|
+
return /microsoft|wsl/i.test(readFileSync9("/proc/version", "utf-8"));
|
|
6084
6519
|
} catch {
|
|
6085
6520
|
return false;
|
|
6086
6521
|
}
|
|
@@ -6096,8 +6531,8 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6096
6531
|
}
|
|
6097
6532
|
}, mkcertCaRoot = () => runCapture(["mkcert", "-CAROOT"]), getDevCertificateAuthorityPath = () => {
|
|
6098
6533
|
const caRoot = hasMkcert() ? mkcertCaRoot() : null;
|
|
6099
|
-
const rootCertificate = caRoot ?
|
|
6100
|
-
if (rootCertificate &&
|
|
6534
|
+
const rootCertificate = caRoot ? join16(caRoot, "rootCA.pem") : null;
|
|
6535
|
+
if (rootCertificate && existsSync5(rootCertificate))
|
|
6101
6536
|
return rootCertificate;
|
|
6102
6537
|
if (certFilesExist())
|
|
6103
6538
|
return CERT_PATH;
|
|
@@ -6111,13 +6546,13 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6111
6546
|
const caRoot = mkcertCaRoot();
|
|
6112
6547
|
if (!caRoot)
|
|
6113
6548
|
return false;
|
|
6114
|
-
const rootCa =
|
|
6115
|
-
if (!
|
|
6549
|
+
const rootCa = join16(caRoot, "rootCA.pem");
|
|
6550
|
+
if (!existsSync5(rootCa))
|
|
6116
6551
|
return false;
|
|
6117
6552
|
const winTemp = windowsTempDir();
|
|
6118
6553
|
if (!winTemp)
|
|
6119
6554
|
return false;
|
|
6120
|
-
const staged =
|
|
6555
|
+
const staged = join16(winTemp, "absolutejs-mkcert-rootCA.crt");
|
|
6121
6556
|
try {
|
|
6122
6557
|
copyFileSync(rootCa, staged);
|
|
6123
6558
|
} catch {
|
|
@@ -6153,7 +6588,7 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6153
6588
|
devLog("Trusted the local CA in the Windows store \u2014 Chrome/Edge on Windows now accept dev HTTPS");
|
|
6154
6589
|
} else {
|
|
6155
6590
|
const caRoot = mkcertCaRoot();
|
|
6156
|
-
const hint = caRoot ? toWindowsPath(
|
|
6591
|
+
const hint = caRoot ? toWindowsPath(join16(caRoot, "rootCA.pem")) : null;
|
|
6157
6592
|
devWarn("Could not auto-trust the local CA on Windows; Windows browsers may warn.");
|
|
6158
6593
|
if (hint) {
|
|
6159
6594
|
console.log(` Run in PowerShell: Import-Certificate -FilePath "${hint}" -CertStoreLocation Cert:\\CurrentUser\\Root`);
|
|
@@ -6169,9 +6604,9 @@ var CERT_DIR, CERT_PATH, KEY_PATH, CERT_VALIDITY_DAYS = 365, DEFAULT_CERTIFICATE
|
|
|
6169
6604
|
return true;
|
|
6170
6605
|
};
|
|
6171
6606
|
var init_devCert = __esm(() => {
|
|
6172
|
-
CERT_DIR =
|
|
6173
|
-
CERT_PATH =
|
|
6174
|
-
KEY_PATH =
|
|
6607
|
+
CERT_DIR = join16(process.cwd(), ".absolutejs");
|
|
6608
|
+
CERT_PATH = join16(CERT_DIR, "cert.pem");
|
|
6609
|
+
KEY_PATH = join16(CERT_DIR, "key.pem");
|
|
6175
6610
|
DEFAULT_CERTIFICATE_HOSTS = ["localhost", "127.0.0.1", "::1"];
|
|
6176
6611
|
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
6612
|
});
|
|
@@ -6187,9 +6622,9 @@ __export(exports_eslintChunked, {
|
|
|
6187
6622
|
ruleSummary: () => ruleSummary,
|
|
6188
6623
|
upstreamRef: () => upstreamRef
|
|
6189
6624
|
});
|
|
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 = (
|
|
6625
|
+
import { existsSync as existsSync7 } from "fs";
|
|
6626
|
+
import { relative as relative8, resolve as resolve11 } from "path";
|
|
6627
|
+
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
6628
|
`).map((line) => line.trimEnd()).filter(Boolean), applyChangedBase = (parsed, base) => {
|
|
6194
6629
|
parsed.changedOnly = true;
|
|
6195
6630
|
parsed.changedBase = base;
|
|
@@ -6200,7 +6635,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6200
6635
|
}, matchesAnyGlob = (file, globs) => globs.some((pattern) => new Bun.Glob(pattern).match(file)), resolveLintSet = (parsed, cwd) => {
|
|
6201
6636
|
const visible = gitVisibleFiles(cwd);
|
|
6202
6637
|
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) =>
|
|
6638
|
+
return matched.filter((file) => existsSync7(resolve11(cwd, file))).sort();
|
|
6204
6639
|
}, resolveLintTargets = (args, cwd = process.cwd()) => resolveLintSet(parseChunkedArgs(args), cwd), buildShardChunks = (files, shards, chunkSize) => {
|
|
6205
6640
|
const shardFiles = Array.from({ length: shards }, () => []);
|
|
6206
6641
|
for (const file of files)
|
|
@@ -6222,7 +6657,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6222
6657
|
"content"
|
|
6223
6658
|
];
|
|
6224
6659
|
const proc = Bun.spawn([
|
|
6225
|
-
|
|
6660
|
+
resolve11(cwd, "node_modules/.bin/eslint"),
|
|
6226
6661
|
"--color",
|
|
6227
6662
|
...hasMaxWarnings ? [] : ["--max-warnings", "0"],
|
|
6228
6663
|
...cacheArgs,
|
|
@@ -6269,7 +6704,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6269
6704
|
const fingerprint = createEslintCacheFingerprint(cwd);
|
|
6270
6705
|
for (let shard = 0;shard < parsed.shards; shard++)
|
|
6271
6706
|
prepareEslintCache({
|
|
6272
|
-
cacheLocation:
|
|
6707
|
+
cacheLocation: relative8(cwd, resolve11(cwd, `${cachePrefix}${shard}`)),
|
|
6273
6708
|
cwd,
|
|
6274
6709
|
fingerprint
|
|
6275
6710
|
});
|
|
@@ -6310,7 +6745,7 @@ var DEFAULT_CHUNK_SIZE = 20, DEFAULT_SHARDS = 4, DEFAULT_CONCURRENCY = 2, DEFAUL
|
|
|
6310
6745
|
const header = `eslint report \u2014 ${files.length} files, ${totalChunks} chunks, ${elapsed}s
|
|
6311
6746
|
${"=".repeat(SUMMARY_RULE_WIDTH)}
|
|
6312
6747
|
`;
|
|
6313
|
-
await Bun.write(
|
|
6748
|
+
await Bun.write(resolve11(cwd, parsed.outFile), header + report + summary);
|
|
6314
6749
|
console.log(summary);
|
|
6315
6750
|
console.log(`Full report written to ${parsed.outFile}`);
|
|
6316
6751
|
if (failedChunks > 0) {
|
|
@@ -6397,14 +6832,14 @@ var init_eslintChunked = __esm(() => {
|
|
|
6397
6832
|
// src/cli/scripts/eslint.ts
|
|
6398
6833
|
import { createHash as createHash7 } from "crypto";
|
|
6399
6834
|
import {
|
|
6400
|
-
existsSync as
|
|
6835
|
+
existsSync as existsSync8,
|
|
6401
6836
|
mkdirSync as mkdirSync5,
|
|
6402
|
-
readFileSync as
|
|
6837
|
+
readFileSync as readFileSync11,
|
|
6403
6838
|
renameSync,
|
|
6404
6839
|
rmSync as rmSync3,
|
|
6405
6840
|
writeFileSync as writeFileSync5
|
|
6406
6841
|
} from "fs";
|
|
6407
|
-
import { dirname as dirname9, relative as
|
|
6842
|
+
import { dirname as dirname9, relative as relative9, resolve as resolve12 } from "path";
|
|
6408
6843
|
var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION = "1", CACHE_FINGERPRINT_SUFFIX = ".fingerprint", flagValue = (args, flag) => {
|
|
6409
6844
|
const assignment = args.find((arg) => arg.startsWith(`${flag}=`));
|
|
6410
6845
|
if (assignment)
|
|
@@ -6428,20 +6863,20 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6428
6863
|
return false;
|
|
6429
6864
|
}, findEslintConfigPath = (cwd = process.cwd()) => {
|
|
6430
6865
|
for (const name of CONFIG_CANDIDATES) {
|
|
6431
|
-
const candidate =
|
|
6432
|
-
if (
|
|
6866
|
+
const candidate = resolve12(cwd, name);
|
|
6867
|
+
if (existsSync8(candidate))
|
|
6433
6868
|
return candidate;
|
|
6434
6869
|
}
|
|
6435
6870
|
return null;
|
|
6436
6871
|
}, fingerprintLocation = (cacheLocation, cwd) => {
|
|
6437
|
-
const absolute =
|
|
6438
|
-
return /[\\/]$/.test(cacheLocation) ?
|
|
6872
|
+
const absolute = resolve12(cwd, cacheLocation);
|
|
6873
|
+
return /[\\/]$/.test(cacheLocation) ? resolve12(absolute, CACHE_FINGERPRINT_SUFFIX.slice(1)) : `${absolute}${CACHE_FINGERPRINT_SUFFIX}`;
|
|
6439
6874
|
}, addFileToFingerprint = (hash, path, label) => {
|
|
6440
|
-
if (!
|
|
6875
|
+
if (!existsSync8(path))
|
|
6441
6876
|
return;
|
|
6442
6877
|
hash.update(label);
|
|
6443
6878
|
hash.update("\x00");
|
|
6444
|
-
hash.update(
|
|
6879
|
+
hash.update(readFileSync11(path));
|
|
6445
6880
|
hash.update("\x00");
|
|
6446
6881
|
}, packageNameFor = (specifier) => {
|
|
6447
6882
|
if (specifier.startsWith("@"))
|
|
@@ -6451,7 +6886,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6451
6886
|
}, configPackageNames = (configPath2) => {
|
|
6452
6887
|
if (!configPath2)
|
|
6453
6888
|
return [];
|
|
6454
|
-
const source =
|
|
6889
|
+
const source = readFileSync11(configPath2, "utf-8");
|
|
6455
6890
|
const names = new Set;
|
|
6456
6891
|
for (const match of source.matchAll(/(?:from\s+|import\s*(?:\(\s*)?|require\s*\(\s*)(['"])([^'".][^'"]*)\1/g)) {
|
|
6457
6892
|
const [, , specifier] = match;
|
|
@@ -6470,11 +6905,11 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6470
6905
|
return Object.keys(value);
|
|
6471
6906
|
});
|
|
6472
6907
|
}, lintDependencyNames = (cwd, configPath2) => {
|
|
6473
|
-
const manifestPath =
|
|
6474
|
-
if (!
|
|
6908
|
+
const manifestPath = resolve12(cwd, "package.json");
|
|
6909
|
+
if (!existsSync8(manifestPath))
|
|
6475
6910
|
return configPackageNames(configPath2);
|
|
6476
6911
|
try {
|
|
6477
|
-
const manifest = JSON.parse(
|
|
6912
|
+
const manifest = JSON.parse(readFileSync11(manifestPath, "utf-8"));
|
|
6478
6913
|
const lintPackages = manifestDependencyNames(manifest).filter((name) => /eslint|typescript/.test(name));
|
|
6479
6914
|
return [
|
|
6480
6915
|
...new Set([...lintPackages, ...configPackageNames(configPath2)])
|
|
@@ -6485,8 +6920,8 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6485
6920
|
}, findInstalledManifest = (cwd, dependency) => {
|
|
6486
6921
|
let directory = cwd;
|
|
6487
6922
|
while (true) {
|
|
6488
|
-
const candidate =
|
|
6489
|
-
if (
|
|
6923
|
+
const candidate = resolve12(directory, "node_modules", dependency, "package.json");
|
|
6924
|
+
if (existsSync8(candidate))
|
|
6490
6925
|
return candidate;
|
|
6491
6926
|
const parent = dirname9(directory);
|
|
6492
6927
|
if (parent === directory)
|
|
@@ -6508,7 +6943,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6508
6943
|
hash.update(`absolute-eslint-config:${CACHE_CONTRACT_VERSION}\x00`);
|
|
6509
6944
|
const configPath2 = findEslintConfigPath(cwd);
|
|
6510
6945
|
if (configPath2)
|
|
6511
|
-
addFileToFingerprint(hash, configPath2,
|
|
6946
|
+
addFileToFingerprint(hash, configPath2, relative9(cwd, configPath2));
|
|
6512
6947
|
return hash.digest("hex");
|
|
6513
6948
|
}, writeFingerprint = (path, fingerprint) => {
|
|
6514
6949
|
mkdirSync5(dirname9(path), { recursive: true });
|
|
@@ -6518,10 +6953,10 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6518
6953
|
renameSync(temporary, path);
|
|
6519
6954
|
}, prepareEslintCache = (options) => {
|
|
6520
6955
|
const cwd = options.cwd ?? process.cwd();
|
|
6521
|
-
const cachePath =
|
|
6956
|
+
const cachePath = resolve12(cwd, options.cacheLocation);
|
|
6522
6957
|
const metadataPath = fingerprintLocation(options.cacheLocation, cwd);
|
|
6523
6958
|
const fingerprint = options.fingerprint ?? createEslintCacheFingerprint(cwd);
|
|
6524
|
-
const prior =
|
|
6959
|
+
const prior = existsSync8(metadataPath) ? readFileSync11(metadataPath, "utf-8").trim() : null;
|
|
6525
6960
|
if (prior === fingerprint)
|
|
6526
6961
|
return false;
|
|
6527
6962
|
rmSync3(cachePath, { force: true, recursive: true });
|
|
@@ -6609,7 +7044,7 @@ var DEFAULT_CACHE_LOCATION = ".absolutejs/eslint-cache", CACHE_CONTRACT_VERSION
|
|
|
6609
7044
|
return;
|
|
6610
7045
|
let source;
|
|
6611
7046
|
try {
|
|
6612
|
-
source =
|
|
7047
|
+
source = readFileSync11(configPath2, "utf-8");
|
|
6613
7048
|
} catch {
|
|
6614
7049
|
return;
|
|
6615
7050
|
}
|
|
@@ -6648,7 +7083,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6648
7083
|
return `${minutes}m ${seconds}s`;
|
|
6649
7084
|
}, handleClearCache = (cacheLocation, cwd = process.cwd()) => {
|
|
6650
7085
|
try {
|
|
6651
|
-
const cachePath =
|
|
7086
|
+
const cachePath = resolve12(cwd, cacheLocation);
|
|
6652
7087
|
const metadataPath = fingerprintLocation(cacheLocation, cwd);
|
|
6653
7088
|
rmSync3(cachePath, { force: true, recursive: true });
|
|
6654
7089
|
rmSync3(metadataPath, { force: true, recursive: true });
|
|
@@ -6677,7 +7112,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6677
7112
|
return;
|
|
6678
7113
|
}
|
|
6679
7114
|
if (args.includes("--chunked")) {
|
|
6680
|
-
if (!
|
|
7115
|
+
if (!existsSync8(resolve12("node_modules", ".bin", "eslint"))) {
|
|
6681
7116
|
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
7117
|
process.exit(1);
|
|
6683
7118
|
}
|
|
@@ -6685,7 +7120,7 @@ Detected at: ${configPath2}${reset}`);
|
|
|
6685
7120
|
await eslintChunked2(args);
|
|
6686
7121
|
return;
|
|
6687
7122
|
}
|
|
6688
|
-
if (!
|
|
7123
|
+
if (!existsSync8(resolve12("node_modules", ".bin", "eslint"))) {
|
|
6689
7124
|
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
7125
|
process.exit(1);
|
|
6691
7126
|
}
|
|
@@ -6876,8 +7311,8 @@ var isRecord4 = (value) => typeof value === "object" && value !== null, getIslan
|
|
|
6876
7311
|
var init_islands = () => {};
|
|
6877
7312
|
|
|
6878
7313
|
// src/build/islandEntries.ts
|
|
6879
|
-
import { dirname as dirname10, extname, join as
|
|
6880
|
-
import
|
|
7314
|
+
import { dirname as dirname10, extname as extname2, join as join19, relative as relative10, resolve as resolve14 } from "path";
|
|
7315
|
+
import ts2 from "typescript";
|
|
6881
7316
|
var frameworks, isRecord5 = (value) => typeof value === "object" && value !== null, resolveRegistryExport = (mod) => {
|
|
6882
7317
|
if (isRecord5(mod.islandRegistry))
|
|
6883
7318
|
return mod.islandRegistry;
|
|
@@ -6888,9 +7323,9 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6888
7323
|
if (sourcePath.startsWith("file://")) {
|
|
6889
7324
|
return new URL(sourcePath).pathname;
|
|
6890
7325
|
}
|
|
6891
|
-
return
|
|
7326
|
+
return resolve14(dirname10(registryPath), sourcePath);
|
|
6892
7327
|
}, getObjectPropertyName = (name) => {
|
|
6893
|
-
if (
|
|
7328
|
+
if (ts2.isIdentifier(name) || ts2.isStringLiteral(name)) {
|
|
6894
7329
|
return name.text;
|
|
6895
7330
|
}
|
|
6896
7331
|
return null;
|
|
@@ -6903,7 +7338,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6903
7338
|
});
|
|
6904
7339
|
}, collectNamedImports = (imports, importClause, source) => {
|
|
6905
7340
|
const bindings = importClause.namedBindings;
|
|
6906
|
-
if (!bindings || !
|
|
7341
|
+
if (!bindings || !ts2.isNamedImports(bindings))
|
|
6907
7342
|
return;
|
|
6908
7343
|
for (const element of bindings.elements) {
|
|
6909
7344
|
imports.set(element.name.text, {
|
|
@@ -6917,7 +7352,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6917
7352
|
const bindings = importClause.namedBindings;
|
|
6918
7353
|
if (!bindings)
|
|
6919
7354
|
return;
|
|
6920
|
-
if (
|
|
7355
|
+
if (ts2.isNamespaceImport(bindings)) {
|
|
6921
7356
|
registryNamespaceNames.add(bindings.name.text);
|
|
6922
7357
|
return;
|
|
6923
7358
|
}
|
|
@@ -6935,13 +7370,13 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6935
7370
|
const frameworkRegistry = registry2[framework] ?? {};
|
|
6936
7371
|
registry2[framework] = frameworkRegistry;
|
|
6937
7372
|
for (const property of frameworkNode.properties) {
|
|
6938
|
-
if (!
|
|
7373
|
+
if (!ts2.isPropertyAssignment(property) && !ts2.isShorthandPropertyAssignment(property))
|
|
6939
7374
|
continue;
|
|
6940
7375
|
const componentName = getObjectPropertyName(property.name);
|
|
6941
7376
|
if (!componentName)
|
|
6942
7377
|
continue;
|
|
6943
|
-
const initializer =
|
|
6944
|
-
if (!
|
|
7378
|
+
const initializer = ts2.isPropertyAssignment(property) ? property.initializer : property.name;
|
|
7379
|
+
if (!ts2.isIdentifier(initializer))
|
|
6945
7380
|
continue;
|
|
6946
7381
|
const reference = imports.get(initializer.text);
|
|
6947
7382
|
if (!reference)
|
|
@@ -6955,7 +7390,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6955
7390
|
}
|
|
6956
7391
|
}, processDefineIslandRegistry = (node, imports, definitions, registry2) => {
|
|
6957
7392
|
const [firstArg] = node.arguments;
|
|
6958
|
-
if (!firstArg || !
|
|
7393
|
+
if (!firstArg || !ts2.isObjectLiteralExpression(firstArg))
|
|
6959
7394
|
return;
|
|
6960
7395
|
const validFrameworks = [
|
|
6961
7396
|
"react",
|
|
@@ -6964,7 +7399,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6964
7399
|
"angular"
|
|
6965
7400
|
];
|
|
6966
7401
|
for (const property of firstArg.properties) {
|
|
6967
|
-
if (!
|
|
7402
|
+
if (!ts2.isPropertyAssignment(property))
|
|
6968
7403
|
continue;
|
|
6969
7404
|
const frameworkName = getObjectPropertyName(property.name);
|
|
6970
7405
|
if (!frameworkName)
|
|
@@ -6972,28 +7407,28 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
6972
7407
|
const framework = validFrameworks.find((f) => f === frameworkName);
|
|
6973
7408
|
if (!framework)
|
|
6974
7409
|
continue;
|
|
6975
|
-
if (!
|
|
7410
|
+
if (!ts2.isObjectLiteralExpression(property.initializer))
|
|
6976
7411
|
continue;
|
|
6977
7412
|
addRegistryEntries(property.initializer, framework, imports, definitions, registry2);
|
|
6978
7413
|
}
|
|
6979
7414
|
}, walkRegistryNode = (node, imports, registryFactoryNames, registryNamespaceNames, definitions, registry2) => {
|
|
6980
|
-
if (
|
|
7415
|
+
if (ts2.isCallExpression(node) && isDefineIslandRegistryCall(node.expression, registryFactoryNames, registryNamespaceNames)) {
|
|
6981
7416
|
processDefineIslandRegistry(node, imports, definitions, registry2);
|
|
6982
7417
|
}
|
|
6983
|
-
|
|
7418
|
+
ts2.forEachChild(node, (child) => walkRegistryNode(child, imports, registryFactoryNames, registryNamespaceNames, definitions, registry2));
|
|
6984
7419
|
}, isDefineIslandRegistryCall = (expression, registryFactoryNames, registryNamespaceNames) => {
|
|
6985
|
-
if (
|
|
7420
|
+
if (ts2.isIdentifier(expression)) {
|
|
6986
7421
|
return registryFactoryNames.has(expression.text);
|
|
6987
7422
|
}
|
|
6988
|
-
return
|
|
7423
|
+
return ts2.isPropertyAccessExpression(expression) && expression.name.text === "defineIslandRegistry" && ts2.isIdentifier(expression.expression) && registryNamespaceNames.has(expression.expression.text);
|
|
6989
7424
|
}, hasIslandRegistryNamedExport = (sourceFile) => {
|
|
6990
7425
|
for (const statement of sourceFile.statements) {
|
|
6991
|
-
if (
|
|
7426
|
+
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
7427
|
return true;
|
|
6993
7428
|
}
|
|
6994
|
-
if (!
|
|
7429
|
+
if (!ts2.isExportDeclaration(statement) || !statement.exportClause)
|
|
6995
7430
|
continue;
|
|
6996
|
-
if (!
|
|
7431
|
+
if (!ts2.isNamedExports(statement.exportClause))
|
|
6997
7432
|
continue;
|
|
6998
7433
|
if (statement.exportClause.elements.some((element) => element.name.text === "islandRegistry")) {
|
|
6999
7434
|
return true;
|
|
@@ -7002,7 +7437,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7002
7437
|
return false;
|
|
7003
7438
|
}, collectImportDeclarations = (sourceFile, registryPath, imports, registryFactoryNames, registryNamespaceNames) => {
|
|
7004
7439
|
for (const statement of sourceFile.statements) {
|
|
7005
|
-
if (!
|
|
7440
|
+
if (!ts2.isImportDeclaration(statement) || !ts2.isStringLiteral(statement.moduleSpecifier))
|
|
7006
7441
|
continue;
|
|
7007
7442
|
const { importClause } = statement;
|
|
7008
7443
|
if (!importClause)
|
|
@@ -7013,7 +7448,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7013
7448
|
collectRegistryHelperImports(importClause, statement.moduleSpecifier.text, registryFactoryNames, registryNamespaceNames);
|
|
7014
7449
|
}
|
|
7015
7450
|
}, parseIslandRegistryBuildInfo = (registrySource, registryPath) => {
|
|
7016
|
-
const sourceFile =
|
|
7451
|
+
const sourceFile = ts2.createSourceFile(registryPath, registrySource, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
|
|
7017
7452
|
const imports = new Map;
|
|
7018
7453
|
const registryFactoryNames = new Set(["defineIslandRegistry"]);
|
|
7019
7454
|
const registryNamespaceNames = new Set;
|
|
@@ -7045,7 +7480,7 @@ var frameworks, isRecord5 = (value) => typeof value === "object" && value !== nu
|
|
|
7045
7480
|
registry: registry2
|
|
7046
7481
|
};
|
|
7047
7482
|
}, loadIslandRegistryBuildInfo = async (registryPath) => {
|
|
7048
|
-
const resolvedRegistryPath =
|
|
7483
|
+
const resolvedRegistryPath = resolve14(registryPath);
|
|
7049
7484
|
const registrySource = Bun.file(resolvedRegistryPath);
|
|
7050
7485
|
const registrySourceText = await registrySource.text();
|
|
7051
7486
|
const parsedInfo = parseIslandRegistryBuildInfo(registrySourceText, resolvedRegistryPath);
|
|
@@ -7075,25 +7510,25 @@ var init_islandEntries = __esm(() => {
|
|
|
7075
7510
|
|
|
7076
7511
|
// src/build/islandRegistryTransform.ts
|
|
7077
7512
|
import { basename as basename6 } from "path";
|
|
7078
|
-
import
|
|
7079
|
-
var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) =>
|
|
7513
|
+
import ts3 from "typescript";
|
|
7514
|
+
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
7515
|
const factoryNames = new Set;
|
|
7081
7516
|
const namespaceNames = new Set;
|
|
7082
7517
|
for (const statement of sourceFile.statements) {
|
|
7083
|
-
if (!
|
|
7518
|
+
if (!ts3.isImportDeclaration(statement))
|
|
7084
7519
|
continue;
|
|
7085
|
-
if (!
|
|
7520
|
+
if (!ts3.isStringLiteral(statement.moduleSpecifier))
|
|
7086
7521
|
continue;
|
|
7087
7522
|
if (!isIslandRegistryHelperImport2(statement.moduleSpecifier.text))
|
|
7088
7523
|
continue;
|
|
7089
7524
|
const bindings = statement.importClause?.namedBindings;
|
|
7090
7525
|
if (!bindings)
|
|
7091
7526
|
continue;
|
|
7092
|
-
if (
|
|
7527
|
+
if (ts3.isNamespaceImport(bindings)) {
|
|
7093
7528
|
namespaceNames.add(bindings.name.text);
|
|
7094
7529
|
continue;
|
|
7095
7530
|
}
|
|
7096
|
-
if (!
|
|
7531
|
+
if (!ts3.isNamedImports(bindings))
|
|
7097
7532
|
continue;
|
|
7098
7533
|
for (const element of bindings.elements) {
|
|
7099
7534
|
const imported = element.propertyName?.text ?? element.name.text;
|
|
@@ -7104,20 +7539,20 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7104
7539
|
}
|
|
7105
7540
|
return { factoryNames, namespaceNames };
|
|
7106
7541
|
}, isDefineIslandRegistryCall2 = (expression, factoryNames, namespaceNames) => {
|
|
7107
|
-
if (
|
|
7542
|
+
if (ts3.isIdentifier(expression))
|
|
7108
7543
|
return factoryNames.has(expression.text);
|
|
7109
|
-
return
|
|
7544
|
+
return ts3.isPropertyAccessExpression(expression) && expression.name.text === "defineIslandRegistry" && ts3.isIdentifier(expression.expression) && namespaceNames.has(expression.expression.text);
|
|
7110
7545
|
}, findDefineIslandRegistryCall = (sourceFile, factoryNames, namespaceNames) => {
|
|
7111
7546
|
let found = null;
|
|
7112
7547
|
const visit = (node) => {
|
|
7113
7548
|
if (found)
|
|
7114
7549
|
return;
|
|
7115
|
-
const [firstArg] =
|
|
7116
|
-
if (
|
|
7550
|
+
const [firstArg] = ts3.isCallExpression(node) ? node.arguments : [];
|
|
7551
|
+
if (ts3.isCallExpression(node) && isDefineIslandRegistryCall2(node.expression, factoryNames, namespaceNames) && firstArg && ts3.isObjectLiteralExpression(firstArg)) {
|
|
7117
7552
|
found = node;
|
|
7118
7553
|
return;
|
|
7119
7554
|
}
|
|
7120
|
-
|
|
7555
|
+
ts3.forEachChild(node, visit);
|
|
7121
7556
|
};
|
|
7122
7557
|
visit(sourceFile);
|
|
7123
7558
|
return found;
|
|
@@ -7127,8 +7562,8 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7127
7562
|
}, transformIslandRegistrySource = (source, filePath, info2) => {
|
|
7128
7563
|
if (!source.includes("defineIslandRegistry"))
|
|
7129
7564
|
return null;
|
|
7130
|
-
const scriptKind = filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ?
|
|
7131
|
-
const sourceFile =
|
|
7565
|
+
const scriptKind = filePath.endsWith(".tsx") || filePath.endsWith(".jsx") ? ts3.ScriptKind.TSX : ts3.ScriptKind.TS;
|
|
7566
|
+
const sourceFile = ts3.createSourceFile(filePath, source, ts3.ScriptTarget.Latest, true, scriptKind);
|
|
7132
7567
|
const { factoryNames, namespaceNames } = collectRegistryFactory(sourceFile);
|
|
7133
7568
|
if (factoryNames.size === 0 && namespaceNames.size === 0)
|
|
7134
7569
|
return null;
|
|
@@ -7136,7 +7571,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7136
7571
|
if (!call)
|
|
7137
7572
|
return null;
|
|
7138
7573
|
const [objectLiteral] = call.arguments;
|
|
7139
|
-
if (!objectLiteral || !
|
|
7574
|
+
if (!objectLiteral || !ts3.isObjectLiteralExpression(objectLiteral)) {
|
|
7140
7575
|
return null;
|
|
7141
7576
|
}
|
|
7142
7577
|
const definitionLookup = new Map;
|
|
@@ -7151,20 +7586,20 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7151
7586
|
const edits = [];
|
|
7152
7587
|
const replacedLocals = new Set;
|
|
7153
7588
|
for (const frameworkProperty of objectLiteral.properties) {
|
|
7154
|
-
if (!
|
|
7589
|
+
if (!ts3.isPropertyAssignment(frameworkProperty))
|
|
7155
7590
|
continue;
|
|
7156
7591
|
const frameworkName = getObjectPropertyName2(frameworkProperty.name);
|
|
7157
7592
|
const framework = VALID_FRAMEWORKS.find((f) => f === frameworkName);
|
|
7158
7593
|
if (!framework)
|
|
7159
7594
|
continue;
|
|
7160
|
-
if (!
|
|
7595
|
+
if (!ts3.isObjectLiteralExpression(frameworkProperty.initializer))
|
|
7161
7596
|
continue;
|
|
7162
7597
|
for (const componentProperty of frameworkProperty.initializer.properties) {
|
|
7163
7598
|
let componentKey = null;
|
|
7164
7599
|
let localName = null;
|
|
7165
7600
|
let replaceNode = null;
|
|
7166
7601
|
let replacementText = "";
|
|
7167
|
-
if (
|
|
7602
|
+
if (ts3.isShorthandPropertyAssignment(componentProperty)) {
|
|
7168
7603
|
componentKey = componentProperty.name.text;
|
|
7169
7604
|
localName = componentProperty.name.text;
|
|
7170
7605
|
const reference = definitionLookup.get(`${framework}:${componentKey}`);
|
|
@@ -7172,7 +7607,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7172
7607
|
continue;
|
|
7173
7608
|
replaceNode = componentProperty;
|
|
7174
7609
|
replacementText = `${quoteKey(componentKey)}: ${definitionLiteral(reference)}`;
|
|
7175
|
-
} else if (
|
|
7610
|
+
} else if (ts3.isPropertyAssignment(componentProperty) && ts3.isIdentifier(componentProperty.initializer)) {
|
|
7176
7611
|
componentKey = getObjectPropertyName2(componentProperty.name);
|
|
7177
7612
|
localName = componentProperty.initializer.text;
|
|
7178
7613
|
if (!componentKey)
|
|
@@ -7196,7 +7631,7 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7196
7631
|
if (edits.length === 0)
|
|
7197
7632
|
return null;
|
|
7198
7633
|
for (const statement of sourceFile.statements) {
|
|
7199
|
-
if (!
|
|
7634
|
+
if (!ts3.isImportDeclaration(statement))
|
|
7200
7635
|
continue;
|
|
7201
7636
|
const clause = statement.importClause;
|
|
7202
7637
|
if (!clause)
|
|
@@ -7205,11 +7640,11 @@ var VALID_FRAMEWORKS, getObjectPropertyName2 = (name) => ts2.isIdentifier(name)
|
|
|
7205
7640
|
if (clause.name)
|
|
7206
7641
|
localNames.push(clause.name.text);
|
|
7207
7642
|
const bindings = clause.namedBindings;
|
|
7208
|
-
if (bindings &&
|
|
7643
|
+
if (bindings && ts3.isNamedImports(bindings)) {
|
|
7209
7644
|
for (const element of bindings.elements) {
|
|
7210
7645
|
localNames.push(element.name.text);
|
|
7211
7646
|
}
|
|
7212
|
-
} else if (bindings &&
|
|
7647
|
+
} else if (bindings && ts3.isNamespaceImport(bindings)) {
|
|
7213
7648
|
localNames.push(bindings.name.text);
|
|
7214
7649
|
}
|
|
7215
7650
|
if (localNames.length === 0)
|
|
@@ -7266,18 +7701,18 @@ var init_islandRegistryTransform = __esm(() => {
|
|
|
7266
7701
|
});
|
|
7267
7702
|
|
|
7268
7703
|
// src/build/bunStringRawUnicodePlugin.ts
|
|
7269
|
-
import { extname as
|
|
7270
|
-
import
|
|
7704
|
+
import { extname as extname3 } from "path";
|
|
7705
|
+
import ts4 from "typescript";
|
|
7271
7706
|
var NON_ASCII, getScriptKind = (filePath) => {
|
|
7272
7707
|
if (/\.[cm]?tsx$/.test(filePath))
|
|
7273
|
-
return
|
|
7708
|
+
return ts4.ScriptKind.TSX;
|
|
7274
7709
|
if (/\.[cm]?jsx$/.test(filePath))
|
|
7275
|
-
return
|
|
7710
|
+
return ts4.ScriptKind.JSX;
|
|
7276
7711
|
if (/\.[cm]?ts$/.test(filePath))
|
|
7277
|
-
return
|
|
7278
|
-
return
|
|
7712
|
+
return ts4.ScriptKind.TS;
|
|
7713
|
+
return ts4.ScriptKind.JS;
|
|
7279
7714
|
}, getLoader = (filePath) => {
|
|
7280
|
-
const extension =
|
|
7715
|
+
const extension = extname3(filePath);
|
|
7281
7716
|
if (extension === ".tsx")
|
|
7282
7717
|
return "tsx";
|
|
7283
7718
|
if (extension === ".jsx")
|
|
@@ -7286,24 +7721,24 @@ var NON_ASCII, getScriptKind = (filePath) => {
|
|
|
7286
7721
|
return "ts";
|
|
7287
7722
|
}
|
|
7288
7723
|
return "js";
|
|
7289
|
-
}, isStringRawTag = (node) =>
|
|
7724
|
+
}, 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
7725
|
if (!source.includes("String.raw") || !NON_ASCII.test(source))
|
|
7291
7726
|
return source;
|
|
7292
|
-
const sourceFile =
|
|
7727
|
+
const sourceFile = ts4.createSourceFile(filePath, source, ts4.ScriptTarget.Latest, true, getScriptKind(filePath));
|
|
7293
7728
|
const replacements = [];
|
|
7294
7729
|
const visit = (node) => {
|
|
7295
|
-
if (
|
|
7296
|
-
const rawSegments =
|
|
7730
|
+
if (ts4.isTaggedTemplateExpression(node) && isStringRawTag(node)) {
|
|
7731
|
+
const rawSegments = ts4.isNoSubstitutionTemplateLiteral(node.template) ? [getRawText(node.template)] : [
|
|
7297
7732
|
getRawText(node.template.head),
|
|
7298
7733
|
...node.template.templateSpans.map((span) => getRawText(span.literal))
|
|
7299
7734
|
];
|
|
7300
7735
|
if (rawSegments.some((segment) => NON_ASCII.test(segment))) {
|
|
7301
|
-
const expressions =
|
|
7736
|
+
const expressions = ts4.isTemplateExpression(node.template) ? node.template.templateSpans.map((span) => {
|
|
7302
7737
|
const expression = source.slice(span.expression.getStart(sourceFile), span.expression.end);
|
|
7303
7738
|
return rewriteBunStringRawUnicode(expression, filePath);
|
|
7304
7739
|
}) : [];
|
|
7305
7740
|
const args = [
|
|
7306
|
-
`{ raw: [${rawSegments.map((
|
|
7741
|
+
`{ raw: [${rawSegments.map((text2) => JSON.stringify(text2)).join(", ")}] }`,
|
|
7307
7742
|
...expressions
|
|
7308
7743
|
];
|
|
7309
7744
|
replacements.push({
|
|
@@ -7314,7 +7749,7 @@ var NON_ASCII, getScriptKind = (filePath) => {
|
|
|
7314
7749
|
return;
|
|
7315
7750
|
}
|
|
7316
7751
|
}
|
|
7317
|
-
|
|
7752
|
+
ts4.forEachChild(node, visit);
|
|
7318
7753
|
};
|
|
7319
7754
|
visit(sourceFile);
|
|
7320
7755
|
let result = source;
|
|
@@ -7579,20 +8014,20 @@ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-
|
|
|
7579
8014
|
// src/mobile/buildRelease.ts
|
|
7580
8015
|
import { createHash as createHash9 } from "crypto";
|
|
7581
8016
|
import { mkdir as mkdir8, readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
7582
|
-
import { basename as basename7, dirname as dirname11, extname as
|
|
8017
|
+
import { basename as basename7, dirname as dirname11, extname as extname4, join as join20, relative as relative11, resolve as resolve15 } from "path";
|
|
7583
8018
|
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
8019
|
if (path.endsWith("/htmx.min.js"))
|
|
7585
8020
|
return match;
|
|
7586
|
-
const key = toPascal(basename7(path,
|
|
8021
|
+
const key = toPascal(basename7(path, extname4(path)));
|
|
7587
8022
|
const builtPath = manifest[key];
|
|
7588
8023
|
return builtPath ? `${prefix}${builtPath}${suffix}` : match;
|
|
7589
8024
|
}), readPageMetadata = (route) => parseAbsoluteMobileBuildPageMetadata(route.hooks?.detail?.[ABSOLUTE_MOBILE_ROUTE_DETAIL]), resolveAssetPath = (buildDirectory, assetPath) => {
|
|
7590
|
-
const resolvedBuildDirectory =
|
|
7591
|
-
const resolvedAsset =
|
|
8025
|
+
const resolvedBuildDirectory = resolve15(buildDirectory);
|
|
8026
|
+
const resolvedAsset = resolve15(assetPath);
|
|
7592
8027
|
if (resolvedAsset.startsWith(`${resolvedBuildDirectory}/`)) {
|
|
7593
8028
|
return resolvedAsset;
|
|
7594
8029
|
}
|
|
7595
|
-
return
|
|
8030
|
+
return join20(buildDirectory, assetPath.replace(/^\/+/, ""));
|
|
7596
8031
|
}, pageFor = async (metadata, manifest, buildDirectory) => {
|
|
7597
8032
|
const assetPath = manifest[metadata.bundleKey];
|
|
7598
8033
|
if (!assetPath) {
|
|
@@ -7603,7 +8038,7 @@ var sha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex"), STATI
|
|
|
7603
8038
|
const source = await readFile9(resolvedAssetPath, "utf8");
|
|
7604
8039
|
const rewritten = rewriteStaticScriptPaths(source, manifest);
|
|
7605
8040
|
const documentHash = sha256(new TextEncoder().encode(rewritten));
|
|
7606
|
-
resolvedAssetPath =
|
|
8041
|
+
resolvedAssetPath = join20(buildDirectory, ".absolutejs", "mobile-pages", `${documentHash}.html`);
|
|
7607
8042
|
await mkdir8(dirname11(resolvedAssetPath), { recursive: true });
|
|
7608
8043
|
await writeFile7(resolvedAssetPath, rewritten);
|
|
7609
8044
|
}
|
|
@@ -7617,8 +8052,8 @@ var sha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex"), STATI
|
|
|
7617
8052
|
readFile9(resolvedAssetPath),
|
|
7618
8053
|
resolvedStylePath ? readFile9(resolvedStylePath) : undefined
|
|
7619
8054
|
]);
|
|
7620
|
-
const bundlePath = `/${
|
|
7621
|
-
const styleBundlePath = resolvedStylePath ? `/${
|
|
8055
|
+
const bundlePath = `/${relative11(resolve15(buildDirectory), resolvedAssetPath).replaceAll("\\", "/")}`;
|
|
8056
|
+
const styleBundlePath = resolvedStylePath ? `/${relative11(resolve15(buildDirectory), resolvedStylePath).replaceAll("\\", "/")}` : undefined;
|
|
7622
8057
|
return {
|
|
7623
8058
|
bundleHash: sha256(bytes),
|
|
7624
8059
|
bundlePath,
|
|
@@ -7819,40 +8254,40 @@ import {
|
|
|
7819
8254
|
rm as rm6,
|
|
7820
8255
|
writeFile as writeFile8
|
|
7821
8256
|
} from "fs/promises";
|
|
7822
|
-
import { existsSync as
|
|
7823
|
-
import { basename as basename8, dirname as dirname12, extname as
|
|
8257
|
+
import { existsSync as existsSync10 } from "fs";
|
|
8258
|
+
import { basename as basename8, dirname as dirname12, extname as extname5, join as join21, relative as relative12, resolve as resolve16 } from "path";
|
|
7824
8259
|
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) =>
|
|
8260
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellBootstrap.${extension}`)).find(existsSync10);
|
|
7826
8261
|
if (candidate)
|
|
7827
8262
|
return candidate;
|
|
7828
8263
|
throw new TypeError("AbsoluteJS mobile shell bootstrap module is missing.");
|
|
7829
8264
|
}, shellAuthModule = () => {
|
|
7830
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8265
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellAuth.${extension}`)).find(existsSync10);
|
|
7831
8266
|
if (candidate)
|
|
7832
8267
|
return candidate;
|
|
7833
8268
|
throw new TypeError("AbsoluteJS mobile auth shell module is missing.");
|
|
7834
8269
|
}, shellExpoAuthModule = () => {
|
|
7835
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8270
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoAuth.${extension}`)).find(existsSync10);
|
|
7836
8271
|
if (candidate)
|
|
7837
8272
|
return candidate;
|
|
7838
8273
|
throw new TypeError("AbsoluteJS Expo auth bridge module is missing.");
|
|
7839
8274
|
}, shellSyncModule = () => {
|
|
7840
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8275
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellSync.${extension}`)).find(existsSync10);
|
|
7841
8276
|
if (candidate)
|
|
7842
8277
|
return candidate;
|
|
7843
8278
|
throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
|
|
7844
8279
|
}, shellExpoSyncModule = () => {
|
|
7845
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8280
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoSync.${extension}`)).find(existsSync10);
|
|
7846
8281
|
if (candidate)
|
|
7847
8282
|
return candidate;
|
|
7848
8283
|
throw new TypeError("AbsoluteJS Expo Sync bridge module is missing.");
|
|
7849
8284
|
}, shellPushModule = () => {
|
|
7850
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8285
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellPush.${extension}`)).find(existsSync10);
|
|
7851
8286
|
if (candidate)
|
|
7852
8287
|
return candidate;
|
|
7853
8288
|
throw new TypeError("AbsoluteJS mobile push shell module is missing.");
|
|
7854
8289
|
}, shellExpoDevicesModule = () => {
|
|
7855
|
-
const candidate = ["js", "ts"].map((extension) =>
|
|
8290
|
+
const candidate = ["js", "ts"].map((extension) => join21(import.meta.dir, `shellExpoDevices.${extension}`)).find(existsSync10);
|
|
7856
8291
|
if (candidate)
|
|
7857
8292
|
return candidate;
|
|
7858
8293
|
throw new TypeError("AbsoluteJS Expo device bridge module is missing.");
|
|
@@ -7883,8 +8318,8 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7883
8318
|
</body>
|
|
7884
8319
|
</html>
|
|
7885
8320
|
`, sourceAssetPath = (buildDirectory, bundlePath) => {
|
|
7886
|
-
const root =
|
|
7887
|
-
const asset =
|
|
8321
|
+
const root = resolve16(buildDirectory);
|
|
8322
|
+
const asset = resolve16(root, bundlePath.replace(/^\/+/, ""));
|
|
7888
8323
|
if (!asset.startsWith(`${root}/`)) {
|
|
7889
8324
|
throw new TypeError("Mobile page bundle escaped the build directory.");
|
|
7890
8325
|
}
|
|
@@ -7899,15 +8334,15 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7899
8334
|
const segments = specifier.split("/");
|
|
7900
8335
|
const packageName = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0] ?? "";
|
|
7901
8336
|
const subpath = specifier.slice(packageName.length);
|
|
7902
|
-
const packageDirectory =
|
|
7903
|
-
const manifest = JSON.parse(await readFile10(
|
|
8337
|
+
const packageDirectory = join21(resolve16(projectRoot), "node_modules", packageName);
|
|
8338
|
+
const manifest = JSON.parse(await readFile10(join21(packageDirectory, "package.json"), "utf8"));
|
|
7904
8339
|
const exports = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "exports") : undefined;
|
|
7905
8340
|
const entry = typeof exports === "object" && exports !== null ? Reflect.get(exports, subpath ? `.${subpath}` : ".") : undefined;
|
|
7906
8341
|
const target = importEntryTarget(entry);
|
|
7907
8342
|
if (typeof target !== "string" || !target.startsWith("./"))
|
|
7908
8343
|
throw new TypeError(`${specifier} does not publish an import entry.`);
|
|
7909
|
-
const resolved =
|
|
7910
|
-
if (!resolved.startsWith(`${
|
|
8344
|
+
const resolved = resolve16(packageDirectory, target);
|
|
8345
|
+
if (!resolved.startsWith(`${resolve16(packageDirectory)}/`))
|
|
7911
8346
|
throw new TypeError(`${specifier} has an unsafe import entry.`);
|
|
7912
8347
|
return resolved;
|
|
7913
8348
|
}, buildShellBootstrap = async (staging, auth, sync, storagePrefix, engine, deviceCapabilities, projectRoot) => {
|
|
@@ -7936,10 +8371,10 @@ var MANIFEST_FILE = "absolute-mobile-manifest.json", BOOTSTRAP_FILE = "absolute-
|
|
|
7936
8371
|
const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absoluteMobilePush.capabilityOptions);
|
|
7937
8372
|
` : "";
|
|
7938
8373
|
const capabilityOptions = shellCapabilities.map((name, index) => `${JSON.stringify(name)}: ${name === "pushNotifications" ? "absoluteMobilePushCapability" : `absoluteDeviceCapability${index}()`}`).join(", ");
|
|
7939
|
-
const entryPath =
|
|
8374
|
+
const entryPath = join21(staging, ".absolute-mobile-entry.ts");
|
|
7940
8375
|
const baseAdapterModule = capacitor ? await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor") : shellExpoDevicesModule();
|
|
7941
8376
|
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}` : ""} });` :
|
|
8377
|
+
const adapterInstall = capacitor ? `installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });` : `installAbsoluteExpoWebDeviceAdapter(${JSON.stringify(deviceCapabilities.capabilities)});`;
|
|
7943
8378
|
let shellOptions = auth ? options : "{ createFetch: createAbsoluteExpoBridgeFetch }";
|
|
7944
8379
|
if (capacitor)
|
|
7945
8380
|
shellOptions = options;
|
|
@@ -7961,7 +8396,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
7961
8396
|
if (!build.success || build.outputs.length !== 1) {
|
|
7962
8397
|
throw new AggregateError(build.logs, "Failed to build the AbsoluteJS Capacitor shell.");
|
|
7963
8398
|
}
|
|
7964
|
-
await rename7(build.outputs[0]?.path ?? "",
|
|
8399
|
+
await rename7(build.outputs[0]?.path ?? "", join21(staging, BOOTSTRAP_FILE));
|
|
7965
8400
|
await rm6(entryPath, { force: true });
|
|
7966
8401
|
}, removePreviousBundle = async (backup, moved) => {
|
|
7967
8402
|
if (!moved)
|
|
@@ -7992,20 +8427,20 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
7992
8427
|
if (!CAPACITOR_CLIENT_FRAMEWORKS.has(page.framework)) {
|
|
7993
8428
|
throw new TypeError(`Capacitor client rendering does not yet support ${page.framework} page ${page.pageId}.`);
|
|
7994
8429
|
}
|
|
7995
|
-
const extension =
|
|
8430
|
+
const extension = extname5(page.bundlePath) || ".js";
|
|
7996
8431
|
const localBundlePath = `./pages/${page.bundleHash}${extension}`;
|
|
7997
8432
|
const source = sourceAssetPath(buildDirectory, page.bundlePath);
|
|
7998
|
-
await copyFile4(source,
|
|
8433
|
+
await copyFile4(source, join21(staging, localBundlePath));
|
|
7999
8434
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copiedDependencies);
|
|
8000
8435
|
let localStylePath;
|
|
8001
8436
|
if (page.styleBundlePath && page.styleBundleHash) {
|
|
8002
|
-
const styleExtension =
|
|
8437
|
+
const styleExtension = extname5(page.styleBundlePath) || ".css";
|
|
8003
8438
|
localStylePath = `./styles/${page.styleBundleHash}${styleExtension}`;
|
|
8004
8439
|
const styleSource = sourceAssetPath(buildDirectory, page.styleBundlePath);
|
|
8005
|
-
await mkdir9(dirname12(
|
|
8440
|
+
await mkdir9(dirname12(join21(staging, localStylePath)), {
|
|
8006
8441
|
recursive: true
|
|
8007
8442
|
});
|
|
8008
|
-
await copyFile4(styleSource,
|
|
8443
|
+
await copyFile4(styleSource, join21(staging, localStylePath));
|
|
8009
8444
|
await copyAbsoluteClientDependencies(styleSource, buildDirectory, staging, copiedDependencies);
|
|
8010
8445
|
}
|
|
8011
8446
|
return {
|
|
@@ -8015,7 +8450,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8015
8450
|
};
|
|
8016
8451
|
}, absoluteClientImports = async (sourcePath, buildDirectory) => {
|
|
8017
8452
|
const source = await readFile10(sourcePath, "utf8");
|
|
8018
|
-
const extension =
|
|
8453
|
+
const extension = extname5(sourcePath).toLowerCase();
|
|
8019
8454
|
let scriptLoader;
|
|
8020
8455
|
if (extension === ".tsx")
|
|
8021
8456
|
scriptLoader = "tsx";
|
|
@@ -8037,9 +8472,9 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8037
8472
|
const clean = specifier.split(/[?#]/u, 1)[0] ?? specifier;
|
|
8038
8473
|
if (clean.startsWith("/"))
|
|
8039
8474
|
return [clean];
|
|
8040
|
-
const resolved =
|
|
8041
|
-
const root =
|
|
8042
|
-
const relativePath =
|
|
8475
|
+
const resolved = resolve16(dirname12(sourcePath), clean);
|
|
8476
|
+
const root = resolve16(buildDirectory);
|
|
8477
|
+
const relativePath = relative12(root, resolved).replaceAll("\\", "/");
|
|
8043
8478
|
if (relativePath === ".." || relativePath.startsWith("../")) {
|
|
8044
8479
|
throw new TypeError(`Mobile client dependency escaped the build directory: ${specifier}`);
|
|
8045
8480
|
}
|
|
@@ -8050,7 +8485,7 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8050
8485
|
return;
|
|
8051
8486
|
copied.add(specifier);
|
|
8052
8487
|
const source = sourceAssetPath(buildDirectory, specifier);
|
|
8053
|
-
const destination =
|
|
8488
|
+
const destination = join21(staging, specifier.replace(/^\/+/, ""));
|
|
8054
8489
|
await mkdir9(dirname12(destination), { recursive: true });
|
|
8055
8490
|
await copyFile4(source, destination);
|
|
8056
8491
|
await copyAbsoluteClientDependencies(source, buildDirectory, staging, copied);
|
|
@@ -8063,14 +8498,14 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8063
8498
|
}
|
|
8064
8499
|
const destination = options.config.bundleDirectory;
|
|
8065
8500
|
await mkdir9(dirname12(destination), { recursive: true });
|
|
8066
|
-
const staging = await mkdtemp4(
|
|
8501
|
+
const staging = await mkdtemp4(join21(dirname12(destination), `.${basename8(destination)}.stage-`));
|
|
8067
8502
|
try {
|
|
8068
|
-
const pageDirectory =
|
|
8503
|
+
const pageDirectory = join21(staging, "pages");
|
|
8069
8504
|
await mkdir9(pageDirectory, { recursive: true });
|
|
8070
8505
|
await Promise.all(CLIENT_ASSET_DIRECTORIES.map((directory) => ({
|
|
8071
|
-
destination:
|
|
8072
|
-
source:
|
|
8073
|
-
})).filter(({ source }) =>
|
|
8506
|
+
destination: join21(staging, directory),
|
|
8507
|
+
source: join21(options.buildDirectory, directory)
|
|
8508
|
+
})).filter(({ source }) => existsSync10(source)).map(({ destination: assetDestination, source }) => cp3(source, assetDestination, { recursive: true })));
|
|
8074
8509
|
const copiedDependencies = new Set;
|
|
8075
8510
|
const pages = await Promise.all(options.artifact.pages.map((page) => copyClientPage(page, options.buildDirectory, staging, copiedDependencies)));
|
|
8076
8511
|
const manifest = {
|
|
@@ -8103,9 +8538,9 @@ void startAbsoluteMobileShell(${shellOptions});
|
|
|
8103
8538
|
} : {}
|
|
8104
8539
|
};
|
|
8105
8540
|
await Promise.all([
|
|
8106
|
-
writeFile8(
|
|
8541
|
+
writeFile8(join21(staging, MANIFEST_FILE), `${JSON.stringify(manifest, null, "\t")}
|
|
8107
8542
|
`),
|
|
8108
|
-
writeFile8(
|
|
8543
|
+
writeFile8(join21(staging, INDEX_FILE), indexHtml(options.config.appName, options.config.productionOrigin)),
|
|
8109
8544
|
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
8545
|
]);
|
|
8111
8546
|
await installBundle(staging, destination);
|
|
@@ -8161,7 +8596,7 @@ import {
|
|
|
8161
8596
|
rm as rm7,
|
|
8162
8597
|
writeFile as writeFile9
|
|
8163
8598
|
} from "fs/promises";
|
|
8164
|
-
import { dirname as dirname13, join as
|
|
8599
|
+
import { dirname as dirname13, join as join22, resolve as resolvePath3 } from "path";
|
|
8165
8600
|
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
8601
|
const identity = JSON.stringify({
|
|
8167
8602
|
currentReleaseId,
|
|
@@ -8191,16 +8626,16 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8191
8626
|
releases
|
|
8192
8627
|
};
|
|
8193
8628
|
}, writeRelease = async (root, release) => {
|
|
8194
|
-
const directory =
|
|
8195
|
-
const producerPath =
|
|
8629
|
+
const directory = join22(root, release.artifact.releaseId);
|
|
8630
|
+
const producerPath = join22(directory, release.artifact.producer.module);
|
|
8196
8631
|
await mkdir10(dirname13(producerPath), { recursive: true });
|
|
8197
8632
|
await Promise.all([
|
|
8198
|
-
writeFile9(
|
|
8633
|
+
writeFile9(join22(directory, ARTIFACT_FILE), `${JSON.stringify(release.artifact, null, "\t")}
|
|
8199
8634
|
`),
|
|
8200
8635
|
writeFile9(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
|
|
8201
8636
|
]);
|
|
8202
8637
|
}, installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
|
|
8203
|
-
const destination =
|
|
8638
|
+
const destination = join22(bundlesRoot, bundleId);
|
|
8204
8639
|
try {
|
|
8205
8640
|
await access8(destination);
|
|
8206
8641
|
return destination;
|
|
@@ -8208,7 +8643,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8208
8643
|
if (!errorHasCode2(error, "ENOENT"))
|
|
8209
8644
|
throw error;
|
|
8210
8645
|
}
|
|
8211
|
-
const staging = await mkdtemp5(
|
|
8646
|
+
const staging = await mkdtemp5(join22(bundlesRoot, ".stage-"));
|
|
8212
8647
|
try {
|
|
8213
8648
|
await Promise.all(releases.map((release) => writeRelease(staging, release)));
|
|
8214
8649
|
await rename8(staging, destination);
|
|
@@ -8237,7 +8672,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8237
8672
|
return release;
|
|
8238
8673
|
});
|
|
8239
8674
|
const root = resolvePath3(input.root);
|
|
8240
|
-
const bundlesRoot =
|
|
8675
|
+
const bundlesRoot = join22(root, BUNDLES_DIRECTORY);
|
|
8241
8676
|
await mkdir10(bundlesRoot, { recursive: true });
|
|
8242
8677
|
const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
|
|
8243
8678
|
await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
|
|
@@ -8247,8 +8682,8 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8247
8682
|
format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
|
|
8248
8683
|
releases: artifacts
|
|
8249
8684
|
};
|
|
8250
|
-
const pointerPath =
|
|
8251
|
-
const temporaryPointerPath =
|
|
8685
|
+
const pointerPath = join22(root, CURRENT_BUNDLE_FILE);
|
|
8686
|
+
const temporaryPointerPath = join22(root, `.current-${crypto.randomUUID()}.json`);
|
|
8252
8687
|
await writeFile9(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
|
|
8253
8688
|
`, { flag: "wx" });
|
|
8254
8689
|
await rename8(temporaryPointerPath, pointerPath);
|
|
@@ -8256,12 +8691,12 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
|
|
|
8256
8691
|
}, readAbsoluteMobileMaterializedReleases = async (root) => {
|
|
8257
8692
|
const resolvedRoot = resolvePath3(root);
|
|
8258
8693
|
try {
|
|
8259
|
-
const serialized = await readFile11(
|
|
8694
|
+
const serialized = await readFile11(join22(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
|
|
8260
8695
|
const parsed = JSON.parse(serialized);
|
|
8261
8696
|
const index = parseBundleIndex(parsed);
|
|
8262
|
-
const bundleRoot =
|
|
8697
|
+
const bundleRoot = join22(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
|
|
8263
8698
|
return Promise.all(index.releases.map(async (artifact) => {
|
|
8264
|
-
const producer = Bun.file(
|
|
8699
|
+
const producer = Bun.file(join22(bundleRoot, artifact.releaseId, artifact.producer.module));
|
|
8265
8700
|
await verifyAbsoluteMobileCompatibilityProducer({
|
|
8266
8701
|
artifact,
|
|
8267
8702
|
producer
|
|
@@ -8280,261 +8715,6 @@ var init_materializedBundle = __esm(() => {
|
|
|
8280
8715
|
BUNDLE_ID_PATTERN = /^amb_[a-f0-9]{64}$/;
|
|
8281
8716
|
});
|
|
8282
8717
|
|
|
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
8718
|
// src/mobile/buildPipeline.ts
|
|
8539
8719
|
import { readFile as readFile12 } from "fs/promises";
|
|
8540
8720
|
import { join as join23, resolve as resolve17 } from "path";
|
|
@@ -8606,11 +8786,8 @@ var isElysiaApp = (value) => typeof value === "object" && value !== null && type
|
|
|
8606
8786
|
const auth = resolveAbsoluteMobileAuthManifest(options.projectRoot, mobile);
|
|
8607
8787
|
const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
|
|
8608
8788
|
const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
|
|
8609
|
-
const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
|
|
8789
|
+
const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot, mobile.engine);
|
|
8610
8790
|
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
8791
|
if (usesPush && !auth)
|
|
8615
8792
|
throw new TypeError("Portable push notifications require @absolutejs/auth so provider tokens can be registered without exposing identity controls to page code.");
|
|
8616
8793
|
if (usesPush && !loaded.app.routes.some((route) => route.path === "/auth/push" || route.path === "/auth/mobile/push"))
|
|
@@ -8663,10 +8840,10 @@ var init_buildPipeline = __esm(() => {
|
|
|
8663
8840
|
});
|
|
8664
8841
|
|
|
8665
8842
|
// src/mobile/routeMetadataTransform.ts
|
|
8666
|
-
import { existsSync as
|
|
8843
|
+
import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
|
|
8667
8844
|
import { dirname as dirname14, extname as extname6, relative as relative13, resolve as resolve18 } from "path";
|
|
8668
8845
|
import ts5 from "typescript";
|
|
8669
|
-
var ROUTE_METHODS, SOURCE_FILTER, PAGE_HANDLERS, posixPath = (value) => value.replace(/\\/g, "/"), findTsconfig = (entry, projectRoot) => ts5.findConfigFile(dirname14(entry),
|
|
8846
|
+
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
8847
|
const configPath2 = findTsconfig(entry, projectRoot);
|
|
8671
8848
|
if (!configPath2) {
|
|
8672
8849
|
return ts5.createProgram([entry], {
|
|
@@ -9934,7 +10111,7 @@ var init_rewriteImports = __esm(() => {
|
|
|
9934
10111
|
|
|
9935
10112
|
// src/cli/scripts/start.ts
|
|
9936
10113
|
var {env: env2 } = globalThis.Bun;
|
|
9937
|
-
import { existsSync as
|
|
10114
|
+
import { existsSync as existsSync12, readFileSync as readFileSync15, rmSync as rmSync4 } from "fs";
|
|
9938
10115
|
import { basename as basename9, join as join26, resolve as resolve21 } from "path";
|
|
9939
10116
|
var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[cli]\x1B[0m ${color}${message}\x1B[0m`, resolvePackageVersion = (candidates) => {
|
|
9940
10117
|
for (const candidate of candidates) {
|
|
@@ -9992,7 +10169,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
9992
10169
|
resolve21(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
|
|
9993
10170
|
];
|
|
9994
10171
|
for (const candidate of candidates) {
|
|
9995
|
-
if (
|
|
10172
|
+
if (existsSync12(candidate))
|
|
9996
10173
|
return candidate;
|
|
9997
10174
|
}
|
|
9998
10175
|
return resolve21(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
|
|
@@ -10029,7 +10206,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10029
10206
|
serverEntry,
|
|
10030
10207
|
totalDuration
|
|
10031
10208
|
}) => {
|
|
10032
|
-
const usesDocker =
|
|
10209
|
+
const usesDocker = existsSync12(resolve21(COMPOSE_PATH));
|
|
10033
10210
|
const scripts = usesDocker ? await readDbScripts() : null;
|
|
10034
10211
|
if (scripts)
|
|
10035
10212
|
await startDatabase(scripts);
|
|
@@ -10140,7 +10317,7 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10140
10317
|
].filter((val) => Boolean(val));
|
|
10141
10318
|
const outputPath = resolve21(resolvedOutdir, `${entryName}.js`);
|
|
10142
10319
|
if (options.prebuilt) {
|
|
10143
|
-
if (!
|
|
10320
|
+
if (!existsSync12(outputPath)) {
|
|
10144
10321
|
throw new Error(`Prepared production server not found: ${outputPath}`);
|
|
10145
10322
|
}
|
|
10146
10323
|
return runPreparedServer({
|
|
@@ -10267,11 +10444,11 @@ var cliTag2 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
10267
10444
|
if (!serverBundle.success) {
|
|
10268
10445
|
handleBundleFailure(serverBundle, bundleStart, serverEntry);
|
|
10269
10446
|
}
|
|
10270
|
-
if (!
|
|
10447
|
+
if (!existsSync12(outputPath)) {
|
|
10271
10448
|
console.error(cliTag2("\x1B[31m", `Expected output not found: ${outputPath}`));
|
|
10272
10449
|
process.exit(1);
|
|
10273
10450
|
}
|
|
10274
|
-
if (
|
|
10451
|
+
if (existsSync12(resolve21(resolvedOutdir, "angular", "vendor", "server"))) {
|
|
10275
10452
|
const { readdirSync: readdirSync2 } = await import("fs");
|
|
10276
10453
|
const vendorDir = resolve21(resolvedOutdir, "angular", "vendor", "server");
|
|
10277
10454
|
const vendorEntries = readdirSync2(vendorDir).filter((fileName) => fileName.endsWith(".js"));
|
|
@@ -10470,11 +10647,11 @@ var exports_build = {};
|
|
|
10470
10647
|
__export(exports_build, {
|
|
10471
10648
|
build: () => build
|
|
10472
10649
|
});
|
|
10473
|
-
import { existsSync as
|
|
10650
|
+
import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync as readFileSync17 } from "fs";
|
|
10474
10651
|
import { join as join27, resolve as resolve23 } from "path";
|
|
10475
10652
|
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
10653
|
const traceDir = join27(buildDir, ".absolute-trace");
|
|
10477
|
-
if (!
|
|
10654
|
+
if (!existsSync14(traceDir))
|
|
10478
10655
|
return;
|
|
10479
10656
|
const files = readdirSync3(traceDir).filter((file) => file.endsWith(".json")).sort();
|
|
10480
10657
|
const latest = files[files.length - 1];
|
|
@@ -10573,7 +10750,7 @@ import {
|
|
|
10573
10750
|
verify
|
|
10574
10751
|
} from "crypto";
|
|
10575
10752
|
import {
|
|
10576
|
-
existsSync as
|
|
10753
|
+
existsSync as existsSync15,
|
|
10577
10754
|
lstatSync,
|
|
10578
10755
|
mkdirSync as mkdirSync8,
|
|
10579
10756
|
mkdtempSync,
|
|
@@ -10773,7 +10950,7 @@ var DEFAULT_PROOF_LOCATION = ".absolutejs/lint-proof.json", PROOF_CONTRACT_VERSI
|
|
|
10773
10950
|
const cwd = options.cwd ?? process.cwd();
|
|
10774
10951
|
const proofLocation = options.proofLocation ?? DEFAULT_PROOF_LOCATION;
|
|
10775
10952
|
const path = resolve24(cwd, proofLocation);
|
|
10776
|
-
if (!
|
|
10953
|
+
if (!existsSync15(path))
|
|
10777
10954
|
return { reason: `missing lint proof: ${proofLocation}`, valid: false };
|
|
10778
10955
|
let proof;
|
|
10779
10956
|
try {
|
|
@@ -10890,7 +11067,7 @@ var init_lintProof = __esm(() => {
|
|
|
10890
11067
|
// src/build/scanConventions.ts
|
|
10891
11068
|
import { basename as basename10 } from "path";
|
|
10892
11069
|
var {Glob: Glob2 } = globalThis.Bun;
|
|
10893
|
-
import { existsSync as
|
|
11070
|
+
import { existsSync as existsSync16 } from "fs";
|
|
10894
11071
|
var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
|
|
10895
11072
|
const fileName = basename10(file);
|
|
10896
11073
|
const match = CONVENTION_RE.exec(fileName);
|
|
@@ -10915,7 +11092,7 @@ var CONVENTION_RE, classifyFile = (file, pageFiles, defaults, pages) => {
|
|
|
10915
11092
|
else if (kind === "loading")
|
|
10916
11093
|
pages[pageName].loading = file;
|
|
10917
11094
|
}, scanConventions = async (pagesDir, pattern) => {
|
|
10918
|
-
if (!
|
|
11095
|
+
if (!existsSync16(pagesDir)) {
|
|
10919
11096
|
const pageFiles2 = [];
|
|
10920
11097
|
return { conventions: undefined, pageFiles: pageFiles2 };
|
|
10921
11098
|
}
|
|
@@ -10942,7 +11119,7 @@ var exports_ls = {};
|
|
|
10942
11119
|
__export(exports_ls, {
|
|
10943
11120
|
runLs: () => runLs
|
|
10944
11121
|
});
|
|
10945
|
-
import { existsSync as
|
|
11122
|
+
import { existsSync as existsSync17, readFileSync as readFileSync19, statSync } from "fs";
|
|
10946
11123
|
import { basename as basename11, extname as extname7, join as join28, relative as relative15 } from "path";
|
|
10947
11124
|
var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELDS, readStringField = (source, key) => {
|
|
10948
11125
|
const value = Reflect.get(source, key);
|
|
@@ -10993,10 +11170,10 @@ var DEFAULT_BUILD_DIR = "build", LABEL_ORDER, ARTIFACT_SUFFIXES, FRAMEWORK_FIELD
|
|
|
10993
11170
|
return pages ? [{ label, pages: sortPages(pages) }] : [];
|
|
10994
11171
|
});
|
|
10995
11172
|
}, resolveDiskPath = (buildDir, value) => {
|
|
10996
|
-
if (
|
|
11173
|
+
if (existsSync17(value))
|
|
10997
11174
|
return value;
|
|
10998
11175
|
const underBuild = join28(buildDir, value);
|
|
10999
|
-
if (
|
|
11176
|
+
if (existsSync17(underBuild))
|
|
11000
11177
|
return underBuild;
|
|
11001
11178
|
return join28(process.cwd(), value);
|
|
11002
11179
|
}, fileSize = (diskPath) => {
|
|
@@ -11124,7 +11301,7 @@ ${colors.dim}${frameworkCount} ${frameworkCount === 1 ? "framework" : "framework
|
|
|
11124
11301
|
}
|
|
11125
11302
|
const sizesDir = resolveSizesDir(args, candidates);
|
|
11126
11303
|
const manifestPath = join28(sizesDir, "manifest.json");
|
|
11127
|
-
if (!
|
|
11304
|
+
if (!existsSync17(manifestPath)) {
|
|
11128
11305
|
printDim(`No build at ${relativeOrSelf(manifestPath)}. Run \`absolute build\` first, or pass \`--outdir <dir>\`.`);
|
|
11129
11306
|
return;
|
|
11130
11307
|
}
|
|
@@ -11974,7 +12151,7 @@ var exports_heapDiff = {};
|
|
|
11974
12151
|
__export(exports_heapDiff, {
|
|
11975
12152
|
runHeapDiff: () => runHeapDiff
|
|
11976
12153
|
});
|
|
11977
|
-
import { existsSync as
|
|
12154
|
+
import { existsSync as existsSync18, readFileSync as readFileSync20 } from "fs";
|
|
11978
12155
|
var TOP = 15, STRING_TYPES, aggregate = (path) => {
|
|
11979
12156
|
const data = JSON.parse(readFileSync20(path, "utf-8"));
|
|
11980
12157
|
const { nodes, strings } = data;
|
|
@@ -12005,7 +12182,7 @@ var TOP = 15, STRING_TYPES, aggregate = (path) => {
|
|
|
12005
12182
|
return;
|
|
12006
12183
|
}
|
|
12007
12184
|
for (const path of [beforePath, afterPath]) {
|
|
12008
|
-
if (
|
|
12185
|
+
if (existsSync18(path))
|
|
12009
12186
|
continue;
|
|
12010
12187
|
process.stdout.write(`${colors.red}No such file: ${path}${colors.reset}
|
|
12011
12188
|
`);
|
|
@@ -12126,7 +12303,7 @@ var isRecord9 = (value) => typeof value === "object" && value !== null && !Array
|
|
|
12126
12303
|
// src/cli/config/schema/fromType.ts
|
|
12127
12304
|
import ts6 from "typescript";
|
|
12128
12305
|
import {
|
|
12129
|
-
existsSync as
|
|
12306
|
+
existsSync as existsSync19,
|
|
12130
12307
|
mkdirSync as mkdirSync9,
|
|
12131
12308
|
readFileSync as readFileSync21,
|
|
12132
12309
|
statSync as statSync2,
|
|
@@ -12321,7 +12498,7 @@ export { value };
|
|
|
12321
12498
|
const cached = cache.get(cacheKey);
|
|
12322
12499
|
if (cached)
|
|
12323
12500
|
return cached;
|
|
12324
|
-
const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) &&
|
|
12501
|
+
const local = specifier === "@absolutejs/absolute" && isFrameworkRepo(cwd) && existsSync19(resolve25(cwd, "types/index.ts"));
|
|
12325
12502
|
const signature = cacheSignature(cwd, typeName, local, specifier);
|
|
12326
12503
|
const fromDisk = readDiskCache(cwd, typeName, signature, specifier);
|
|
12327
12504
|
if (fromDisk) {
|
|
@@ -12349,16 +12526,16 @@ var init_fromType = __esm(() => {
|
|
|
12349
12526
|
|
|
12350
12527
|
// src/cli/config/absolute/resolveAbsoluteConfig.ts
|
|
12351
12528
|
import ts7 from "typescript";
|
|
12352
|
-
import { existsSync as
|
|
12529
|
+
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "fs";
|
|
12353
12530
|
import { resolve as resolve26 } from "path";
|
|
12354
12531
|
var CONFIG_CANDIDATES2, RUNTIME_FIELDS, findConfigPath = (cwd, override) => {
|
|
12355
12532
|
if (override) {
|
|
12356
12533
|
const resolved = resolve26(cwd, override);
|
|
12357
|
-
return
|
|
12534
|
+
return existsSync20(resolved) ? resolved : null;
|
|
12358
12535
|
}
|
|
12359
12536
|
for (const name of CONFIG_CANDIDATES2) {
|
|
12360
12537
|
const candidate = resolve26(cwd, name);
|
|
12361
|
-
if (
|
|
12538
|
+
if (existsSync20(candidate))
|
|
12362
12539
|
return candidate;
|
|
12363
12540
|
}
|
|
12364
12541
|
return null;
|
|
@@ -12682,7 +12859,7 @@ var emptyOutcome = () => ({
|
|
|
12682
12859
|
|
|
12683
12860
|
// src/cli/generate/routeWiring.ts
|
|
12684
12861
|
import ts8 from "typescript";
|
|
12685
|
-
import { existsSync as
|
|
12862
|
+
import { existsSync as existsSync21, readFileSync as readFileSync23, readdirSync as readdirSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
12686
12863
|
import { dirname as dirname18, join as join30 } from "path";
|
|
12687
12864
|
var DEFAULT_SEPARATOR = `
|
|
12688
12865
|
`, BOUNDARY_USE, applyEdits = (text2, edits) => {
|
|
@@ -12831,13 +13008,13 @@ ${newLines.join(`
|
|
|
12831
13008
|
return lines.join(`
|
|
12832
13009
|
`);
|
|
12833
13010
|
}, hasChain = (path) => {
|
|
12834
|
-
if (!
|
|
13011
|
+
if (!existsSync21(path))
|
|
12835
13012
|
return false;
|
|
12836
13013
|
const sourceFile = parse2(path, readFileSync23(path, "utf-8"));
|
|
12837
13014
|
const found = findElysiaNew(sourceFile);
|
|
12838
13015
|
return found !== null;
|
|
12839
13016
|
}, firstChainFile = (pluginsDir) => {
|
|
12840
|
-
if (!
|
|
13017
|
+
if (!existsSync21(pluginsDir))
|
|
12841
13018
|
return null;
|
|
12842
13019
|
for (const name of readdirSync4(pluginsDir)) {
|
|
12843
13020
|
if (!name.endsWith(".ts"))
|
|
@@ -12940,7 +13117,7 @@ var init_routeWiring = __esm(() => {
|
|
|
12940
13117
|
});
|
|
12941
13118
|
|
|
12942
13119
|
// src/cli/generate/generateApi.ts
|
|
12943
|
-
import { existsSync as
|
|
13120
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
|
|
12944
13121
|
import { dirname as dirname19, join as join31 } from "path";
|
|
12945
13122
|
var apiPluginTemplate = (pluginName, base) => `import { Elysia } from 'elysia';
|
|
12946
13123
|
|
|
@@ -12955,7 +13132,7 @@ export const ${pluginName} = new Elysia()
|
|
|
12955
13132
|
const outcome = { ...emptyOutcome(), route: base };
|
|
12956
13133
|
const pluginsDir = join31(dirname19(project.serverEntry), "plugins");
|
|
12957
13134
|
const fileAbs = join31(pluginsDir, `${pluginName}.ts`);
|
|
12958
|
-
if (
|
|
13135
|
+
if (existsSync22(fileAbs)) {
|
|
12959
13136
|
outcome.notes.push(`${pluginName} already exists at ${fileAbs} \u2014 skipped.`);
|
|
12960
13137
|
return outcome;
|
|
12961
13138
|
}
|
|
@@ -13028,7 +13205,7 @@ var init_componentTemplates = __esm(() => {
|
|
|
13028
13205
|
});
|
|
13029
13206
|
|
|
13030
13207
|
// src/cli/generate/generateComponent.ts
|
|
13031
|
-
import { existsSync as
|
|
13208
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
|
|
13032
13209
|
import { dirname as dirname20, join as join32 } from "path";
|
|
13033
13210
|
var generateComponent = (project, framework, rawName) => {
|
|
13034
13211
|
const def = frameworks6[framework];
|
|
@@ -13041,7 +13218,7 @@ var generateComponent = (project, framework, rawName) => {
|
|
|
13041
13218
|
return outcome;
|
|
13042
13219
|
}
|
|
13043
13220
|
const fileAbs = join32(frameworkDir, "components", def.componentFile({ kebab, pascal }));
|
|
13044
|
-
if (
|
|
13221
|
+
if (existsSync23(fileAbs)) {
|
|
13045
13222
|
outcome.notes.push(`${pascal} already exists at ${fileAbs} \u2014 skipped.`);
|
|
13046
13223
|
return outcome;
|
|
13047
13224
|
}
|
|
@@ -13061,7 +13238,7 @@ var init_generateComponent = __esm(() => {
|
|
|
13061
13238
|
|
|
13062
13239
|
// src/cli/generate/cssStrategy.ts
|
|
13063
13240
|
import ts9 from "typescript";
|
|
13064
|
-
import { existsSync as
|
|
13241
|
+
import { existsSync as existsSync24 } from "fs";
|
|
13065
13242
|
import { join as join33 } from "path";
|
|
13066
13243
|
var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
13067
13244
|
margin: 0 auto;
|
|
@@ -13109,7 +13286,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
|
13109
13286
|
return {
|
|
13110
13287
|
assetKey: sharedKey,
|
|
13111
13288
|
contents: DEFAULT_CSS,
|
|
13112
|
-
create: !
|
|
13289
|
+
create: !existsSync24(cssFileAbs2),
|
|
13113
13290
|
cssFileAbs: cssFileAbs2,
|
|
13114
13291
|
shared: true
|
|
13115
13292
|
};
|
|
@@ -13118,7 +13295,7 @@ var CSS_SUFFIX = "CSS", SHARED_MIN_USES = 2, DEFAULT_CSS = `main {
|
|
|
13118
13295
|
return {
|
|
13119
13296
|
assetKey: `${pascal}${CSS_SUFFIX}`,
|
|
13120
13297
|
contents: DEFAULT_CSS,
|
|
13121
|
-
create: !
|
|
13298
|
+
create: !existsSync24(cssFileAbs),
|
|
13122
13299
|
cssFileAbs,
|
|
13123
13300
|
shared: false
|
|
13124
13301
|
};
|
|
@@ -13127,7 +13304,7 @@ var init_cssStrategy = () => {};
|
|
|
13127
13304
|
|
|
13128
13305
|
// src/cli/generate/navData.ts
|
|
13129
13306
|
import ts10 from "typescript";
|
|
13130
|
-
import { existsSync as
|
|
13307
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "fs";
|
|
13131
13308
|
import { dirname as dirname21 } from "path";
|
|
13132
13309
|
var NAV_DATA_TEMPLATE = `type NavItem = {
|
|
13133
13310
|
href: string;
|
|
@@ -13166,7 +13343,7 @@ export const navData: NavItem[] = [];
|
|
|
13166
13343
|
}
|
|
13167
13344
|
return items;
|
|
13168
13345
|
}, readNavItems = (navDataPath) => {
|
|
13169
|
-
if (!
|
|
13346
|
+
if (!existsSync25(navDataPath))
|
|
13170
13347
|
return [];
|
|
13171
13348
|
const text2 = readFileSync24(navDataPath, "utf-8");
|
|
13172
13349
|
const sourceFile = ts10.createSourceFile(navDataPath, text2, ts10.ScriptTarget.Latest, true);
|
|
@@ -13203,7 +13380,7 @@ ${indentOf(text2, array.getStart(sourceFile))}`;
|
|
|
13203
13380
|
${indent}${entry}`;
|
|
13204
13381
|
return text2.slice(0, insertAt) + insertion + text2.slice(insertAt);
|
|
13205
13382
|
}, upsertNavItem = (navDataPath, item) => {
|
|
13206
|
-
const created = !
|
|
13383
|
+
const created = !existsSync25(navDataPath);
|
|
13207
13384
|
if (created) {
|
|
13208
13385
|
mkdirSync12(dirname21(navDataPath), { recursive: true });
|
|
13209
13386
|
writeFileSync12(navDataPath, NAV_DATA_TEMPLATE, "utf-8");
|
|
@@ -13369,7 +13546,7 @@ var init_pageTemplates = __esm(() => {
|
|
|
13369
13546
|
|
|
13370
13547
|
// src/cli/generate/generatePage.ts
|
|
13371
13548
|
import {
|
|
13372
|
-
existsSync as
|
|
13549
|
+
existsSync as existsSync26,
|
|
13373
13550
|
mkdirSync as mkdirSync13,
|
|
13374
13551
|
readFileSync as readFileSync25,
|
|
13375
13552
|
readdirSync as readdirSync5,
|
|
@@ -13382,7 +13559,7 @@ var writeNew = (path, contents) => {
|
|
|
13382
13559
|
}, toHref = (fromDir, toFile) => {
|
|
13383
13560
|
const rel = relative17(fromDir, toFile).split("\\").join("/");
|
|
13384
13561
|
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 &&
|
|
13562
|
+
}, 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
13563
|
const html = readFileSync25(file, "utf-8");
|
|
13387
13564
|
const synced = syncStaticNav(html, items);
|
|
13388
13565
|
if (synced === null || synced === html)
|
|
@@ -13411,7 +13588,7 @@ var writeNew = (path, contents) => {
|
|
|
13411
13588
|
return outcome;
|
|
13412
13589
|
}
|
|
13413
13590
|
const pageFileAbs = join34(frameworkDir, "pages", def.pageFile({ kebab, pascal }));
|
|
13414
|
-
if (
|
|
13591
|
+
if (existsSync26(pageFileAbs)) {
|
|
13415
13592
|
outcome.notes.push(`${pascal} already exists at ${pageFileAbs} \u2014 skipped.`);
|
|
13416
13593
|
return outcome;
|
|
13417
13594
|
}
|
|
@@ -13797,11 +13974,11 @@ var init_catalog = __esm(() => {
|
|
|
13797
13974
|
});
|
|
13798
13975
|
|
|
13799
13976
|
// src/cli/integrations/addPlugin.ts
|
|
13800
|
-
import { existsSync as
|
|
13977
|
+
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "fs";
|
|
13801
13978
|
import { join as join35 } from "path";
|
|
13802
13979
|
var isRecord11 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readPackageJson = (cwd) => {
|
|
13803
13980
|
const path = join35(cwd, "package.json");
|
|
13804
|
-
if (!
|
|
13981
|
+
if (!existsSync27(path))
|
|
13805
13982
|
return null;
|
|
13806
13983
|
try {
|
|
13807
13984
|
const parsed = JSON.parse(readFileSync27(path, "utf-8"));
|
|
@@ -14296,16 +14473,16 @@ var init_authCatalog = __esm(() => {
|
|
|
14296
14473
|
|
|
14297
14474
|
// src/cli/config/auth/resolveAuthSettings.ts
|
|
14298
14475
|
import ts12 from "typescript";
|
|
14299
|
-
import { existsSync as
|
|
14476
|
+
import { existsSync as existsSync28, readFileSync as readFileSync28 } from "fs";
|
|
14300
14477
|
import { resolve as resolve28 } from "path";
|
|
14301
14478
|
var AUTH_PACKAGE = "@absolutejs/auth", CONFIG_CANDIDATES3, findAuthSettingsPath = (cwd, override) => {
|
|
14302
14479
|
if (override) {
|
|
14303
14480
|
const resolved = resolve28(cwd, override);
|
|
14304
|
-
return
|
|
14481
|
+
return existsSync28(resolved) ? resolved : null;
|
|
14305
14482
|
}
|
|
14306
14483
|
for (const name of CONFIG_CANDIDATES3) {
|
|
14307
14484
|
const candidate = resolve28(cwd, name);
|
|
14308
|
-
if (
|
|
14485
|
+
if (existsSync28(candidate))
|
|
14309
14486
|
return candidate;
|
|
14310
14487
|
}
|
|
14311
14488
|
return null;
|
|
@@ -14401,10 +14578,10 @@ var init_resolveAuthSettings = __esm(() => {
|
|
|
14401
14578
|
|
|
14402
14579
|
// src/cli/config/auth/resolveAuthState.ts
|
|
14403
14580
|
import ts13 from "typescript";
|
|
14404
|
-
import { existsSync as
|
|
14581
|
+
import { existsSync as existsSync29, readdirSync as readdirSync6, readFileSync as readFileSync29 } from "fs";
|
|
14405
14582
|
import { join as join36, relative as relative19, resolve as resolve29 } from "path";
|
|
14406
14583
|
var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutejs/absolute-auth", NPM_URL = "https://www.npmjs.com/package/@absolutejs/auth", SKIP_DIRS, MAX_FILES = 4000, SETUP_EXPORTS, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson2 = (path) => {
|
|
14407
|
-
if (!
|
|
14584
|
+
if (!existsSync29(path))
|
|
14408
14585
|
return null;
|
|
14409
14586
|
try {
|
|
14410
14587
|
const parsed = JSON.parse(readFileSync29(path, "utf-8"));
|
|
@@ -14533,7 +14710,7 @@ var AUTH_PACKAGE2 = "@absolutejs/auth", REPO_URL = "https://github.com/absolutej
|
|
|
14533
14710
|
scaffoldable: isScaffoldableFeature(feature.id)
|
|
14534
14711
|
})), resolveAuthState = (cwd) => {
|
|
14535
14712
|
const installedVersion = installedVersionFor(cwd);
|
|
14536
|
-
const root =
|
|
14713
|
+
const root = existsSync29(join36(cwd, "src")) ? join36(cwd, "src") : cwd;
|
|
14537
14714
|
let match = null;
|
|
14538
14715
|
let setupPath = null;
|
|
14539
14716
|
for (const file of candidateFiles(root)) {
|
|
@@ -14578,7 +14755,7 @@ var init_resolveAuthState = __esm(() => {
|
|
|
14578
14755
|
});
|
|
14579
14756
|
|
|
14580
14757
|
// src/cli/config/auth/scaffoldAuthFeature.ts
|
|
14581
|
-
import { existsSync as
|
|
14758
|
+
import { existsSync as existsSync30, writeFileSync as writeFileSync15 } from "fs";
|
|
14582
14759
|
import { dirname as dirname23, join as join37, relative as relative20, resolve as resolve30 } from "path";
|
|
14583
14760
|
var renderScaffold = (scaffold) => {
|
|
14584
14761
|
const importNames = [...scaffold.imports, `type ${scaffold.typeName}`];
|
|
@@ -14606,7 +14783,7 @@ ${body}
|
|
|
14606
14783
|
if (setupPath)
|
|
14607
14784
|
return dirname23(resolve30(cwd, setupPath));
|
|
14608
14785
|
const src = join37(cwd, "src");
|
|
14609
|
-
return
|
|
14786
|
+
return existsSync30(src) ? src : cwd;
|
|
14610
14787
|
}, spreadFor = (scaffold) => `import { ${scaffold.exportName} } from './${scaffold.exportName}';
|
|
14611
14788
|
// add to your auth() call:
|
|
14612
14789
|
${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
|
|
@@ -14621,7 +14798,7 @@ ${scaffold.configKey}: ${scaffold.exportName}`, failure2 = (message) => ({
|
|
|
14621
14798
|
return failure2(`Unknown auth feature "${id}".`);
|
|
14622
14799
|
const filePath = join37(targetDir(cwd), `${scaffold.exportName}.ts`);
|
|
14623
14800
|
const relPath = relative20(cwd, filePath);
|
|
14624
|
-
if (
|
|
14801
|
+
if (existsSync30(filePath)) {
|
|
14625
14802
|
return {
|
|
14626
14803
|
created: null,
|
|
14627
14804
|
installed: false,
|
|
@@ -14648,13 +14825,13 @@ var init_scaffoldAuthFeature = __esm(() => {
|
|
|
14648
14825
|
});
|
|
14649
14826
|
|
|
14650
14827
|
// src/cli/htmx/install.ts
|
|
14651
|
-
import { existsSync as
|
|
14828
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync14, readFileSync as readFileSync30, writeFileSync as writeFileSync16 } from "fs";
|
|
14652
14829
|
import { join as join38 } from "path";
|
|
14653
14830
|
var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
|
|
14654
14831
|
join38(import.meta.dir, "htmx.min.js"),
|
|
14655
14832
|
join38(import.meta.dir, "htmx", "htmx.min.js"),
|
|
14656
14833
|
join38(import.meta.dir, "..", "htmx", "htmx.min.js")
|
|
14657
|
-
].find((path) =>
|
|
14834
|
+
].find((path) => existsSync31(path)) ?? null, detectHtmxVersion = (content) => {
|
|
14658
14835
|
const match = content.match(/version:"([0-9.]+)"/);
|
|
14659
14836
|
return match ? match[1] : null;
|
|
14660
14837
|
}, fetchHtmx = async (version2) => {
|
|
@@ -14666,7 +14843,7 @@ var VENDORED_HTMX_VERSION = "2.0.6", vendoredHtmxFile = () => [
|
|
|
14666
14843
|
return response.text();
|
|
14667
14844
|
}, installedHtmxVersion = (htmxDir) => {
|
|
14668
14845
|
const file = join38(htmxDir, "htmx.min.js");
|
|
14669
|
-
if (!
|
|
14846
|
+
if (!existsSync31(file))
|
|
14670
14847
|
return null;
|
|
14671
14848
|
return detectHtmxVersion(readFileSync30(file, "utf-8"));
|
|
14672
14849
|
}, readVendoredHtmx = () => {
|
|
@@ -14834,7 +15011,7 @@ var exports_analyze = {};
|
|
|
14834
15011
|
__export(exports_analyze, {
|
|
14835
15012
|
runAnalyze: () => runAnalyze
|
|
14836
15013
|
});
|
|
14837
|
-
import { existsSync as
|
|
15014
|
+
import { existsSync as existsSync32, readFileSync as readFileSync31, statSync as statSync3, writeFileSync as writeFileSync17 } from "fs";
|
|
14838
15015
|
import { join as join40, resolve as resolve31 } from "path";
|
|
14839
15016
|
var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_WIDTH = 16, SIZE_WIDTH = 12, CHANGE_WIDTH = 10, CATEGORY_ORDER, categoryOf = (key) => {
|
|
14840
15017
|
if (key.startsWith("Island"))
|
|
@@ -14856,7 +15033,7 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
|
|
|
14856
15033
|
}
|
|
14857
15034
|
}, readSizes = (manifestDir) => {
|
|
14858
15035
|
const manifestPath = join40(manifestDir, "manifest.json");
|
|
14859
|
-
if (!
|
|
15036
|
+
if (!existsSync32(manifestPath))
|
|
14860
15037
|
return null;
|
|
14861
15038
|
const manifest = JSON.parse(readFileSync31(manifestPath, "utf-8"));
|
|
14862
15039
|
const sizes = {};
|
|
@@ -14866,7 +15043,7 @@ var BASELINE_FILE = ".absolute-size-baseline.json", TOP_CHANGES = 12, CATEGORY_W
|
|
|
14866
15043
|
return sizes;
|
|
14867
15044
|
}, readBaseline = (cwd) => {
|
|
14868
15045
|
const path = join40(cwd, BASELINE_FILE);
|
|
14869
|
-
if (!
|
|
15046
|
+
if (!existsSync32(path))
|
|
14870
15047
|
return null;
|
|
14871
15048
|
try {
|
|
14872
15049
|
const parsed = JSON.parse(readFileSync31(path, "utf-8"));
|
|
@@ -15200,7 +15377,7 @@ var exports_remove = {};
|
|
|
15200
15377
|
__export(exports_remove, {
|
|
15201
15378
|
runRemove: () => runRemove
|
|
15202
15379
|
});
|
|
15203
|
-
import { existsSync as
|
|
15380
|
+
import { existsSync as existsSync33, readFileSync as readFileSync32 } from "fs";
|
|
15204
15381
|
import { relative as relative22 } from "path";
|
|
15205
15382
|
var write3 = (text2) => process.stdout.write(`${text2}
|
|
15206
15383
|
`), fail3 = (message) => {
|
|
@@ -15211,7 +15388,7 @@ var write3 = (text2) => process.stdout.write(`${text2}
|
|
|
15211
15388
|
const candidates = [findRoutingFile(serverEntry), serverEntry];
|
|
15212
15389
|
const seen = new Set;
|
|
15213
15390
|
return candidates.filter((file) => {
|
|
15214
|
-
if (file === null || seen.has(file) || !
|
|
15391
|
+
if (file === null || seen.has(file) || !existsSync33(file))
|
|
15215
15392
|
return false;
|
|
15216
15393
|
seen.add(file);
|
|
15217
15394
|
return readFileSync32(file, "utf-8").includes(handler);
|
|
@@ -15341,10 +15518,10 @@ __export(exports_env, {
|
|
|
15341
15518
|
runEnv: () => runEnv,
|
|
15342
15519
|
scanEnvUsage: () => scanEnvUsage
|
|
15343
15520
|
});
|
|
15344
|
-
import { existsSync as
|
|
15521
|
+
import { existsSync as existsSync34, readFileSync as readFileSync33 } from "fs";
|
|
15345
15522
|
import { join as join41 } from "path";
|
|
15346
15523
|
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 = () =>
|
|
15524
|
+
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
15525
|
const scans = scanPatterns().map((pattern) => Array.fromAsync(new Glob3(pattern).scan({ cwd: process.cwd() })));
|
|
15349
15526
|
const files = (await Promise.all(scans)).flat();
|
|
15350
15527
|
const usage = new Map;
|
|
@@ -15410,7 +15587,7 @@ __export(exports_db, {
|
|
|
15410
15587
|
quoteIdent: () => quoteIdent,
|
|
15411
15588
|
runDb: () => runDb
|
|
15412
15589
|
});
|
|
15413
|
-
import { existsSync as
|
|
15590
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync18 } from "fs";
|
|
15414
15591
|
import { join as join42 } from "path";
|
|
15415
15592
|
var {env: env4, spawn: spawn3, SQL } = globalThis.Bun;
|
|
15416
15593
|
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 +15708,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
|
|
|
15531
15708
|
console.log(paint(`\u2713 backup \u2192 ${file}`, colors.green));
|
|
15532
15709
|
console.log(paint(` ${chosen.length} tables, ${total} rows`, colors.dim));
|
|
15533
15710
|
}, runRestore = async (file, options) => {
|
|
15534
|
-
if (!
|
|
15711
|
+
if (!existsSync35(file))
|
|
15535
15712
|
throw new Error(`Backup not found: ${file}`);
|
|
15536
15713
|
const payload = JSON.parse(readFileSync34(file, "utf-8"));
|
|
15537
15714
|
const names = Object.keys(payload.tables).filter((name) => keepTable(name, options));
|
|
@@ -15555,7 +15732,7 @@ var BACKUP_FORMAT_VERSION = 1, RESTORE_CHUNK_ROWS = 500, URL_ENV_KEYS, JSON_DATA
|
|
|
15555
15732
|
const total = order.reduce((sum, name) => sum + (payload.tables[name]?.length ?? 0), 0);
|
|
15556
15733
|
console.log(paint(`\u2713 restored ${order.length} tables, ${total} rows (idempotent upsert by primary key)`, colors.green));
|
|
15557
15734
|
}, runSeed = async (entry) => {
|
|
15558
|
-
const target = entry ?? SEED_CANDIDATES.find((candidate) =>
|
|
15735
|
+
const target = entry ?? SEED_CANDIDATES.find((candidate) => existsSync35(join42(process.cwd(), candidate)));
|
|
15559
15736
|
if (target === undefined)
|
|
15560
15737
|
throw new Error(`No seed script found (looked for ${SEED_CANDIDATES.join(", ")}). Pass a path: absolute db seed <file>.`);
|
|
15561
15738
|
console.log(paint(`seeding via ${target}\u2026`, colors.cyan));
|
|
@@ -15616,7 +15793,7 @@ __export(exports_logs, {
|
|
|
15616
15793
|
});
|
|
15617
15794
|
import {
|
|
15618
15795
|
closeSync as closeSync2,
|
|
15619
|
-
existsSync as
|
|
15796
|
+
existsSync as existsSync36,
|
|
15620
15797
|
openSync as openSync4,
|
|
15621
15798
|
readSync as readSync2,
|
|
15622
15799
|
statSync as statSync4,
|
|
@@ -15683,7 +15860,7 @@ var DEFAULT_LINES = 40, POLL_MS = 250, LINES_FLAG_SPAN = 2, readFrom = (path, st
|
|
|
15683
15860
|
printAvailable(instances);
|
|
15684
15861
|
return;
|
|
15685
15862
|
}
|
|
15686
|
-
if (match.logFile === null || !
|
|
15863
|
+
if (match.logFile === null || !existsSync36(match.logFile)) {
|
|
15687
15864
|
printDim3(`"${name}" has no captured log (untracked, or started outside the CLI).`);
|
|
15688
15865
|
return;
|
|
15689
15866
|
}
|
|
@@ -15703,7 +15880,7 @@ var init_logs = __esm(() => {
|
|
|
15703
15880
|
|
|
15704
15881
|
// src/cli/typeGraphCoherence.ts
|
|
15705
15882
|
import {
|
|
15706
|
-
existsSync as
|
|
15883
|
+
existsSync as existsSync37,
|
|
15707
15884
|
readFileSync as readFileSync35,
|
|
15708
15885
|
realpathSync as realpathSync2,
|
|
15709
15886
|
rmSync as rmSync6,
|
|
@@ -15754,7 +15931,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
15754
15931
|
}, findInstallRoot = (cwd) => {
|
|
15755
15932
|
let directory = resolve32(cwd);
|
|
15756
15933
|
for (;; ) {
|
|
15757
|
-
if (
|
|
15934
|
+
if (existsSync37(join43(directory, "bun.lock")) || existsSync37(join43(directory, "bun.lockb"))) {
|
|
15758
15935
|
return directory;
|
|
15759
15936
|
}
|
|
15760
15937
|
const parent = dirname25(directory);
|
|
@@ -15766,7 +15943,7 @@ var DEPENDENCY_FIELDS, TYPE_GRAPH_PACKAGES, readManifest = (path) => {
|
|
|
15766
15943
|
let directory = resolve32(cwd);
|
|
15767
15944
|
for (;; ) {
|
|
15768
15945
|
const candidate = join43(directory, "package.json");
|
|
15769
|
-
if (
|
|
15946
|
+
if (existsSync37(candidate))
|
|
15770
15947
|
return candidate;
|
|
15771
15948
|
if (directory === installRoot)
|
|
15772
15949
|
return join43(installRoot, "package.json");
|
|
@@ -15907,7 +16084,7 @@ var exports_doctor = {};
|
|
|
15907
16084
|
__export(exports_doctor, {
|
|
15908
16085
|
runDoctor: () => runDoctor
|
|
15909
16086
|
});
|
|
15910
|
-
import { existsSync as
|
|
16087
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync16, readFileSync as readFileSync36, writeFileSync as writeFileSync20 } from "fs";
|
|
15911
16088
|
import { createRequire as createRequire2 } from "module";
|
|
15912
16089
|
import { arch as arch4, platform as platform5 } from "os";
|
|
15913
16090
|
import { join as join44 } from "path";
|
|
@@ -15945,7 +16122,7 @@ var FRAMEWORK_FIELDS2, projectRequire, check = (status2, label, detail) => ({
|
|
|
15945
16122
|
return [];
|
|
15946
16123
|
const label = `${field.replace("Directory", "")} pages`;
|
|
15947
16124
|
return [
|
|
15948
|
-
|
|
16125
|
+
existsSync38(join44(process.cwd(), dir)) ? check("ok", label, dir) : check("fail", label, `${dir} (missing)`)
|
|
15949
16126
|
];
|
|
15950
16127
|
}), envCheck = async () => {
|
|
15951
16128
|
const vars = await collectEnvVars();
|
|
@@ -16007,7 +16184,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
|
|
|
16007
16184
|
const fixes = [];
|
|
16008
16185
|
for (const field of FRAMEWORK_FIELDS2) {
|
|
16009
16186
|
const dir = readString2(config, field);
|
|
16010
|
-
if (dir === undefined ||
|
|
16187
|
+
if (dir === undefined || existsSync38(join44(cwd, dir)))
|
|
16011
16188
|
continue;
|
|
16012
16189
|
mkdirSync16(join44(cwd, dir, "pages"), { recursive: true });
|
|
16013
16190
|
fixes.push(`created ${dir}/pages`);
|
|
@@ -16018,7 +16195,7 @@ ${colors.dim}${checks.length} checks \xB7 ${colors.reset}${summary}${colors.dim}
|
|
|
16018
16195
|
if (missing.length === 0)
|
|
16019
16196
|
return null;
|
|
16020
16197
|
const envExample = join44(cwd, ".env.example");
|
|
16021
|
-
const existing =
|
|
16198
|
+
const existing = existsSync38(envExample) ? readFileSync36(envExample, "utf-8") : "";
|
|
16022
16199
|
const existingKeys = new Set(existing.split(`
|
|
16023
16200
|
`).map((line) => line.split("=")[0]?.trim()));
|
|
16024
16201
|
const toAdd = missing.filter((entry) => !existingKeys.has(entry.key));
|
|
@@ -16392,10 +16569,10 @@ var init_inspect = __esm(() => {
|
|
|
16392
16569
|
});
|
|
16393
16570
|
|
|
16394
16571
|
// src/build/scanEntryPoints.ts
|
|
16395
|
-
import { existsSync as
|
|
16572
|
+
import { existsSync as existsSync39 } from "fs";
|
|
16396
16573
|
var {Glob: Glob4 } = globalThis.Bun;
|
|
16397
16574
|
var scanEntryPoints = async (dir, pattern) => {
|
|
16398
|
-
if (!
|
|
16575
|
+
if (!existsSync39(dir))
|
|
16399
16576
|
return [];
|
|
16400
16577
|
const entryPaths = [];
|
|
16401
16578
|
const glob = new Glob4(pattern);
|
|
@@ -16547,7 +16724,7 @@ var exports_islands = {};
|
|
|
16547
16724
|
__export(exports_islands, {
|
|
16548
16725
|
runIslands: () => runIslands
|
|
16549
16726
|
});
|
|
16550
|
-
import { existsSync as
|
|
16727
|
+
import { existsSync as existsSync40, readFileSync as readFileSync38, statSync as statSync5 } from "fs";
|
|
16551
16728
|
import { join as join45, relative as relative23, resolve as resolve34 } from "path";
|
|
16552
16729
|
var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.write(`${colors.dim}${message}${colors.reset}
|
|
16553
16730
|
`), hostFrameworkOf = (pagePath, cwd, config) => {
|
|
@@ -16567,7 +16744,7 @@ var FRAMEWORK_DIR_KEY, FRAMEWORK_COLOR, printDim6 = (message) => process.stdout.
|
|
|
16567
16744
|
}
|
|
16568
16745
|
}, readManifestSizes2 = (manifestDir) => {
|
|
16569
16746
|
const manifestPath = join45(manifestDir, "manifest.json");
|
|
16570
|
-
if (!
|
|
16747
|
+
if (!existsSync40(manifestPath))
|
|
16571
16748
|
return null;
|
|
16572
16749
|
const manifest = JSON.parse(readFileSync38(manifestPath, "utf-8"));
|
|
16573
16750
|
const sizes = new Map;
|
|
@@ -16707,7 +16884,7 @@ var init_islands2 = __esm(() => {
|
|
|
16707
16884
|
});
|
|
16708
16885
|
|
|
16709
16886
|
// src/build/externalAssetPlugin.ts
|
|
16710
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
16887
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync41, mkdirSync as mkdirSync17, statSync as statSync6 } from "fs";
|
|
16711
16888
|
import { basename as basename12, dirname as dirname27, join as join46, resolve as resolve35 } from "path";
|
|
16712
16889
|
var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
|
|
16713
16890
|
name: "absolute-external-asset",
|
|
@@ -16729,12 +16906,12 @@ var createExternalAssetPlugin = (outDir, userSourceRoots = []) => ({
|
|
|
16729
16906
|
if (!relPath)
|
|
16730
16907
|
continue;
|
|
16731
16908
|
const assetPath = resolve35(sourceDir, relPath);
|
|
16732
|
-
if (!
|
|
16909
|
+
if (!existsSync41(assetPath))
|
|
16733
16910
|
continue;
|
|
16734
16911
|
if (!statSync6(assetPath).isFile())
|
|
16735
16912
|
continue;
|
|
16736
16913
|
const targetPath = join46(outDir, basename12(assetPath));
|
|
16737
|
-
if (
|
|
16914
|
+
if (existsSync41(targetPath))
|
|
16738
16915
|
continue;
|
|
16739
16916
|
mkdirSync17(dirname27(targetPath), { recursive: true });
|
|
16740
16917
|
copyFileSync2(assetPath, targetPath);
|
|
@@ -16754,7 +16931,7 @@ __export(exports_compile, {
|
|
|
16754
16931
|
var {env: env5 } = globalThis.Bun;
|
|
16755
16932
|
import {
|
|
16756
16933
|
cpSync,
|
|
16757
|
-
existsSync as
|
|
16934
|
+
existsSync as existsSync42,
|
|
16758
16935
|
mkdirSync as mkdirSync18,
|
|
16759
16936
|
readdirSync as readdirSync7,
|
|
16760
16937
|
readFileSync as readFileSync39,
|
|
@@ -16845,7 +17022,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
16845
17022
|
const normalizedOutdir = resolve36(outdir);
|
|
16846
17023
|
const copyReference = (filePath, relPath) => {
|
|
16847
17024
|
const assetSource = resolve36(dirname28(filePath), relPath);
|
|
16848
|
-
if (!
|
|
17025
|
+
if (!existsSync42(assetSource) || !statSync7(assetSource).isFile())
|
|
16849
17026
|
return;
|
|
16850
17027
|
const assetTarget = resolve36(normalizedOutdir, relPath.replace(/^\.\//, ""));
|
|
16851
17028
|
if (assetTarget !== normalizedOutdir && !assetTarget.startsWith(`${normalizedOutdir}/`))
|
|
@@ -16929,7 +17106,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
16929
17106
|
resolve36(import.meta.dir, "..", "..", "..", "src", "react", "jsxDevRuntimeCompat.ts")
|
|
16930
17107
|
];
|
|
16931
17108
|
for (const candidate of candidates) {
|
|
16932
|
-
if (
|
|
17109
|
+
if (existsSync42(candidate))
|
|
16933
17110
|
return candidate;
|
|
16934
17111
|
}
|
|
16935
17112
|
return resolve36(import.meta.dir, "..", "..", "react", "jsxDevRuntimeCompat.js");
|
|
@@ -17004,7 +17181,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17004
17181
|
if (!buildConfig.angularDirectory)
|
|
17005
17182
|
return;
|
|
17006
17183
|
const angularScopeDir = resolve36(process.cwd(), "node_modules", "@angular");
|
|
17007
|
-
const angularPackages =
|
|
17184
|
+
const angularPackages = existsSync42(angularScopeDir) ? readdirSync7(angularScopeDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).filter((entry) => entry.name !== "compiler-cli").map((entry) => `@angular/${entry.name}`) : [];
|
|
17008
17185
|
const roots = new Set([...angularPackages, "rxjs", "tslib", "typescript"]);
|
|
17009
17186
|
const seen = new Set;
|
|
17010
17187
|
for (const specifier of roots) {
|
|
@@ -17023,7 +17200,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17023
17200
|
copyChunkReferencedPackages(outdir, seen);
|
|
17024
17201
|
}, collectRuntimePackageSpecifiers = (distDir) => {
|
|
17025
17202
|
const nodeModulesDir = join47(distDir, "node_modules");
|
|
17026
|
-
if (!
|
|
17203
|
+
if (!existsSync42(nodeModulesDir))
|
|
17027
17204
|
return [];
|
|
17028
17205
|
const specifiers = [];
|
|
17029
17206
|
for (const entry of readdirSync7(nodeModulesDir, { withFileTypes: true })) {
|
|
@@ -17064,9 +17241,9 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17064
17241
|
const packageDir = join47(distDir, "node_modules", ...packageSpecifier.split("/"));
|
|
17065
17242
|
const subpath = specifier.slice(packageSpecifier.length);
|
|
17066
17243
|
const subPackageDir = subpath ? join47(packageDir, ...subpath.slice(1).split("/")) : null;
|
|
17067
|
-
const resolvedPackageDir = subPackageDir &&
|
|
17244
|
+
const resolvedPackageDir = subPackageDir && existsSync42(join47(subPackageDir, "package.json")) ? subPackageDir : packageDir;
|
|
17068
17245
|
const packageJsonPath = join47(resolvedPackageDir, "package.json");
|
|
17069
|
-
if (!
|
|
17246
|
+
if (!existsSync42(packageJsonPath))
|
|
17070
17247
|
return null;
|
|
17071
17248
|
const pkg = JSON.parse(readFileSync39(packageJsonPath, "utf-8"));
|
|
17072
17249
|
const exportKey = resolvedPackageDir !== subPackageDir && subpath ? `.${subpath}` : ".";
|
|
@@ -17091,7 +17268,7 @@ var cliTag4 = (color, message) => `\x1B[2m${formatTimestamp()}\x1B[0m ${color}[c
|
|
|
17091
17268
|
}, findContainingRuntimePackageDir = (filePath) => {
|
|
17092
17269
|
let dir = dirname28(filePath);
|
|
17093
17270
|
while (dir !== dirname28(dir)) {
|
|
17094
|
-
if (isNodeModulesPath(dir) &&
|
|
17271
|
+
if (isNodeModulesPath(dir) && existsSync42(join47(dir, "package.json"))) {
|
|
17095
17272
|
return dir;
|
|
17096
17273
|
}
|
|
17097
17274
|
dir = dirname28(dir);
|
|
@@ -17771,11 +17948,11 @@ export default server;
|
|
|
17771
17948
|
process.exit(1);
|
|
17772
17949
|
}
|
|
17773
17950
|
const outputPath = resolve36(resolvedOutdir, `${entryName}.js`);
|
|
17774
|
-
if (!
|
|
17951
|
+
if (!existsSync42(outputPath)) {
|
|
17775
17952
|
console.error(cliTag4("\x1B[31m", `Expected output not found: ${outputPath}`));
|
|
17776
17953
|
process.exit(1);
|
|
17777
17954
|
}
|
|
17778
|
-
if (
|
|
17955
|
+
if (existsSync42(resolve36(resolvedOutdir, "angular", "vendor", "server"))) {
|
|
17779
17956
|
const vendorDir = resolve36(resolvedOutdir, "angular", "vendor", "server");
|
|
17780
17957
|
const vendorEntries = readdirSync7(vendorDir).filter((fileName) => fileName.endsWith(".js"));
|
|
17781
17958
|
const angularServerVendorPaths = {};
|
|
@@ -20633,7 +20810,7 @@ var init_mobileInspect = __esm(() => {
|
|
|
20633
20810
|
});
|
|
20634
20811
|
|
|
20635
20812
|
// src/mobile/ciWorkflow.ts
|
|
20636
|
-
import { existsSync as
|
|
20813
|
+
import { existsSync as existsSync43 } from "fs";
|
|
20637
20814
|
import { access as access15, mkdir as mkdir15, readFile as readFile23, writeFile as writeFile17 } from "fs/promises";
|
|
20638
20815
|
import { dirname as dirname32, extname as extname9, relative as relative30, resolve as resolve43, sep as sep8 } from "path";
|
|
20639
20816
|
var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTATION = 6, RESERVED_SECRET_NAMES, exists4 = async (path) => {
|
|
@@ -20652,7 +20829,7 @@ var ABSOLUTE_MOBILE_CI_WORKFLOW_FORMAT = 1, SECRET_NAME_PATTERN, CI_ENV_INDENTAT
|
|
|
20652
20829
|
}
|
|
20653
20830
|
if (/\r|\n/u.test(portable) || portable.startsWith("-"))
|
|
20654
20831
|
throw new TypeError(`${field} contains an unsafe path.`);
|
|
20655
|
-
if (!options.allowMissing && !
|
|
20832
|
+
if (!options.allowMissing && !existsSync43(path))
|
|
20656
20833
|
throw new TypeError(`${field} does not exist inside the project.`);
|
|
20657
20834
|
return portable;
|
|
20658
20835
|
}, workflowOutputPath = (projectRoot, value) => {
|
|
@@ -21213,7 +21390,26 @@ var NOT_FOUND4 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
21213
21390
|
throw new TypeError(`Expo exited with status ${exitCode}.`);
|
|
21214
21391
|
}, ensureExpoPackages = async (project, args) => {
|
|
21215
21392
|
try {
|
|
21216
|
-
await
|
|
21393
|
+
const manifest = JSON.parse(await readFile24(join56(project, "package.json"), "utf8"));
|
|
21394
|
+
const dependencies = typeof manifest === "object" && manifest !== null ? Reflect.get(manifest, "dependencies") : undefined;
|
|
21395
|
+
if (typeof dependencies !== "object" || dependencies === null || Array.isArray(dependencies))
|
|
21396
|
+
throw new TypeError("Generated Expo dependencies are invalid.");
|
|
21397
|
+
await Promise.all(Object.entries(dependencies).map(async ([name, expected]) => {
|
|
21398
|
+
if (typeof expected !== "string")
|
|
21399
|
+
throw new TypeError("Generated Expo dependency version is invalid.");
|
|
21400
|
+
const installed = JSON.parse(await readFile24(join56(project, "node_modules", name, "package.json"), "utf8"));
|
|
21401
|
+
const actual = typeof installed === "object" && installed !== null ? Reflect.get(installed, "version") : undefined;
|
|
21402
|
+
if (typeof actual !== "string")
|
|
21403
|
+
throw new TypeError("Installed Expo dependency version is invalid.");
|
|
21404
|
+
if (/^\d+\.\d+\.\d+$/u.test(expected) && actual !== expected)
|
|
21405
|
+
throw new TypeError("Installed Expo dependency is outdated.");
|
|
21406
|
+
if (expected.startsWith("~")) {
|
|
21407
|
+
const wanted = expected.slice(1).split(".").map(Number);
|
|
21408
|
+
const found = actual.split(".").map(Number);
|
|
21409
|
+
if (found[0] !== wanted[0] || found[1] !== wanted[1] || (found[2] ?? -1) < (wanted[2] ?? 0))
|
|
21410
|
+
throw new TypeError("Installed Expo dependency is outdated.");
|
|
21411
|
+
}
|
|
21412
|
+
}));
|
|
21217
21413
|
return;
|
|
21218
21414
|
} catch {}
|
|
21219
21415
|
const approved = args.includes("--yes") || await confirmInstall("The experimental Expo shell dependencies are missing. Install the pinned Expo SDK 57 toolchain now?");
|
|
@@ -22779,10 +22975,10 @@ __export(exports_typecheck, {
|
|
|
22779
22975
|
typecheck: () => typecheck
|
|
22780
22976
|
});
|
|
22781
22977
|
import { resolve as resolve45, join as join57 } from "path";
|
|
22782
|
-
import { existsSync as
|
|
22978
|
+
import { existsSync as existsSync44, readFileSync as readFileSync40 } from "fs";
|
|
22783
22979
|
import { mkdir as mkdir17, writeFile as writeFile19 } from "fs/promises";
|
|
22784
22980
|
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 (!
|
|
22981
|
+
if (!existsSync44(resolveConfigPath(configPath2))) {
|
|
22786
22982
|
const defaultService = {};
|
|
22787
22983
|
return [defaultService];
|
|
22788
22984
|
}
|
|
@@ -22804,7 +23000,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
22804
23000
|
return { exitCode, name, output: (stdout + stderr).trim() };
|
|
22805
23001
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
22806
23002
|
const local = resolve45("node_modules", ".bin", name);
|
|
22807
|
-
return
|
|
23003
|
+
return existsSync44(local) ? local : null;
|
|
22808
23004
|
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi4 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
22809
23005
|
const cwd = `${process.cwd()}/`;
|
|
22810
23006
|
const summaryMatch = stripAnsi4(output).match(/svelte-check found (\d+) error/);
|
|
@@ -22856,7 +23052,7 @@ Found ${errorCount} error${suffix}.`;
|
|
|
22856
23052
|
resolve45(import.meta.dir, "../../types", fileName),
|
|
22857
23053
|
resolve45(import.meta.dir, "../../../types", fileName)
|
|
22858
23054
|
];
|
|
22859
|
-
return candidates.find((candidate) =>
|
|
23055
|
+
return candidates.find((candidate) => existsSync44(candidate)) ?? candidates[0];
|
|
22860
23056
|
}, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
|
|
22861
23057
|
try {
|
|
22862
23058
|
return JSON.parse(readFileSync40(resolve45("tsconfig.json"), "utf-8"));
|
|
@@ -23215,13 +23411,13 @@ var {$: $3, env } = globalThis.Bun;
|
|
|
23215
23411
|
import { spawn as nodeSpawn } from "child_process";
|
|
23216
23412
|
import {
|
|
23217
23413
|
createWriteStream,
|
|
23218
|
-
existsSync as
|
|
23219
|
-
readFileSync as
|
|
23414
|
+
existsSync as existsSync6,
|
|
23415
|
+
readFileSync as readFileSync10,
|
|
23220
23416
|
rmSync as rmSync2,
|
|
23221
23417
|
writeFileSync as writeFileSync4
|
|
23222
23418
|
} from "fs";
|
|
23223
23419
|
import { tmpdir as tmpdir2 } from "os";
|
|
23224
|
-
import { join as
|
|
23420
|
+
import { join as join17, resolve as resolvePath2 } from "path";
|
|
23225
23421
|
|
|
23226
23422
|
// src/dev/tunnel/client.ts
|
|
23227
23423
|
var RECONNECT_DELAY_MS = 2000;
|
|
@@ -23731,7 +23927,7 @@ init_expoProject();
|
|
|
23731
23927
|
init_iosPhysicalDeviceTransport();
|
|
23732
23928
|
import { spawn } from "child_process";
|
|
23733
23929
|
import { access as access2 } from "fs/promises";
|
|
23734
|
-
import { join as
|
|
23930
|
+
import { join as join9 } from "path";
|
|
23735
23931
|
var METRO_READY_TIMEOUT_MS = 60000;
|
|
23736
23932
|
var PROCESS_CLOSE_TIMEOUT_MS = 2000;
|
|
23737
23933
|
var commandEnvironment = (options) => ({
|
|
@@ -23744,7 +23940,7 @@ var commandEnvironment = (options) => ({
|
|
|
23744
23940
|
...options.metroHost ? { REACT_NATIVE_PACKAGER_HOSTNAME: options.metroHost } : {}
|
|
23745
23941
|
});
|
|
23746
23942
|
var absoluteExpoExecutable = async (project) => {
|
|
23747
|
-
const executable =
|
|
23943
|
+
const executable = join9(project, "node_modules", ".bin", "expo");
|
|
23748
23944
|
try {
|
|
23749
23945
|
await access2(executable);
|
|
23750
23946
|
return executable;
|
|
@@ -23840,18 +24036,18 @@ var stopProcess = async (process2) => {
|
|
|
23840
24036
|
return;
|
|
23841
24037
|
process2.kill("SIGTERM");
|
|
23842
24038
|
await Promise.race([
|
|
23843
|
-
new Promise((
|
|
23844
|
-
new Promise((
|
|
24039
|
+
new Promise((resolve6) => process2.once("exit", () => resolve6())),
|
|
24040
|
+
new Promise((resolve6) => setTimeout(resolve6, PROCESS_CLOSE_TIMEOUT_MS))
|
|
23845
24041
|
]);
|
|
23846
24042
|
if (process2.exitCode === null)
|
|
23847
24043
|
process2.kill("SIGKILL");
|
|
23848
24044
|
};
|
|
23849
|
-
var waitForExit = (process2) => new Promise((
|
|
24045
|
+
var waitForExit = (process2) => new Promise((resolve6) => {
|
|
23850
24046
|
if (process2.exitCode !== null) {
|
|
23851
|
-
|
|
24047
|
+
resolve6(process2.exitCode);
|
|
23852
24048
|
return;
|
|
23853
24049
|
}
|
|
23854
|
-
process2.once("exit", (code) =>
|
|
24050
|
+
process2.once("exit", (code) => resolve6(code ?? 1));
|
|
23855
24051
|
});
|
|
23856
24052
|
var runUtilityCommand = async (run, command, args, options) => {
|
|
23857
24053
|
const child = run(command, args, {
|
|
@@ -23931,9 +24127,9 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
23931
24127
|
}) : undefined;
|
|
23932
24128
|
let metroReady = false;
|
|
23933
24129
|
let resolveMetro;
|
|
23934
|
-
const metroPromise = new Promise((
|
|
24130
|
+
const metroPromise = new Promise((resolve6, reject) => {
|
|
23935
24131
|
if (!metro) {
|
|
23936
|
-
|
|
24132
|
+
resolve6();
|
|
23937
24133
|
return;
|
|
23938
24134
|
}
|
|
23939
24135
|
const timeout = setTimeout(() => {
|
|
@@ -23941,7 +24137,7 @@ var startAbsoluteExpoDevSession = async (options) => {
|
|
|
23941
24137
|
}, METRO_READY_TIMEOUT_MS);
|
|
23942
24138
|
resolveMetro = () => {
|
|
23943
24139
|
clearTimeout(timeout);
|
|
23944
|
-
|
|
24140
|
+
resolve6();
|
|
23945
24141
|
};
|
|
23946
24142
|
metro.once("exit", (code) => {
|
|
23947
24143
|
if (!metroReady) {
|
|
@@ -24306,7 +24502,7 @@ var DEFAULT_PORT_RANGE = 10;
|
|
|
24306
24502
|
var RESTART_PARK_POLL_MS = 20;
|
|
24307
24503
|
var NODE_API_IMPORT_ERROR = "To load Node-API modules, use require() or process.dlopen instead of import.";
|
|
24308
24504
|
var sourceServerBootstrap = resolvePath2(import.meta.dir, "../../dev/serverBootstrap.ts");
|
|
24309
|
-
var serverBootstrap =
|
|
24505
|
+
var serverBootstrap = existsSync6(sourceServerBootstrap) ? sourceServerBootstrap : resolvePath2(import.meta.dir, "../dev/serverBootstrap.js");
|
|
24310
24506
|
var formatServerBootDiagnostic = (output, serverEntry) => {
|
|
24311
24507
|
if (!output.includes(NODE_API_IMPORT_ERROR))
|
|
24312
24508
|
return null;
|
|
@@ -24496,7 +24692,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24496
24692
|
const generated = await writeAbsoluteExpoProject(normalized, {
|
|
24497
24693
|
projectRoot: process.cwd()
|
|
24498
24694
|
});
|
|
24499
|
-
const dependenciesReady =
|
|
24695
|
+
const dependenciesReady = existsSync6(join17(generated.path, "node_modules", "expo", "package.json")) && existsSync6(join17(generated.path, "node_modules", "expo-dev-client", "package.json"));
|
|
24500
24696
|
if (!dependenciesReady) {
|
|
24501
24697
|
const install = await confirmPrompt("Expo development dependencies are missing. Install the pinned SDK 57 development client now?");
|
|
24502
24698
|
if (!install) {
|
|
@@ -24506,7 +24702,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24506
24702
|
cwd: generated.path,
|
|
24507
24703
|
stdio: "inherit"
|
|
24508
24704
|
});
|
|
24509
|
-
const installExit = await new Promise((
|
|
24705
|
+
const installExit = await new Promise((resolve11) => installProcess.once("exit", (code) => resolve11(code ?? 1)));
|
|
24510
24706
|
if (installExit !== 0) {
|
|
24511
24707
|
throw new TypeError(`Expo dependency installation exited with status ${installExit}.`);
|
|
24512
24708
|
}
|
|
@@ -24575,12 +24771,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24575
24771
|
}
|
|
24576
24772
|
}
|
|
24577
24773
|
if (ready) {
|
|
24578
|
-
const nativeDirectory =
|
|
24774
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "android");
|
|
24579
24775
|
let createNativeProject = false;
|
|
24580
|
-
if (!
|
|
24776
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24581
24777
|
createNativeProject = await confirmPrompt("Create the managed Capacitor Android project now?");
|
|
24582
24778
|
}
|
|
24583
|
-
if (
|
|
24779
|
+
if (existsSync6(nativeDirectory) || createNativeProject) {
|
|
24584
24780
|
androidDevProject = await prepareAbsoluteAndroidDevProject(normalized, {
|
|
24585
24781
|
createNativeProject,
|
|
24586
24782
|
projectRoot: process.cwd(),
|
|
@@ -24595,8 +24791,8 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24595
24791
|
if (!remote) {
|
|
24596
24792
|
console.log(cliTag("\x1B[33m", "iOS target skipped. Pair a Mac with `absolute mobile pair mac <name> <user@host>`."));
|
|
24597
24793
|
} else {
|
|
24598
|
-
const nativeDirectory =
|
|
24599
|
-
if (!
|
|
24794
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "ios");
|
|
24795
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24600
24796
|
console.log(cliTag("\x1B[33m", "The iOS project is missing. Run `absolute mobile init` before remote development."));
|
|
24601
24797
|
} else {
|
|
24602
24798
|
iosDevProject = createAbsoluteRemoteIosDevProject(normalized, process.cwd(), remote);
|
|
@@ -24616,12 +24812,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24616
24812
|
}
|
|
24617
24813
|
}
|
|
24618
24814
|
if (ready) {
|
|
24619
|
-
const nativeDirectory =
|
|
24815
|
+
const nativeDirectory = join17(normalized.nativeProjectDirectory, "ios");
|
|
24620
24816
|
let createNativeProject = false;
|
|
24621
|
-
if (!
|
|
24817
|
+
if (!existsSync6(nativeDirectory)) {
|
|
24622
24818
|
createNativeProject = await confirmPrompt("Create the managed Capacitor iOS project now?");
|
|
24623
24819
|
}
|
|
24624
|
-
if (
|
|
24820
|
+
if (existsSync6(nativeDirectory) || createNativeProject) {
|
|
24625
24821
|
iosDevProject = await prepareAbsoluteIosDevProject(normalized, {
|
|
24626
24822
|
createNativeProject,
|
|
24627
24823
|
projectRoot: process.cwd(),
|
|
@@ -24690,12 +24886,12 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
24690
24886
|
startedAt: new Date().toISOString()
|
|
24691
24887
|
});
|
|
24692
24888
|
const instanceLog = createWriteStream(instanceLogFile, { flags: "w" });
|
|
24693
|
-
const writeInstanceLog = (
|
|
24889
|
+
const writeInstanceLog = (text2) => {
|
|
24694
24890
|
try {
|
|
24695
|
-
instanceLog.write(
|
|
24891
|
+
instanceLog.write(text2.replace(ANSI_LOG_REGEX, ""));
|
|
24696
24892
|
} catch {}
|
|
24697
24893
|
};
|
|
24698
|
-
const usesDocker =
|
|
24894
|
+
const usesDocker = existsSync6(resolvePath2(COMPOSE_PATH));
|
|
24699
24895
|
const scripts = usesDocker ? await readDbScripts() : null;
|
|
24700
24896
|
if (scripts)
|
|
24701
24897
|
await startDatabase(scripts);
|
|
@@ -25181,8 +25377,8 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25181
25377
|
const ANSI_COLOR_SEQUENCE_RE = new RegExp(`${ANSI_ESCAPE}\\[[0-9;]*m`, "g");
|
|
25182
25378
|
let restartScanBuffer = "";
|
|
25183
25379
|
const handleChunk = (value) => {
|
|
25184
|
-
const
|
|
25185
|
-
restartScanBuffer +=
|
|
25380
|
+
const text2 = value.toString("utf8");
|
|
25381
|
+
restartScanBuffer += text2;
|
|
25186
25382
|
let newlineIdx;
|
|
25187
25383
|
while ((newlineIdx = restartScanBuffer.indexOf(`
|
|
25188
25384
|
`)) !== -1) {
|
|
@@ -25250,13 +25446,13 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25250
25446
|
const merged = {};
|
|
25251
25447
|
const candidates = [".env", ".env.development", ".env.local"];
|
|
25252
25448
|
for (const name of candidates) {
|
|
25253
|
-
let
|
|
25449
|
+
let text2;
|
|
25254
25450
|
try {
|
|
25255
|
-
|
|
25451
|
+
text2 = readFileSync10(resolvePath2(process.cwd(), name), "utf8");
|
|
25256
25452
|
} catch {
|
|
25257
25453
|
continue;
|
|
25258
25454
|
}
|
|
25259
|
-
for (const rawLine of
|
|
25455
|
+
for (const rawLine of text2.split(`
|
|
25260
25456
|
`)) {
|
|
25261
25457
|
const line = rawLine.trim();
|
|
25262
25458
|
if (!line || line.startsWith("#"))
|
|
@@ -25274,7 +25470,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25274
25470
|
}
|
|
25275
25471
|
return merged;
|
|
25276
25472
|
};
|
|
25277
|
-
const heapPreloadPath =
|
|
25473
|
+
const heapPreloadPath = join17(tmpdir2(), `absolute-heap-${process.pid}.ts`);
|
|
25278
25474
|
let heapSnapshotEnabled = false;
|
|
25279
25475
|
try {
|
|
25280
25476
|
writeFileSync4(heapPreloadPath, DEV_CHILD_PRELOAD);
|
|
@@ -25407,7 +25603,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25407
25603
|
if (now - last < 100)
|
|
25408
25604
|
return;
|
|
25409
25605
|
recentlyHandled.set(filename, now);
|
|
25410
|
-
scheduleServerRestart(
|
|
25606
|
+
scheduleServerRestart(join17(serverEntryDir, filename));
|
|
25411
25607
|
};
|
|
25412
25608
|
const recoveryScan = async () => {
|
|
25413
25609
|
let entries;
|
|
@@ -25426,7 +25622,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
25426
25622
|
continue;
|
|
25427
25623
|
let fileStat;
|
|
25428
25624
|
try {
|
|
25429
|
-
fileStat = statSync(
|
|
25625
|
+
fileStat = statSync(join17(serverEntryDir, entry.name));
|
|
25430
25626
|
} catch {
|
|
25431
25627
|
continue;
|
|
25432
25628
|
}
|
|
@@ -25814,9 +26010,9 @@ init_eslint();
|
|
|
25814
26010
|
init_constants();
|
|
25815
26011
|
init_utils();
|
|
25816
26012
|
import { execSync as execSync2 } from "child_process";
|
|
25817
|
-
import { existsSync as
|
|
26013
|
+
import { existsSync as existsSync9, readFileSync as readFileSync12 } from "fs";
|
|
25818
26014
|
import { arch as arch2, cpus, platform as platform3, totalmem, version } from "os";
|
|
25819
|
-
import { resolve as
|
|
26015
|
+
import { resolve as resolve13 } from "path";
|
|
25820
26016
|
var bold = (str) => `\x1B[1m${str}\x1B[0m`;
|
|
25821
26017
|
var getBinaryVersion = (binary, flag = "--version") => {
|
|
25822
26018
|
try {
|
|
@@ -25836,7 +26032,7 @@ var getPackageVersion = (packageName) => {
|
|
|
25836
26032
|
const pkgPath = __require.resolve(`${packageName}/package.json`, {
|
|
25837
26033
|
paths: [process.cwd()]
|
|
25838
26034
|
});
|
|
25839
|
-
const pkg = JSON.parse(
|
|
26035
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
25840
26036
|
const ver = pkg.version;
|
|
25841
26037
|
return ver;
|
|
25842
26038
|
} catch {
|
|
@@ -25846,10 +26042,10 @@ var getPackageVersion = (packageName) => {
|
|
|
25846
26042
|
var getAbsoluteVersion = () => {
|
|
25847
26043
|
try {
|
|
25848
26044
|
const candidates = [
|
|
25849
|
-
|
|
25850
|
-
|
|
26045
|
+
resolve13(import.meta.dir, "..", "..", "package.json"),
|
|
26046
|
+
resolve13(import.meta.dir, "..", "..", "..", "package.json")
|
|
25851
26047
|
];
|
|
25852
|
-
const pkgPath = candidates.find((candidate) =>
|
|
26048
|
+
const pkgPath = candidates.find((candidate) => existsSync9(candidate));
|
|
25853
26049
|
if (pkgPath)
|
|
25854
26050
|
return readPackageVersion(pkgPath);
|
|
25855
26051
|
} catch {
|
|
@@ -25858,7 +26054,7 @@ var getAbsoluteVersion = () => {
|
|
|
25858
26054
|
return getPackageVersion("@absolutejs/absolute");
|
|
25859
26055
|
};
|
|
25860
26056
|
var readPackageVersion = (pkgPath) => {
|
|
25861
|
-
const pkg = JSON.parse(
|
|
26057
|
+
const pkg = JSON.parse(readFileSync12(pkgPath, "utf-8"));
|
|
25862
26058
|
const ver = pkg.version;
|
|
25863
26059
|
return ver;
|
|
25864
26060
|
};
|
|
@@ -25890,7 +26086,7 @@ var detectCI = () => {
|
|
|
25890
26086
|
};
|
|
25891
26087
|
var isDockerEnvironment = () => {
|
|
25892
26088
|
try {
|
|
25893
|
-
return
|
|
26089
|
+
return existsSync9("/.dockerenv");
|
|
25894
26090
|
} catch {
|
|
25895
26091
|
return false;
|
|
25896
26092
|
}
|
|
@@ -25960,11 +26156,11 @@ var info = () => {
|
|
|
25960
26156
|
// src/cli/cache.ts
|
|
25961
26157
|
init_constants();
|
|
25962
26158
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
25963
|
-
import { join as
|
|
26159
|
+
import { join as join18 } from "path";
|
|
25964
26160
|
var {Glob } = globalThis.Bun;
|
|
25965
26161
|
var CACHE_DIR = ".absolutejs";
|
|
25966
26162
|
var MAX_FILES_PER_BATCH = 200;
|
|
25967
|
-
var
|
|
26163
|
+
var isIgnored2 = (file, ignorePatterns) => ignorePatterns.some((pat) => new Glob(pat).match(file));
|
|
25968
26164
|
var collectFiles = async (pattern, ignorePatterns) => {
|
|
25969
26165
|
const files = [];
|
|
25970
26166
|
const glob = new Glob(pattern);
|
|
@@ -25972,7 +26168,7 @@ var collectFiles = async (pattern, ignorePatterns) => {
|
|
|
25972
26168
|
cwd: ".",
|
|
25973
26169
|
dot: false
|
|
25974
26170
|
})) {
|
|
25975
|
-
if (!
|
|
26171
|
+
if (!isIgnored2(file, ignorePatterns))
|
|
25976
26172
|
files.push(file);
|
|
25977
26173
|
}
|
|
25978
26174
|
return files;
|
|
@@ -26012,7 +26208,7 @@ var hashFiles = async (paths) => {
|
|
|
26012
26208
|
};
|
|
26013
26209
|
var loadCache = async (tool) => {
|
|
26014
26210
|
try {
|
|
26015
|
-
const path =
|
|
26211
|
+
const path = join18(CACHE_DIR, `${tool}.cache.json`);
|
|
26016
26212
|
const data = await Bun.file(path).json();
|
|
26017
26213
|
const result = data;
|
|
26018
26214
|
return result;
|
|
@@ -26059,7 +26255,7 @@ var runTool = async (adapter, args) => {
|
|
|
26059
26255
|
};
|
|
26060
26256
|
var saveCache = async (tool, data) => {
|
|
26061
26257
|
await mkdir7(CACHE_DIR, { recursive: true });
|
|
26062
|
-
const path =
|
|
26258
|
+
const path = join18(CACHE_DIR, `${tool}.cache.json`);
|
|
26063
26259
|
await Bun.write(path, JSON.stringify(data, null, "\t"));
|
|
26064
26260
|
};
|
|
26065
26261
|
|
|
@@ -26152,7 +26348,7 @@ init_getDurationString();
|
|
|
26152
26348
|
init_instanceRegistry();
|
|
26153
26349
|
import {
|
|
26154
26350
|
appendFileSync,
|
|
26155
|
-
existsSync as
|
|
26351
|
+
existsSync as existsSync13,
|
|
26156
26352
|
mkdirSync as mkdirSync7,
|
|
26157
26353
|
readdirSync as readdirSync2,
|
|
26158
26354
|
readFileSync as readFileSync16,
|
|
@@ -26723,7 +26919,7 @@ var createWorkspaceTui = ({
|
|
|
26723
26919
|
// src/cli/scripts/workspace.ts
|
|
26724
26920
|
init_utils();
|
|
26725
26921
|
var sourceServerBootstrap2 = resolve22(import.meta.dir, "../../dev/serverBootstrap.ts");
|
|
26726
|
-
var serverBootstrap2 =
|
|
26922
|
+
var serverBootstrap2 = existsSync13(sourceServerBootstrap2) ? sourceServerBootstrap2 : resolve22(import.meta.dir, "../dev/serverBootstrap.js");
|
|
26727
26923
|
var ANSI_REGEX2 = new RegExp(`${String.fromCharCode(ANSI_ESCAPE_CODE)}\\[[0-?]*[ -/]*[@-~]`, "g");
|
|
26728
26924
|
var sleep = (durationMs) => Bun.sleep(durationMs);
|
|
26729
26925
|
var stripAnsi3 = (value) => value.replace(ANSI_REGEX2, "");
|
|
@@ -27370,7 +27566,7 @@ var workspace = async (subcommand, options) => {
|
|
|
27370
27566
|
const resolved = resolveService(name, service, workspaceEnv, options);
|
|
27371
27567
|
const port = resolveWorkspaceServicePort(resolved.service, resolved.env);
|
|
27372
27568
|
killStaleServicePort(port);
|
|
27373
|
-
if (isAbsoluteService(resolved.service) && resolved.configPath && !
|
|
27569
|
+
if (isAbsoluteService(resolved.service) && resolved.configPath && !existsSync13(resolved.configPath)) {
|
|
27374
27570
|
throw new Error(`${name} references missing config "${resolved.configPath}"`);
|
|
27375
27571
|
}
|
|
27376
27572
|
serviceBootStartedAt.set(name, performance.now());
|