@absolutejs/absolute 0.20.0-beta.35 → 0.20.0-beta.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +347 -63
- package/dist/dev/serverBootstrap.js +28 -0
- package/dist/mobile/index.js +13 -10
- package/dist/mobile/index.js.map +4 -4
- package/dist/mobile/remoteMacAgentEntry.js +11 -11
- package/dist/src/dev/serverEntryCopies.d.ts +3 -0
- package/dist/src/mobile/iosRelease.d.ts +3 -1
- package/dist/src/mobile/iosSimulatorController.d.ts +6 -1
- package/dist/src/mobile/mobileInspect.d.ts +110 -0
- package/package.json +4 -2
package/dist/cli/index.js
CHANGED
|
@@ -2635,22 +2635,22 @@ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array
|
|
|
2635
2635
|
stdout: ""
|
|
2636
2636
|
};
|
|
2637
2637
|
}
|
|
2638
|
-
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root) => {
|
|
2638
|
+
}, ignoredFingerprintDirectories, fingerprintFiles = async (root, current = root, options = {}) => {
|
|
2639
2639
|
const entries = await readdir2(current, { withFileTypes: true });
|
|
2640
2640
|
const nested = await Promise.all(entries.sort((left, right) => left.name.localeCompare(right.name)).map(async (entry) => {
|
|
2641
2641
|
const path = join9(current, entry.name);
|
|
2642
2642
|
const projectRelative = relative3(root, path).replaceAll("\\", "/");
|
|
2643
|
-
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public");
|
|
2643
|
+
const ignored = entry.isDirectory() && (ignoredFingerprintDirectories.has(entry.name) || projectRelative === "App/App/public" && options.includePublicBundle !== true);
|
|
2644
2644
|
if (ignored)
|
|
2645
2645
|
return [];
|
|
2646
2646
|
if (entry.isDirectory())
|
|
2647
|
-
return fingerprintFiles(root, path);
|
|
2647
|
+
return fingerprintFiles(root, path, options);
|
|
2648
2648
|
return entry.isFile() ? [path] : [];
|
|
2649
2649
|
}));
|
|
2650
2650
|
return nested.flat();
|
|
2651
|
-
}, fingerprintAbsoluteIosNativeProject = async (nativeDirectory) => {
|
|
2651
|
+
}, fingerprintAbsoluteIosNativeProject = async (nativeDirectory, options = {}) => {
|
|
2652
2652
|
const hasher = createHash3("sha256");
|
|
2653
|
-
const files = await fingerprintFiles(nativeDirectory);
|
|
2653
|
+
const files = await fingerprintFiles(nativeDirectory, nativeDirectory, options);
|
|
2654
2654
|
const contents = await Promise.all(files.map((file) => readFile4(file)));
|
|
2655
2655
|
files.forEach((file, index) => {
|
|
2656
2656
|
hasher.update(relative3(nativeDirectory, file).replaceAll("\\", "/"));
|
|
@@ -3299,7 +3299,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3299
3299
|
return;
|
|
3300
3300
|
});
|
|
3301
3301
|
}
|
|
3302
|
-
}, fingerprintAbsoluteIosDevProject = async (project) => fingerprintAbsoluteIosNativeProject(project.nativeDirectory), simulatorInventory = (xcrun, capture) => {
|
|
3302
|
+
}, fingerprintAbsoluteIosDevProject = async (project, options = {}) => fingerprintAbsoluteIosNativeProject(project.nativeDirectory, options), simulatorInventory = (xcrun, capture) => {
|
|
3303
3303
|
const result = capture([
|
|
3304
3304
|
xcrun,
|
|
3305
3305
|
"simctl",
|
|
@@ -3671,10 +3671,13 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3671
3671
|
transition("syncing");
|
|
3672
3672
|
await requireSuccess2([project.cap, "sync", "ios"], "Capacitor iOS synchronization", run, { cwd: project.projectRoot, signal: options.signal });
|
|
3673
3673
|
transition("configuring");
|
|
3674
|
-
|
|
3674
|
+
if (options.embeddedBundle !== true)
|
|
3675
|
+
await writeDevProjection(project, options.port, options.https === true, serverHost);
|
|
3675
3676
|
throwIfAborted2(options.signal);
|
|
3676
3677
|
const fingerprintStartedAt = performance.now();
|
|
3677
|
-
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project
|
|
3678
|
+
const fingerprintPromise = fingerprintAbsoluteIosDevProject(project, {
|
|
3679
|
+
includePublicBundle: options.embeddedBundle === true
|
|
3680
|
+
}).then((fingerprint2) => {
|
|
3678
3681
|
timings.fingerprinting = performance.now() - fingerprintStartedAt;
|
|
3679
3682
|
return fingerprint2;
|
|
3680
3683
|
});
|
|
@@ -3735,7 +3738,7 @@ var ABSOLUTE_IOS_SIMULATOR_NAME = "AbsoluteJS iPhone", BOOT_TIMEOUT_MS = 180000,
|
|
|
3735
3738
|
await requireSuccess2(iosLaunchCommand(project, udid, deviceIdentifier !== undefined), "iOS app launch", run, { signal: options.signal });
|
|
3736
3739
|
transition("ready");
|
|
3737
3740
|
timings.total = performance.now() - startedAt;
|
|
3738
|
-
log(`iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3741
|
+
log(options.embeddedBundle === true ? `iOS ${targetKind} connected with the embedded bundle and backend on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).` : `iOS ${targetKind} connected with HMR on port ${options.port} in ${getDurationString(timings.total)} (${nativeCacheHit ? "native cache hit" : "native build installed"}).`);
|
|
3739
3742
|
log(`iOS startup: ${timingSummary(timings)}.`);
|
|
3740
3743
|
let closed = false;
|
|
3741
3744
|
const close = async () => {
|
|
@@ -18993,16 +18996,270 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
|
18993
18996
|
};
|
|
18994
18997
|
var init_releasePublisher = () => {};
|
|
18995
18998
|
|
|
18999
|
+
// src/mobile/mobileInspect.ts
|
|
19000
|
+
import { access as access11, readFile as readFile20, stat as stat4 } from "fs/promises";
|
|
19001
|
+
import { join as join52, relative as relative27, resolve as resolve41 } from "path";
|
|
19002
|
+
var ABSOLUTE_MOBILE_INSPECTION_FORMAT = 1, MOBILE_PACKAGE_NAMES, MOBILE_FRAMEWORKS, isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), portablePath = (projectRoot, path) => {
|
|
19003
|
+
const value = relative27(resolve41(projectRoot), resolve41(path)).replaceAll("\\", "/");
|
|
19004
|
+
return value || ".";
|
|
19005
|
+
}, pathExists7 = async (path) => {
|
|
19006
|
+
try {
|
|
19007
|
+
await access11(path);
|
|
19008
|
+
return true;
|
|
19009
|
+
} catch {
|
|
19010
|
+
return false;
|
|
19011
|
+
}
|
|
19012
|
+
}, readObject = async (path) => {
|
|
19013
|
+
const value = JSON.parse(await readFile20(path, "utf8"));
|
|
19014
|
+
if (!isObject2(value))
|
|
19015
|
+
throw new TypeError("JSON root must be an object.");
|
|
19016
|
+
return value;
|
|
19017
|
+
}, requireString = (value, field) => {
|
|
19018
|
+
if (typeof value !== "string" || value.length === 0)
|
|
19019
|
+
throw new TypeError(`${field} must be a non-empty string.`);
|
|
19020
|
+
return value;
|
|
19021
|
+
}, requireStringArray = (value, field) => {
|
|
19022
|
+
if (!Array.isArray(value) || !value.every((item) => typeof item === "string"))
|
|
19023
|
+
throw new TypeError(`${field} must be a string array.`);
|
|
19024
|
+
return value;
|
|
19025
|
+
}, requireBundleFile = async (root, value, field) => {
|
|
19026
|
+
const portable = requireString(value, field);
|
|
19027
|
+
const path = resolve41(root, portable);
|
|
19028
|
+
const normalizedRoot = resolve41(root);
|
|
19029
|
+
if (path === normalizedRoot || !path.startsWith(`${normalizedRoot}/`))
|
|
19030
|
+
throw new TypeError(`${field} must remain inside the mobile bundle.`);
|
|
19031
|
+
if (!(await stat4(path).catch(() => {
|
|
19032
|
+
return;
|
|
19033
|
+
}))?.isFile())
|
|
19034
|
+
throw new TypeError(`${field} does not exist in the mobile bundle.`);
|
|
19035
|
+
return portable;
|
|
19036
|
+
}, inspectBundle = async (config, projectRoot) => {
|
|
19037
|
+
const manifestPath = join52(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
19038
|
+
const manifest = portablePath(projectRoot, manifestPath);
|
|
19039
|
+
if (!await pathExists7(manifestPath))
|
|
19040
|
+
return { manifest, status: "missing" };
|
|
19041
|
+
try {
|
|
19042
|
+
const value = await readObject(manifestPath);
|
|
19043
|
+
if (value.format !== 1)
|
|
19044
|
+
throw new TypeError("format is not supported by this runtime.");
|
|
19045
|
+
if (requireString(value.appId, "appId") !== config.appId)
|
|
19046
|
+
throw new TypeError("appId does not match the effective mobile config.");
|
|
19047
|
+
if (requireString(value.productionOrigin, "productionOrigin") !== config.productionOrigin)
|
|
19048
|
+
throw new TypeError("productionOrigin does not match the effective mobile config.");
|
|
19049
|
+
const appBuild = requireString(value.appBuild, "appBuild");
|
|
19050
|
+
const runtime = requireString(value.runtime, "runtime");
|
|
19051
|
+
const capabilities = requireStringArray(value.deviceCapabilities, "deviceCapabilities").sort();
|
|
19052
|
+
if (!Array.isArray(value.pages) || !Array.isArray(value.routes))
|
|
19053
|
+
throw new TypeError("pages and routes must be arrays.");
|
|
19054
|
+
const pageIds = new Set;
|
|
19055
|
+
const frameworks7 = new Set;
|
|
19056
|
+
await Promise.all(value.pages.map(async (candidate) => {
|
|
19057
|
+
if (!isObject2(candidate))
|
|
19058
|
+
throw new TypeError("pages contains an invalid entry.");
|
|
19059
|
+
const pageId = requireString(candidate.pageId, "page.pageId");
|
|
19060
|
+
if (pageIds.has(pageId))
|
|
19061
|
+
throw new TypeError("page.pageId values must be unique.");
|
|
19062
|
+
pageIds.add(pageId);
|
|
19063
|
+
const framework = requireString(candidate.framework, "page.framework");
|
|
19064
|
+
if (!MOBILE_FRAMEWORKS.has(framework))
|
|
19065
|
+
throw new TypeError("page.framework is unsupported.");
|
|
19066
|
+
frameworks7.add(framework);
|
|
19067
|
+
requireString(candidate.bundleHash, "page.bundleHash");
|
|
19068
|
+
requireString(candidate.contract, "page.contract");
|
|
19069
|
+
requireString(candidate.propsSchemaHash, "page.propsSchemaHash");
|
|
19070
|
+
await requireBundleFile(config.bundleDirectory, candidate.localBundlePath, "page.localBundlePath");
|
|
19071
|
+
if (candidate.localStylePath !== undefined)
|
|
19072
|
+
await requireBundleFile(config.bundleDirectory, candidate.localStylePath, "page.localStylePath");
|
|
19073
|
+
}));
|
|
19074
|
+
const routes = value.routes.map((candidate) => {
|
|
19075
|
+
if (!isObject2(candidate))
|
|
19076
|
+
throw new TypeError("routes contains an invalid entry.");
|
|
19077
|
+
const { method } = candidate;
|
|
19078
|
+
if (method !== "GET" && method !== "HEAD")
|
|
19079
|
+
throw new TypeError("route.method must be GET or HEAD.");
|
|
19080
|
+
const pageId = requireString(candidate.pageId, "route.pageId");
|
|
19081
|
+
if (!pageIds.has(pageId))
|
|
19082
|
+
throw new TypeError("route.pageId references a missing page.");
|
|
19083
|
+
return {
|
|
19084
|
+
method,
|
|
19085
|
+
pageId,
|
|
19086
|
+
pattern: requireString(candidate.pattern, "route.pattern")
|
|
19087
|
+
};
|
|
19088
|
+
});
|
|
19089
|
+
await Promise.all(["index.html", "absolute-mobile-bootstrap.js"].map((file) => requireBundleFile(config.bundleDirectory, file, file)));
|
|
19090
|
+
const entryPath = new URL(config.entry, "https://absolute.invalid").pathname;
|
|
19091
|
+
const entryResolved = resolveAbsoluteMobileRoute(routes, entryPath) !== undefined;
|
|
19092
|
+
if (!entryResolved)
|
|
19093
|
+
throw new TypeError("entry is not owned by an embedded route.");
|
|
19094
|
+
return {
|
|
19095
|
+
appBuild,
|
|
19096
|
+
auth: isObject2(value.auth),
|
|
19097
|
+
capabilities,
|
|
19098
|
+
entryResolved,
|
|
19099
|
+
frameworks: [...frameworks7].sort(),
|
|
19100
|
+
manifest,
|
|
19101
|
+
pageCount: value.pages.length,
|
|
19102
|
+
routeCount: value.routes.length,
|
|
19103
|
+
runtime,
|
|
19104
|
+
status: "valid",
|
|
19105
|
+
sync: isObject2(value.sync)
|
|
19106
|
+
};
|
|
19107
|
+
} catch (error) {
|
|
19108
|
+
return {
|
|
19109
|
+
issue: error instanceof Error ? error.message : "The embedded mobile manifest is invalid.",
|
|
19110
|
+
manifest,
|
|
19111
|
+
status: "invalid"
|
|
19112
|
+
};
|
|
19113
|
+
}
|
|
19114
|
+
}, addPackageDeclarations = (declarations, value) => {
|
|
19115
|
+
if (!isObject2(value))
|
|
19116
|
+
return;
|
|
19117
|
+
for (const [name, declared] of Object.entries(value).filter((entry) => typeof entry[1] === "string"))
|
|
19118
|
+
declarations.set(name, declared);
|
|
19119
|
+
}, packageInspections = async (projectRoot, additionalNames) => {
|
|
19120
|
+
const project = await readObject(join52(projectRoot, "package.json"));
|
|
19121
|
+
const declarations = new Map;
|
|
19122
|
+
for (const field of ["dependencies", "devDependencies"])
|
|
19123
|
+
addPackageDeclarations(declarations, project[field]);
|
|
19124
|
+
const names = [...new Set([...declarations.keys(), ...additionalNames])].filter((name) => MOBILE_PACKAGE_NAMES.has(name) || name.startsWith("@capacitor/") || additionalNames.includes(name)).sort();
|
|
19125
|
+
return Promise.all(names.map(async (name) => {
|
|
19126
|
+
const installedManifest = await readObject(join52(projectRoot, "node_modules", name, "package.json")).catch(() => {
|
|
19127
|
+
return;
|
|
19128
|
+
});
|
|
19129
|
+
const installed = installedManifest?.version;
|
|
19130
|
+
return {
|
|
19131
|
+
declared: declarations.get(name) ?? "transitive",
|
|
19132
|
+
...typeof installed === "string" ? { installed } : {},
|
|
19133
|
+
name
|
|
19134
|
+
};
|
|
19135
|
+
}));
|
|
19136
|
+
}, inspectAbsoluteMobileProject = async (config, projectRoot, options = {}) => {
|
|
19137
|
+
const bundle = await inspectBundle(config, projectRoot);
|
|
19138
|
+
let currentCapabilities = [];
|
|
19139
|
+
let capabilityIssue;
|
|
19140
|
+
let plugins = [];
|
|
19141
|
+
try {
|
|
19142
|
+
const plan = resolveAbsoluteDeviceCapabilityPlan(projectRoot);
|
|
19143
|
+
currentCapabilities = plan.capabilities;
|
|
19144
|
+
plugins = plan.requiredPackages;
|
|
19145
|
+
} catch {
|
|
19146
|
+
capabilityIssue = "Native capability metadata could not be resolved.";
|
|
19147
|
+
}
|
|
19148
|
+
const pluginNames = plugins.map((spec) => spec.slice(0, spec.lastIndexOf("@")));
|
|
19149
|
+
const releaseInspection = await (options.inspectRelease ?? inspectAbsoluteMobileRelease)(config, projectRoot).catch(() => ({ checks: [], ready: false }));
|
|
19150
|
+
return {
|
|
19151
|
+
bundle,
|
|
19152
|
+
capabilities: {
|
|
19153
|
+
current: currentCapabilities,
|
|
19154
|
+
...bundle.capabilities ? {
|
|
19155
|
+
embeddedMatchesCurrent: JSON.stringify(bundle.capabilities) === JSON.stringify(currentCapabilities)
|
|
19156
|
+
} : {},
|
|
19157
|
+
...capabilityIssue ? { issue: capabilityIssue } : {},
|
|
19158
|
+
plugins
|
|
19159
|
+
},
|
|
19160
|
+
config: {
|
|
19161
|
+
appId: config.appId,
|
|
19162
|
+
appName: config.appName,
|
|
19163
|
+
bundleDirectory: portablePath(projectRoot, config.bundleDirectory),
|
|
19164
|
+
deepLinkHosts: config.deepLinkHosts,
|
|
19165
|
+
deepLinkScheme: config.deepLinkScheme,
|
|
19166
|
+
engine: config.engine,
|
|
19167
|
+
entry: config.entry,
|
|
19168
|
+
iosVersion: config.iosVersion,
|
|
19169
|
+
nativeProjectDirectory: portablePath(projectRoot, config.nativeProjectDirectory),
|
|
19170
|
+
platforms: config.platforms,
|
|
19171
|
+
productionOrigin: config.productionOrigin
|
|
19172
|
+
},
|
|
19173
|
+
format: ABSOLUTE_MOBILE_INSPECTION_FORMAT,
|
|
19174
|
+
nativeProjects: await Promise.all(config.platforms.map(async (platform6) => {
|
|
19175
|
+
const path = join52(config.nativeProjectDirectory, platform6);
|
|
19176
|
+
return {
|
|
19177
|
+
initialized: await pathExists7(path),
|
|
19178
|
+
path: portablePath(projectRoot, path),
|
|
19179
|
+
platform: platform6
|
|
19180
|
+
};
|
|
19181
|
+
})),
|
|
19182
|
+
packages: await packageInspections(projectRoot, pluginNames),
|
|
19183
|
+
release: {
|
|
19184
|
+
checks: releaseInspection.checks.map(({ id, status: status2 }) => ({
|
|
19185
|
+
id,
|
|
19186
|
+
status: status2
|
|
19187
|
+
})),
|
|
19188
|
+
ready: releaseInspection.ready
|
|
19189
|
+
},
|
|
19190
|
+
runtime: { absolutejs: options.absolutejsVersion ?? "unknown" }
|
|
19191
|
+
};
|
|
19192
|
+
}, yesNo = (value) => value ? "yes" : "no", renderAbsoluteMobileProjectInspection = (report) => {
|
|
19193
|
+
const lines = [
|
|
19194
|
+
`AbsoluteJS mobile inspection (format ${report.format})`,
|
|
19195
|
+
"",
|
|
19196
|
+
`App: ${report.config.appName} (${report.config.appId})`,
|
|
19197
|
+
`Engine: ${report.config.engine}`,
|
|
19198
|
+
`Platforms: ${report.config.platforms.join(", ")}`,
|
|
19199
|
+
`Entry: ${report.config.entry}`,
|
|
19200
|
+
`Production origin: ${report.config.productionOrigin}`,
|
|
19201
|
+
`AbsoluteJS: ${report.runtime.absolutejs}`,
|
|
19202
|
+
"",
|
|
19203
|
+
`Bundle: ${report.bundle.status} (${report.bundle.manifest})`
|
|
19204
|
+
];
|
|
19205
|
+
if (report.bundle.status === "valid") {
|
|
19206
|
+
lines.push(` Build/runtime: ${report.bundle.appBuild} / ${report.bundle.runtime}`, ` Pages/routes: ${report.bundle.pageCount} / ${report.bundle.routeCount}`, ` Frameworks: ${report.bundle.frameworks?.join(", ") || "none"}`, ` Auth/Sync: ${yesNo(report.bundle.auth === true)} / ${yesNo(report.bundle.sync === true)}`);
|
|
19207
|
+
} else if (report.bundle.issue)
|
|
19208
|
+
lines.push(` Issue: ${report.bundle.issue}`);
|
|
19209
|
+
lines.push("", `Capabilities: ${report.capabilities.current.join(", ") || "none"}`, `Native plugins: ${report.capabilities.plugins.join(", ") || "none"}`);
|
|
19210
|
+
if (report.capabilities.embeddedMatchesCurrent !== undefined)
|
|
19211
|
+
lines.push(`Embedded capabilities current: ${yesNo(report.capabilities.embeddedMatchesCurrent)}`);
|
|
19212
|
+
if (report.capabilities.issue)
|
|
19213
|
+
lines.push(`Capability issue: ${report.capabilities.issue}`);
|
|
19214
|
+
lines.push("", "Native projects:");
|
|
19215
|
+
for (const project of report.nativeProjects)
|
|
19216
|
+
lines.push(` ${project.platform}: ${project.initialized ? "initialized" : "missing"} (${project.path})`);
|
|
19217
|
+
lines.push("", "Runtime packages:");
|
|
19218
|
+
for (const runtimePackage of report.packages)
|
|
19219
|
+
lines.push(` ${runtimePackage.name}: ${runtimePackage.installed ?? "not installed"} (declared ${runtimePackage.declared})`);
|
|
19220
|
+
const failed = report.release.checks.filter((check2) => check2.status === "fail").length;
|
|
19221
|
+
const warned = report.release.checks.filter((check2) => check2.status === "warn").length;
|
|
19222
|
+
lines.push("", `Release projection: ${report.release.ready ? "ready" : "not ready"} (${failed} failed, ${warned} warnings)`);
|
|
19223
|
+
return `${lines.join(`
|
|
19224
|
+
`)}
|
|
19225
|
+
`;
|
|
19226
|
+
};
|
|
19227
|
+
var init_mobileInspect = __esm(() => {
|
|
19228
|
+
init_deviceCapabilities();
|
|
19229
|
+
init_releaseDoctor();
|
|
19230
|
+
init_routeMatcher();
|
|
19231
|
+
MOBILE_PACKAGE_NAMES = new Set([
|
|
19232
|
+
"@absolutejs/absolute",
|
|
19233
|
+
"@absolutejs/auth",
|
|
19234
|
+
"@absolutejs/devices",
|
|
19235
|
+
"@absolutejs/devices-capacitor",
|
|
19236
|
+
"@absolutejs/http",
|
|
19237
|
+
"@absolutejs/pwa",
|
|
19238
|
+
"@absolutejs/sync",
|
|
19239
|
+
"@absolutejs/sync-capacitor",
|
|
19240
|
+
"@capacitor-community/sqlite"
|
|
19241
|
+
]);
|
|
19242
|
+
MOBILE_FRAMEWORKS = new Set([
|
|
19243
|
+
"angular",
|
|
19244
|
+
"ember",
|
|
19245
|
+
"html",
|
|
19246
|
+
"htmx",
|
|
19247
|
+
"react",
|
|
19248
|
+
"svelte",
|
|
19249
|
+
"vue"
|
|
19250
|
+
]);
|
|
19251
|
+
});
|
|
19252
|
+
|
|
18996
19253
|
// src/cli/scripts/mobile.ts
|
|
18997
19254
|
var exports_mobile = {};
|
|
18998
19255
|
__export(exports_mobile, {
|
|
18999
19256
|
runMobile: () => runMobile
|
|
19000
19257
|
});
|
|
19001
|
-
import { access as
|
|
19002
|
-
import { join as
|
|
19258
|
+
import { access as access12, mkdir as mkdir14, readFile as readFile21, writeFile as writeFile16 } from "fs/promises";
|
|
19259
|
+
import { join as join53, resolve as resolve42 } from "path";
|
|
19003
19260
|
import { createInterface } from "readline/promises";
|
|
19004
19261
|
var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), CAPACITOR_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, packageNameFromSpec = (spec) => spec.slice(0, spec.lastIndexOf("@")), directProjectPackages = async (projectRoot) => {
|
|
19005
|
-
const manifest = JSON.parse(await
|
|
19262
|
+
const manifest = JSON.parse(await readFile21(join53(projectRoot, "package.json"), "utf8"));
|
|
19006
19263
|
if (!isRecord15(manifest))
|
|
19007
19264
|
throw new TypeError("Application package.json must contain an object.");
|
|
19008
19265
|
const names = new Set;
|
|
@@ -19015,7 +19272,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19015
19272
|
return names;
|
|
19016
19273
|
}, resolvedPackageVersion = async (projectRoot, packageName) => {
|
|
19017
19274
|
try {
|
|
19018
|
-
const manifest = JSON.parse(await
|
|
19275
|
+
const manifest = JSON.parse(await readFile21(join53(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
|
|
19019
19276
|
return isRecord15(manifest) && typeof manifest.version === "string" ? manifest.version : undefined;
|
|
19020
19277
|
} catch {
|
|
19021
19278
|
return;
|
|
@@ -19056,9 +19313,9 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19056
19313
|
}
|
|
19057
19314
|
return value;
|
|
19058
19315
|
}, capacitorExecutable = async (projectRoot) => {
|
|
19059
|
-
const executable =
|
|
19316
|
+
const executable = join53(projectRoot, "node_modules", ".bin", "cap");
|
|
19060
19317
|
try {
|
|
19061
|
-
await
|
|
19318
|
+
await access12(executable);
|
|
19062
19319
|
return executable;
|
|
19063
19320
|
} catch {
|
|
19064
19321
|
throw new TypeError(`Capacitor is not installed in this app. Run: bun add ${CAPACITOR_PACKAGES.join(" ")}`);
|
|
@@ -19080,6 +19337,17 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19080
19337
|
const config = await loadConfig(configPath2);
|
|
19081
19338
|
const mobile = normalizeAbsoluteMobileConfig(requireMobileConfig(config.mobile), projectRoot);
|
|
19082
19339
|
return { mobile, projectRoot };
|
|
19340
|
+
}, inspectMobile = async (args) => {
|
|
19341
|
+
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
19342
|
+
const report = await inspectAbsoluteMobileProject(mobile, projectRoot, {
|
|
19343
|
+
absolutejsVersion: await absolutejsVersionForReport()
|
|
19344
|
+
});
|
|
19345
|
+
if (args.includes("--json")) {
|
|
19346
|
+
console.log(JSON.stringify(report, null, 2));
|
|
19347
|
+
return report;
|
|
19348
|
+
}
|
|
19349
|
+
console.log(renderAbsoluteMobileProjectInspection(report).trimEnd());
|
|
19350
|
+
return report;
|
|
19083
19351
|
}, remoteProfilePath = () => process.env.ABSOLUTE_REMOTE_MAC_PROFILE_PATH || undefined, pairRemoteMac = async (args) => {
|
|
19084
19352
|
if (args[0] !== "mac" || !args[1] || !args[2])
|
|
19085
19353
|
throw new TypeError("Usage: absolute mobile pair mac <name> <user@host> [--port n] [--workspace path]");
|
|
@@ -19144,7 +19412,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19144
19412
|
await applyAbsoluteNativeBackgroundSync(projectRoot, mobile, platforms);
|
|
19145
19413
|
}, associations = async (args) => {
|
|
19146
19414
|
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
19147
|
-
const outputDirectory =
|
|
19415
|
+
const outputDirectory = resolve42(projectRoot, valueAfter(args, "--outdir") ?? ".absolutejs/mobile/associations");
|
|
19148
19416
|
if (args.includes("--verify")) {
|
|
19149
19417
|
const result2 = await verifyAbsoluteMobileAssociationFiles(mobile);
|
|
19150
19418
|
console.log(`Verified ${result2.results.length} hosted association files`);
|
|
@@ -19377,7 +19645,7 @@ Mobile release transport checks failed.`);
|
|
|
19377
19645
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
19378
19646
|
console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} Android App Bundle in ${getDurationString(durationMs)}.`);
|
|
19379
19647
|
console.log(`Artifact: ${release.artifactPath}`);
|
|
19380
|
-
console.log(`Metadata: ${
|
|
19648
|
+
console.log(`Metadata: ${join53(release.releaseRoot, "release.json")}`);
|
|
19381
19649
|
return release;
|
|
19382
19650
|
} finally {
|
|
19383
19651
|
sendTelemetryEvent("mobile:android-release-build", {
|
|
@@ -19480,7 +19748,7 @@ Mobile release transport checks failed.`);
|
|
|
19480
19748
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
19481
19749
|
console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} iOS IPA ${release.metadata.marketingVersion}${release.metadata.buildNumber ? ` (${release.metadata.buildNumber})` : ""} in ${getDurationString(durationMs)}.`);
|
|
19482
19750
|
console.log(`Artifact: ${release.artifactPath}`);
|
|
19483
|
-
console.log(`Metadata: ${
|
|
19751
|
+
console.log(`Metadata: ${join53(release.releaseRoot, "release.json")}`);
|
|
19484
19752
|
return release;
|
|
19485
19753
|
} finally {
|
|
19486
19754
|
sendTelemetryEvent("mobile:ios-release-build", {
|
|
@@ -19587,7 +19855,7 @@ Mobile release transport checks failed.`);
|
|
|
19587
19855
|
checks.push({
|
|
19588
19856
|
id: "sync.storage-schema",
|
|
19589
19857
|
label: `Offline schema ${schema.components.map((component2) => `${component2.id}@${component2.version}`).join(", ")}`,
|
|
19590
|
-
path:
|
|
19858
|
+
path: join53(projectRoot, "package.json"),
|
|
19591
19859
|
platform: "host",
|
|
19592
19860
|
status: "pass"
|
|
19593
19861
|
});
|
|
@@ -19595,7 +19863,7 @@ Mobile release transport checks failed.`);
|
|
|
19595
19863
|
checks.push({
|
|
19596
19864
|
id: "sync.storage-schema",
|
|
19597
19865
|
label: "Offline schema metadata is invalid",
|
|
19598
|
-
path:
|
|
19866
|
+
path: join53(projectRoot, "package.json"),
|
|
19599
19867
|
platform: "host",
|
|
19600
19868
|
remediation: error instanceof Error ? error.message : String(error),
|
|
19601
19869
|
status: "fail"
|
|
@@ -19680,7 +19948,7 @@ Emulator setup verification:`);
|
|
|
19680
19948
|
}
|
|
19681
19949
|
return { https: args.includes("--https"), port };
|
|
19682
19950
|
}
|
|
19683
|
-
const instances = listLiveInstances().filter((instance2) =>
|
|
19951
|
+
const instances = listLiveInstances().filter((instance2) => resolve42(instance2.cwd) === resolve42(projectRoot) && instance2.source === "dev" && instance2.port !== null);
|
|
19684
19952
|
if (instances.length !== 1) {
|
|
19685
19953
|
throw new TypeError(instances.length === 0 ? "No running AbsoluteJS dev server was found for this project. Start `bun dev`, wait for Android to report ready, then run `absolute mobile test android`." : "Multiple dev servers are running for this project. Select one with mobile test android --port <port>.");
|
|
19686
19954
|
}
|
|
@@ -19723,8 +19991,8 @@ Emulator setup verification:`);
|
|
|
19723
19991
|
}
|
|
19724
19992
|
return selected;
|
|
19725
19993
|
}, safeArtifactRoot = (projectRoot, value) => {
|
|
19726
|
-
const root =
|
|
19727
|
-
if (root !== projectRoot && !root.startsWith(`${
|
|
19994
|
+
const root = resolve42(projectRoot, value ?? ".absolutejs/mobile/test-artifacts");
|
|
19995
|
+
if (root !== projectRoot && !root.startsWith(`${resolve42(projectRoot)}/`)) {
|
|
19728
19996
|
throw new TypeError("mobile test --artifacts must remain inside the project.");
|
|
19729
19997
|
}
|
|
19730
19998
|
return root;
|
|
@@ -19749,10 +20017,10 @@ Emulator setup verification:`);
|
|
|
19749
20017
|
});
|
|
19750
20018
|
}, writeAndroidFailureArtifacts = async (options) => {
|
|
19751
20019
|
await mkdir14(options.artifactRoot, { recursive: true });
|
|
19752
|
-
const screenshot = options.session ? await options.session.screenshot(
|
|
20020
|
+
const screenshot = options.session ? await options.session.screenshot(join53(options.artifactRoot, "android-failure.png")).catch(() => {
|
|
19753
20021
|
return;
|
|
19754
20022
|
}) : undefined;
|
|
19755
|
-
const diagnosticPath =
|
|
20023
|
+
const diagnosticPath = join53(options.artifactRoot, "android-failure.json");
|
|
19756
20024
|
await writeFile16(diagnosticPath, `${JSON.stringify({
|
|
19757
20025
|
diagnostics: options.session?.diagnostics ?? [],
|
|
19758
20026
|
error: options.error instanceof Error ? options.error.message : String(options.error),
|
|
@@ -19816,7 +20084,7 @@ Emulator setup verification:`);
|
|
|
19816
20084
|
console.log(JSON.stringify(report, null, 2));
|
|
19817
20085
|
else
|
|
19818
20086
|
printAndroidTestReport(report);
|
|
19819
|
-
const screenshot = reportRoot ? await session.screenshot(
|
|
20087
|
+
const screenshot = reportRoot ? await session.screenshot(join53(artifactRoot, "android-emulator.png")) : undefined;
|
|
19820
20088
|
await writeRequestedAndroidReport({
|
|
19821
20089
|
adb,
|
|
19822
20090
|
args,
|
|
@@ -19884,14 +20152,14 @@ Emulator setup verification:`);
|
|
|
19884
20152
|
const port = Number(explicit);
|
|
19885
20153
|
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
19886
20154
|
throw new TypeError("mobile test --port must be a valid TCP port.");
|
|
19887
|
-
const instance2 = listLiveInstances().find((candidate) =>
|
|
20155
|
+
const instance2 = listLiveInstances().find((candidate) => resolve42(candidate.cwd) === resolve42(projectRoot) && candidate.source === "dev" && candidate.port === port);
|
|
19888
20156
|
return {
|
|
19889
20157
|
https: instance2?.https ?? args.includes("--https"),
|
|
19890
20158
|
instance: instance2,
|
|
19891
20159
|
port
|
|
19892
20160
|
};
|
|
19893
20161
|
}
|
|
19894
|
-
const instances = listLiveInstances().filter((instance2) =>
|
|
20162
|
+
const instances = listLiveInstances().filter((instance2) => resolve42(instance2.cwd) === resolve42(projectRoot) && instance2.source === "dev" && instance2.port !== null);
|
|
19895
20163
|
if (instances.length !== 1)
|
|
19896
20164
|
throw new TypeError(instances.length === 0 ? "No running AbsoluteJS dev server was found for this project. Start `bun dev`, wait for iOS to report ready, then run `absolute mobile test ios`." : "Multiple dev servers are running for this project. Select one with mobile test ios --port <port>.");
|
|
19897
20165
|
const [instance] = instances;
|
|
@@ -20006,7 +20274,7 @@ Emulator setup verification:`);
|
|
|
20006
20274
|
return result;
|
|
20007
20275
|
}, writeIosFailureArtifacts = async (options) => {
|
|
20008
20276
|
await mkdir14(options.artifactRoot, { recursive: true });
|
|
20009
|
-
const screenshot =
|
|
20277
|
+
const screenshot = join53(options.artifactRoot, "ios-failure.png");
|
|
20010
20278
|
const screenshotResult = captureCommand4([
|
|
20011
20279
|
options.xcrun,
|
|
20012
20280
|
"simctl",
|
|
@@ -20015,7 +20283,7 @@ Emulator setup verification:`);
|
|
|
20015
20283
|
"screenshot",
|
|
20016
20284
|
screenshot
|
|
20017
20285
|
]);
|
|
20018
|
-
const diagnosticPath =
|
|
20286
|
+
const diagnosticPath = join53(options.artifactRoot, "ios-failure.json");
|
|
20019
20287
|
await writeFile16(diagnosticPath, `${JSON.stringify({
|
|
20020
20288
|
appId: options.appId,
|
|
20021
20289
|
error: options.error instanceof Error ? options.error.message : String(options.error),
|
|
@@ -20041,8 +20309,8 @@ Emulator setup verification:`);
|
|
|
20041
20309
|
}, absolutejsVersionForReport = async () => {
|
|
20042
20310
|
let absolutejsVersion = process.env.ABSOLUTE_VERSION ?? "unknown";
|
|
20043
20311
|
const versions = await Promise.all([
|
|
20044
|
-
|
|
20045
|
-
|
|
20312
|
+
resolve42(import.meta.dir, "..", "..", "package.json"),
|
|
20313
|
+
resolve42(import.meta.dir, "..", "..", "..", "package.json")
|
|
20046
20314
|
].map((candidate) => readPackageVersionForIosReport(candidate).catch(() => "unknown")));
|
|
20047
20315
|
for (const version2 of versions) {
|
|
20048
20316
|
if (version2 === "unknown")
|
|
@@ -20261,7 +20529,7 @@ Emulator setup verification:`);
|
|
|
20261
20529
|
], "iOS app launch");
|
|
20262
20530
|
await waitForIosHmrClient({ https, port, timeoutMs });
|
|
20263
20531
|
await mkdir14(artifactRoot, { recursive: true });
|
|
20264
|
-
const screenshot =
|
|
20532
|
+
const screenshot = join53(artifactRoot, "ios-simulator.png");
|
|
20265
20533
|
requireCapturedCommand([xcrun, "simctl", "io", simulator.udid, "screenshot", screenshot], "iOS simulator screenshot");
|
|
20266
20534
|
const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
|
|
20267
20535
|
const report = {
|
|
@@ -20374,6 +20642,10 @@ Emulator setup verification:`);
|
|
|
20374
20642
|
await doctor(args.slice(1));
|
|
20375
20643
|
return;
|
|
20376
20644
|
}
|
|
20645
|
+
if (command === "inspect") {
|
|
20646
|
+
await inspectMobile(args.slice(1));
|
|
20647
|
+
return;
|
|
20648
|
+
}
|
|
20377
20649
|
if (command === "test" && args[1] === "android") {
|
|
20378
20650
|
await testAndroid(args.slice(2));
|
|
20379
20651
|
return;
|
|
@@ -20398,7 +20670,7 @@ Emulator setup verification:`);
|
|
|
20398
20670
|
await publishIos(args.slice(2));
|
|
20399
20671
|
return;
|
|
20400
20672
|
}
|
|
20401
|
-
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
20673
|
+
throw new TypeError("Usage: absolute mobile <pair mac <name> <user@host> [--port n] [--workspace path] | remotes [--json] | unpair mac <name> | init [--no-native] [--force] | sync [ios|android] | inspect [--json] | associations [--outdir dir] [--verify] | doctor [ios|android|release] [--remote name] [--json|--fix [--yes]] | build <android|ios> [server-entry] [--outdir dir] [--web-outdir dir] [--unsigned] | publish android [server-entry] [--registry module] [--channel name] [--play-track track] [--play-status completed|draft|halted|in-progress] [--play-rollout fraction] [--play-name name] [--play-notes language=text] [--play-update-priority 0..5] [--play-hold-review] [--play-cancel-existing-review] [--outdir dir] [--web-outdir dir] [--unsigned] | publish ios [server-entry] [--registry module] [--channel name] [--testflight-group name-or-id] [--testflight-notes locale=text] [--testflight-submit-review] [--outdir dir] [--web-outdir dir] [--unsigned] | test android [--route path] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--serial id] [--artifacts dir] [--json] | test ios [--device identifier [--remote name] | --udid id] [--wait-for-hmr] [--report [dir]] [--timeout ms] [--port n] [--artifacts dir] [--json]> [--config path]");
|
|
20402
20674
|
};
|
|
20403
20675
|
var init_mobile = __esm(() => {
|
|
20404
20676
|
init_dependencies();
|
|
@@ -20432,6 +20704,7 @@ var init_mobile = __esm(() => {
|
|
|
20432
20704
|
init_nativeAuth();
|
|
20433
20705
|
init_syncSchema();
|
|
20434
20706
|
init_deviceCapabilities();
|
|
20707
|
+
init_mobileInspect();
|
|
20435
20708
|
CAPACITOR_PACKAGES = [
|
|
20436
20709
|
"@capacitor/core",
|
|
20437
20710
|
"@capacitor/app",
|
|
@@ -20467,10 +20740,10 @@ var exports_typecheck = {};
|
|
|
20467
20740
|
__export(exports_typecheck, {
|
|
20468
20741
|
typecheck: () => typecheck
|
|
20469
20742
|
});
|
|
20470
|
-
import { resolve as
|
|
20743
|
+
import { resolve as resolve43, join as join54 } from "path";
|
|
20471
20744
|
import { existsSync as existsSync42, readFileSync as readFileSync40 } from "fs";
|
|
20472
20745
|
import { mkdir as mkdir15, writeFile as writeFile17 } from "fs/promises";
|
|
20473
|
-
var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) =>
|
|
20746
|
+
var isCommandService3 = (service) => service.kind === "command" || Array.isArray(service.command), resolveConfigPath = (configPath2) => resolve43(configPath2 ?? process.env.ABSOLUTE_CONFIG ?? "absolute.config.ts"), getTypecheckTargets = async (configPath2) => {
|
|
20474
20747
|
if (!existsSync42(resolveConfigPath(configPath2))) {
|
|
20475
20748
|
const defaultService = {};
|
|
20476
20749
|
return [defaultService];
|
|
@@ -20492,7 +20765,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
20492
20765
|
const exitCode = await proc.exited;
|
|
20493
20766
|
return { exitCode, name, output: (stdout + stderr).trim() };
|
|
20494
20767
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
20495
|
-
const local =
|
|
20768
|
+
const local = resolve43("node_modules", ".bin", name);
|
|
20496
20769
|
return existsSync42(local) ? local : null;
|
|
20497
20770
|
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi4 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
20498
20771
|
const cwd = `${process.cwd()}/`;
|
|
@@ -20540,15 +20813,15 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20540
20813
|
return formatted;
|
|
20541
20814
|
}, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
|
|
20542
20815
|
const candidates = [
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
|
|
20546
|
-
|
|
20816
|
+
resolve43("node_modules/@absolutejs/absolute/dist/types", fileName),
|
|
20817
|
+
resolve43(import.meta.dir, "../types", fileName),
|
|
20818
|
+
resolve43(import.meta.dir, "../../types", fileName),
|
|
20819
|
+
resolve43(import.meta.dir, "../../../types", fileName)
|
|
20547
20820
|
];
|
|
20548
20821
|
return candidates.find((candidate) => existsSync42(candidate)) ?? candidates[0];
|
|
20549
20822
|
}, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
|
|
20550
20823
|
try {
|
|
20551
|
-
return JSON.parse(readFileSync40(
|
|
20824
|
+
return JSON.parse(readFileSync40(resolve43("tsconfig.json"), "utf-8"));
|
|
20552
20825
|
} catch {
|
|
20553
20826
|
return {};
|
|
20554
20827
|
}
|
|
@@ -20576,27 +20849,27 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20576
20849
|
console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
|
|
20577
20850
|
process.exit(1);
|
|
20578
20851
|
}
|
|
20579
|
-
const vueTsconfigPath =
|
|
20852
|
+
const vueTsconfigPath = join54(cacheDir, "tsconfig.vue-check.json");
|
|
20580
20853
|
await writeFile17(vueTsconfigPath, JSON.stringify({
|
|
20581
20854
|
compilerOptions: {
|
|
20582
20855
|
rootDir: ".."
|
|
20583
20856
|
},
|
|
20584
20857
|
exclude: getProjectTypecheckExcludes(),
|
|
20585
|
-
extends:
|
|
20858
|
+
extends: resolve43("tsconfig.json"),
|
|
20586
20859
|
include: getProjectTypecheckIncludes()
|
|
20587
20860
|
}, null, "\t"));
|
|
20588
20861
|
const base = [
|
|
20589
20862
|
vueTscBin,
|
|
20590
20863
|
"--noEmit",
|
|
20591
20864
|
"--project",
|
|
20592
|
-
|
|
20865
|
+
resolve43(vueTsconfigPath),
|
|
20593
20866
|
"--pretty"
|
|
20594
20867
|
];
|
|
20595
20868
|
const cached = await run("vue-tsc", [
|
|
20596
20869
|
...base,
|
|
20597
20870
|
"--incremental",
|
|
20598
20871
|
"--tsBuildInfoFile",
|
|
20599
|
-
|
|
20872
|
+
join54(cacheDir, "vue-tsc.tsbuildinfo")
|
|
20600
20873
|
]);
|
|
20601
20874
|
if (cached.exitCode === 0 || cached.output.length > 0)
|
|
20602
20875
|
return cached;
|
|
@@ -20607,7 +20880,7 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20607
20880
|
console.error("\x1B[31m\u2717\x1B[0m @angular/compiler-cli is required for Angular type checking. Install it: bun add -d @angular/compiler-cli");
|
|
20608
20881
|
process.exit(1);
|
|
20609
20882
|
}
|
|
20610
|
-
const angularTsconfigPath =
|
|
20883
|
+
const angularTsconfigPath = join54(cacheDir, "tsconfig.angular-check.json");
|
|
20611
20884
|
await writeFile17(angularTsconfigPath, JSON.stringify({
|
|
20612
20885
|
angularCompilerOptions: {
|
|
20613
20886
|
strictTemplates: true
|
|
@@ -20617,32 +20890,32 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20617
20890
|
rootDir: ".."
|
|
20618
20891
|
},
|
|
20619
20892
|
exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
|
|
20620
|
-
extends:
|
|
20893
|
+
extends: resolve43("tsconfig.json"),
|
|
20621
20894
|
include: [`../${angularDir}/**/*`]
|
|
20622
20895
|
}, null, "\t"));
|
|
20623
|
-
return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(
|
|
20896
|
+
return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve43(angularTsconfigPath))}`);
|
|
20624
20897
|
}, buildTscCheck = (cacheDir) => {
|
|
20625
20898
|
const tscBin = findBin("tsc");
|
|
20626
20899
|
if (!tscBin) {
|
|
20627
20900
|
console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
|
|
20628
20901
|
process.exit(1);
|
|
20629
20902
|
}
|
|
20630
|
-
const tscConfigPath =
|
|
20903
|
+
const tscConfigPath = join54(cacheDir, "tsconfig.typecheck.json");
|
|
20631
20904
|
return writeFile17(tscConfigPath, JSON.stringify({
|
|
20632
20905
|
compilerOptions: {
|
|
20633
20906
|
rootDir: ".."
|
|
20634
20907
|
},
|
|
20635
20908
|
exclude: getProjectTypecheckExcludes(),
|
|
20636
|
-
extends:
|
|
20909
|
+
extends: resolve43("tsconfig.json"),
|
|
20637
20910
|
include: getProjectTypecheckIncludes()
|
|
20638
20911
|
}, null, "\t")).then(() => run("tsc", [
|
|
20639
20912
|
tscBin,
|
|
20640
20913
|
"--noEmit",
|
|
20641
20914
|
"--project",
|
|
20642
|
-
|
|
20915
|
+
resolve43(tscConfigPath),
|
|
20643
20916
|
"--incremental",
|
|
20644
20917
|
"--tsBuildInfoFile",
|
|
20645
|
-
|
|
20918
|
+
join54(cacheDir, "tsc.tsbuildinfo"),
|
|
20646
20919
|
"--pretty"
|
|
20647
20920
|
]));
|
|
20648
20921
|
}, buildSvelteCheck = async (cacheDir, svelteDir) => {
|
|
@@ -20651,16 +20924,16 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20651
20924
|
console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
|
|
20652
20925
|
process.exit(1);
|
|
20653
20926
|
}
|
|
20654
|
-
const svelteTsconfigPath =
|
|
20927
|
+
const svelteTsconfigPath = join54(cacheDir, "tsconfig.svelte-check.json");
|
|
20655
20928
|
await writeFile17(svelteTsconfigPath, JSON.stringify({
|
|
20656
|
-
extends:
|
|
20929
|
+
extends: resolve43("tsconfig.json"),
|
|
20657
20930
|
files: ABSOLUTE_TYPECHECK_FILES,
|
|
20658
20931
|
include: [`../${svelteDir}/**/*`]
|
|
20659
20932
|
}, null, "\t"));
|
|
20660
20933
|
return run("svelte-check", [
|
|
20661
20934
|
svelteBin,
|
|
20662
20935
|
"--tsconfig",
|
|
20663
|
-
|
|
20936
|
+
resolve43(svelteTsconfigPath),
|
|
20664
20937
|
"--threshold",
|
|
20665
20938
|
"error",
|
|
20666
20939
|
"--compiler-warnings",
|
|
@@ -20854,11 +21127,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
|
|
|
20854
21127
|
url: url.pathname + url.search,
|
|
20855
21128
|
...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
|
|
20856
21129
|
};
|
|
20857
|
-
const responsePromise = new Promise((
|
|
20858
|
-
pending.set(id,
|
|
21130
|
+
const responsePromise = new Promise((resolve44) => {
|
|
21131
|
+
pending.set(id, resolve44);
|
|
20859
21132
|
});
|
|
20860
21133
|
client.send(encodeTunnelMessage(message));
|
|
20861
|
-
const timeout = new Promise((
|
|
21134
|
+
const timeout = new Promise((resolve44) => setTimeout(() => resolve44({ id, message: "timeout", type: "error" }), requestTimeoutMs));
|
|
20862
21135
|
const result = await Promise.race([responsePromise, timeout]);
|
|
20863
21136
|
pending.delete(id);
|
|
20864
21137
|
if (result.type === "error") {
|
|
@@ -22469,6 +22742,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
22469
22742
|
const serverEntryBasename = absServerEntry.slice(absServerEntry.lastIndexOf("/") + 1);
|
|
22470
22743
|
const configBasename = configPath2 ? configPath2.slice(configPath2.lastIndexOf("/") + 1) : "absolute.config.ts";
|
|
22471
22744
|
const ATOMIC_RECOVERY_WINDOW_MS = 1000;
|
|
22745
|
+
const ATOMIC_RECOVERY_DELAY_MS = 25;
|
|
22472
22746
|
const recentlyHandled = new Map;
|
|
22473
22747
|
const handleCandidate = (filename) => {
|
|
22474
22748
|
if (filename.includes("/") || filename.includes("\\"))
|
|
@@ -22512,18 +22786,28 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
22512
22786
|
handleCandidate(entry.name);
|
|
22513
22787
|
}
|
|
22514
22788
|
};
|
|
22789
|
+
let atomicRecoveryTimer;
|
|
22790
|
+
const scheduleAtomicRecovery = () => {
|
|
22791
|
+
if (atomicRecoveryTimer)
|
|
22792
|
+
clearTimeout(atomicRecoveryTimer);
|
|
22793
|
+
atomicRecoveryTimer = setTimeout(() => {
|
|
22794
|
+
atomicRecoveryTimer = undefined;
|
|
22795
|
+
recoveryScan();
|
|
22796
|
+
}, ATOMIC_RECOVERY_DELAY_MS);
|
|
22797
|
+
};
|
|
22515
22798
|
const watcher = watch3(serverEntryDir, { recursive: false }, (event, filename) => {
|
|
22516
22799
|
if (!filename)
|
|
22517
22800
|
return;
|
|
22518
22801
|
if (isAtomicWriteTemp(filename)) {
|
|
22519
|
-
if (event === "rename")
|
|
22520
|
-
|
|
22521
|
-
}
|
|
22802
|
+
if (event === "rename")
|
|
22803
|
+
scheduleAtomicRecovery();
|
|
22522
22804
|
return;
|
|
22523
22805
|
}
|
|
22524
22806
|
handleCandidate(filename);
|
|
22525
22807
|
});
|
|
22526
22808
|
const closeWatcher = () => {
|
|
22809
|
+
if (atomicRecoveryTimer)
|
|
22810
|
+
clearTimeout(atomicRecoveryTimer);
|
|
22527
22811
|
try {
|
|
22528
22812
|
watcher.close();
|
|
22529
22813
|
} catch {}
|
|
@@ -24760,7 +25044,7 @@ if (command === "dev") {
|
|
|
24760
25044
|
console.error(" prepare [entry] [--outdir dir] Build production assets and server without launching");
|
|
24761
25045
|
console.error(" start [entry] [--outdir dir] [--prebuilt] Start production server");
|
|
24762
25046
|
console.error(" compile [entry] [--outdir dir] [--outfile path] Compile standalone executable");
|
|
24763
|
-
console.error(" mobile <init|sync|pair|remotes|doctor|test> Manage Capacitor projects, simulators, physical devices, Remote Macs, guided setup, and deep links");
|
|
25047
|
+
console.error(" mobile <init|sync|inspect|pair|remotes|doctor|test> Manage Capacitor projects, simulators, physical devices, Remote Macs, guided setup, and deep links");
|
|
24764
25048
|
console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
|
|
24765
25049
|
console.error(" db <backup|restore|seed> Backup/restore any Postgres DB (ORM-agnostic, upsert by PK) or run the seed script");
|
|
24766
25050
|
console.error(" doctor [--fix] [--json] Diagnose the project (bun, type graph, config, framework dirs, env, port)");
|