@absolutejs/absolute 0.20.0-beta.36 → 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 +335 -54
- package/dist/dev/serverBootstrap.js +28 -0
- package/dist/src/dev/serverEntryCopies.d.ts +3 -0
- package/dist/src/mobile/mobileInspect.d.ts +110 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -254,6 +254,13 @@ edit Swift/Kotlin, or maintain native bootstrap code. Type-only imports and test
|
|
|
254
254
|
sources do not provision plugins. `absolute mobile doctor release` rejects a
|
|
255
255
|
missing or mismatched plugin before release.
|
|
256
256
|
|
|
257
|
+
Run `absolute mobile inspect` from an application root for a read-only summary
|
|
258
|
+
of the effective mobile config, runtime package versions, discovered
|
|
259
|
+
capabilities/plugins, native-project state, embedded routes/frameworks, bundle
|
|
260
|
+
validation, and release projection. Add `--json` for a redacted CI or support
|
|
261
|
+
artifact; it omits credentials, device/account identifiers, absolute paths, and
|
|
262
|
+
detailed doctor messages. See [mobile project inspection](docs/MOBILE_INSPECT.md).
|
|
263
|
+
|
|
257
264
|
`keyboard` provides portable visibility, CSS-pixel height, dismissal, and
|
|
258
265
|
cleanup-safe change events. `systemBars` controls modern edge-to-edge status and
|
|
259
266
|
navigation bar foreground appearance/visibility through Capacitor 8 core. Its
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-6Q6jJy/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
var __require = import.meta.require;
|
|
3
3
|
|
|
4
|
-
// .angular-partial-tmp-
|
|
4
|
+
// .angular-partial-tmp-6Q6jJy/src/core/streamingSlotRegistrar.ts
|
|
5
5
|
var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
|
|
6
6
|
var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
|
|
7
7
|
var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
|
|
@@ -48,7 +48,7 @@ var warnMissingStreamingSlotCollector = (primitiveName) => {
|
|
|
48
48
|
getWarningController()?.maybeWarn(primitiveName);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
// .angular-partial-tmp-
|
|
51
|
+
// .angular-partial-tmp-6Q6jJy/src/core/streamingSlotRegistry.ts
|
|
52
52
|
var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
|
|
53
53
|
var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
|
|
54
54
|
var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
|
package/dist/cli/index.js
CHANGED
|
@@ -18996,16 +18996,270 @@ var prepareAbsoluteIosRelease = async (publisher, options) => {
|
|
|
18996
18996
|
};
|
|
18997
18997
|
var init_releasePublisher = () => {};
|
|
18998
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
|
+
|
|
18999
19253
|
// src/cli/scripts/mobile.ts
|
|
19000
19254
|
var exports_mobile = {};
|
|
19001
19255
|
__export(exports_mobile, {
|
|
19002
19256
|
runMobile: () => runMobile
|
|
19003
19257
|
});
|
|
19004
|
-
import { access as
|
|
19005
|
-
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";
|
|
19006
19260
|
import { createInterface } from "readline/promises";
|
|
19007
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) => {
|
|
19008
|
-
const manifest = JSON.parse(await
|
|
19262
|
+
const manifest = JSON.parse(await readFile21(join53(projectRoot, "package.json"), "utf8"));
|
|
19009
19263
|
if (!isRecord15(manifest))
|
|
19010
19264
|
throw new TypeError("Application package.json must contain an object.");
|
|
19011
19265
|
const names = new Set;
|
|
@@ -19018,7 +19272,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19018
19272
|
return names;
|
|
19019
19273
|
}, resolvedPackageVersion = async (projectRoot, packageName) => {
|
|
19020
19274
|
try {
|
|
19021
|
-
const manifest = JSON.parse(await
|
|
19275
|
+
const manifest = JSON.parse(await readFile21(join53(projectRoot, "node_modules", packageName, "package.json"), "utf8"));
|
|
19022
19276
|
return isRecord15(manifest) && typeof manifest.version === "string" ? manifest.version : undefined;
|
|
19023
19277
|
} catch {
|
|
19024
19278
|
return;
|
|
@@ -19059,9 +19313,9 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19059
19313
|
}
|
|
19060
19314
|
return value;
|
|
19061
19315
|
}, capacitorExecutable = async (projectRoot) => {
|
|
19062
|
-
const executable =
|
|
19316
|
+
const executable = join53(projectRoot, "node_modules", ".bin", "cap");
|
|
19063
19317
|
try {
|
|
19064
|
-
await
|
|
19318
|
+
await access12(executable);
|
|
19065
19319
|
return executable;
|
|
19066
19320
|
} catch {
|
|
19067
19321
|
throw new TypeError(`Capacitor is not installed in this app. Run: bun add ${CAPACITOR_PACKAGES.join(" ")}`);
|
|
@@ -19083,6 +19337,17 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19083
19337
|
const config = await loadConfig(configPath2);
|
|
19084
19338
|
const mobile = normalizeAbsoluteMobileConfig(requireMobileConfig(config.mobile), projectRoot);
|
|
19085
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;
|
|
19086
19351
|
}, remoteProfilePath = () => process.env.ABSOLUTE_REMOTE_MAC_PROFILE_PATH || undefined, pairRemoteMac = async (args) => {
|
|
19087
19352
|
if (args[0] !== "mac" || !args[1] || !args[2])
|
|
19088
19353
|
throw new TypeError("Usage: absolute mobile pair mac <name> <user@host> [--port n] [--workspace path]");
|
|
@@ -19147,7 +19412,7 @@ var NOT_FOUND3 = -1, isRecord15 = (value) => typeof value === "object" && value
|
|
|
19147
19412
|
await applyAbsoluteNativeBackgroundSync(projectRoot, mobile, platforms);
|
|
19148
19413
|
}, associations = async (args) => {
|
|
19149
19414
|
const { mobile, projectRoot } = await loadMobile(valueAfter(args, "--config"));
|
|
19150
|
-
const outputDirectory =
|
|
19415
|
+
const outputDirectory = resolve42(projectRoot, valueAfter(args, "--outdir") ?? ".absolutejs/mobile/associations");
|
|
19151
19416
|
if (args.includes("--verify")) {
|
|
19152
19417
|
const result2 = await verifyAbsoluteMobileAssociationFiles(mobile);
|
|
19153
19418
|
console.log(`Verified ${result2.results.length} hosted association files`);
|
|
@@ -19380,7 +19645,7 @@ Mobile release transport checks failed.`);
|
|
|
19380
19645
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
19381
19646
|
console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} Android App Bundle in ${getDurationString(durationMs)}.`);
|
|
19382
19647
|
console.log(`Artifact: ${release.artifactPath}`);
|
|
19383
|
-
console.log(`Metadata: ${
|
|
19648
|
+
console.log(`Metadata: ${join53(release.releaseRoot, "release.json")}`);
|
|
19384
19649
|
return release;
|
|
19385
19650
|
} finally {
|
|
19386
19651
|
sendTelemetryEvent("mobile:android-release-build", {
|
|
@@ -19483,7 +19748,7 @@ Mobile release transport checks failed.`);
|
|
|
19483
19748
|
const durationMs = Math.round(performance.now() - startedAt);
|
|
19484
19749
|
console.log(`Built ${release.metadata.signed ? "signed" : "unsigned"} iOS IPA ${release.metadata.marketingVersion}${release.metadata.buildNumber ? ` (${release.metadata.buildNumber})` : ""} in ${getDurationString(durationMs)}.`);
|
|
19485
19750
|
console.log(`Artifact: ${release.artifactPath}`);
|
|
19486
|
-
console.log(`Metadata: ${
|
|
19751
|
+
console.log(`Metadata: ${join53(release.releaseRoot, "release.json")}`);
|
|
19487
19752
|
return release;
|
|
19488
19753
|
} finally {
|
|
19489
19754
|
sendTelemetryEvent("mobile:ios-release-build", {
|
|
@@ -19590,7 +19855,7 @@ Mobile release transport checks failed.`);
|
|
|
19590
19855
|
checks.push({
|
|
19591
19856
|
id: "sync.storage-schema",
|
|
19592
19857
|
label: `Offline schema ${schema.components.map((component2) => `${component2.id}@${component2.version}`).join(", ")}`,
|
|
19593
|
-
path:
|
|
19858
|
+
path: join53(projectRoot, "package.json"),
|
|
19594
19859
|
platform: "host",
|
|
19595
19860
|
status: "pass"
|
|
19596
19861
|
});
|
|
@@ -19598,7 +19863,7 @@ Mobile release transport checks failed.`);
|
|
|
19598
19863
|
checks.push({
|
|
19599
19864
|
id: "sync.storage-schema",
|
|
19600
19865
|
label: "Offline schema metadata is invalid",
|
|
19601
|
-
path:
|
|
19866
|
+
path: join53(projectRoot, "package.json"),
|
|
19602
19867
|
platform: "host",
|
|
19603
19868
|
remediation: error instanceof Error ? error.message : String(error),
|
|
19604
19869
|
status: "fail"
|
|
@@ -19683,7 +19948,7 @@ Emulator setup verification:`);
|
|
|
19683
19948
|
}
|
|
19684
19949
|
return { https: args.includes("--https"), port };
|
|
19685
19950
|
}
|
|
19686
|
-
const instances = listLiveInstances().filter((instance2) =>
|
|
19951
|
+
const instances = listLiveInstances().filter((instance2) => resolve42(instance2.cwd) === resolve42(projectRoot) && instance2.source === "dev" && instance2.port !== null);
|
|
19687
19952
|
if (instances.length !== 1) {
|
|
19688
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>.");
|
|
19689
19954
|
}
|
|
@@ -19726,8 +19991,8 @@ Emulator setup verification:`);
|
|
|
19726
19991
|
}
|
|
19727
19992
|
return selected;
|
|
19728
19993
|
}, safeArtifactRoot = (projectRoot, value) => {
|
|
19729
|
-
const root =
|
|
19730
|
-
if (root !== projectRoot && !root.startsWith(`${
|
|
19994
|
+
const root = resolve42(projectRoot, value ?? ".absolutejs/mobile/test-artifacts");
|
|
19995
|
+
if (root !== projectRoot && !root.startsWith(`${resolve42(projectRoot)}/`)) {
|
|
19731
19996
|
throw new TypeError("mobile test --artifacts must remain inside the project.");
|
|
19732
19997
|
}
|
|
19733
19998
|
return root;
|
|
@@ -19752,10 +20017,10 @@ Emulator setup verification:`);
|
|
|
19752
20017
|
});
|
|
19753
20018
|
}, writeAndroidFailureArtifacts = async (options) => {
|
|
19754
20019
|
await mkdir14(options.artifactRoot, { recursive: true });
|
|
19755
|
-
const screenshot = options.session ? await options.session.screenshot(
|
|
20020
|
+
const screenshot = options.session ? await options.session.screenshot(join53(options.artifactRoot, "android-failure.png")).catch(() => {
|
|
19756
20021
|
return;
|
|
19757
20022
|
}) : undefined;
|
|
19758
|
-
const diagnosticPath =
|
|
20023
|
+
const diagnosticPath = join53(options.artifactRoot, "android-failure.json");
|
|
19759
20024
|
await writeFile16(diagnosticPath, `${JSON.stringify({
|
|
19760
20025
|
diagnostics: options.session?.diagnostics ?? [],
|
|
19761
20026
|
error: options.error instanceof Error ? options.error.message : String(options.error),
|
|
@@ -19819,7 +20084,7 @@ Emulator setup verification:`);
|
|
|
19819
20084
|
console.log(JSON.stringify(report, null, 2));
|
|
19820
20085
|
else
|
|
19821
20086
|
printAndroidTestReport(report);
|
|
19822
|
-
const screenshot = reportRoot ? await session.screenshot(
|
|
20087
|
+
const screenshot = reportRoot ? await session.screenshot(join53(artifactRoot, "android-emulator.png")) : undefined;
|
|
19823
20088
|
await writeRequestedAndroidReport({
|
|
19824
20089
|
adb,
|
|
19825
20090
|
args,
|
|
@@ -19887,14 +20152,14 @@ Emulator setup verification:`);
|
|
|
19887
20152
|
const port = Number(explicit);
|
|
19888
20153
|
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
19889
20154
|
throw new TypeError("mobile test --port must be a valid TCP port.");
|
|
19890
|
-
const instance2 = listLiveInstances().find((candidate) =>
|
|
20155
|
+
const instance2 = listLiveInstances().find((candidate) => resolve42(candidate.cwd) === resolve42(projectRoot) && candidate.source === "dev" && candidate.port === port);
|
|
19891
20156
|
return {
|
|
19892
20157
|
https: instance2?.https ?? args.includes("--https"),
|
|
19893
20158
|
instance: instance2,
|
|
19894
20159
|
port
|
|
19895
20160
|
};
|
|
19896
20161
|
}
|
|
19897
|
-
const instances = listLiveInstances().filter((instance2) =>
|
|
20162
|
+
const instances = listLiveInstances().filter((instance2) => resolve42(instance2.cwd) === resolve42(projectRoot) && instance2.source === "dev" && instance2.port !== null);
|
|
19898
20163
|
if (instances.length !== 1)
|
|
19899
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>.");
|
|
19900
20165
|
const [instance] = instances;
|
|
@@ -20009,7 +20274,7 @@ Emulator setup verification:`);
|
|
|
20009
20274
|
return result;
|
|
20010
20275
|
}, writeIosFailureArtifacts = async (options) => {
|
|
20011
20276
|
await mkdir14(options.artifactRoot, { recursive: true });
|
|
20012
|
-
const screenshot =
|
|
20277
|
+
const screenshot = join53(options.artifactRoot, "ios-failure.png");
|
|
20013
20278
|
const screenshotResult = captureCommand4([
|
|
20014
20279
|
options.xcrun,
|
|
20015
20280
|
"simctl",
|
|
@@ -20018,7 +20283,7 @@ Emulator setup verification:`);
|
|
|
20018
20283
|
"screenshot",
|
|
20019
20284
|
screenshot
|
|
20020
20285
|
]);
|
|
20021
|
-
const diagnosticPath =
|
|
20286
|
+
const diagnosticPath = join53(options.artifactRoot, "ios-failure.json");
|
|
20022
20287
|
await writeFile16(diagnosticPath, `${JSON.stringify({
|
|
20023
20288
|
appId: options.appId,
|
|
20024
20289
|
error: options.error instanceof Error ? options.error.message : String(options.error),
|
|
@@ -20044,8 +20309,8 @@ Emulator setup verification:`);
|
|
|
20044
20309
|
}, absolutejsVersionForReport = async () => {
|
|
20045
20310
|
let absolutejsVersion = process.env.ABSOLUTE_VERSION ?? "unknown";
|
|
20046
20311
|
const versions = await Promise.all([
|
|
20047
|
-
|
|
20048
|
-
|
|
20312
|
+
resolve42(import.meta.dir, "..", "..", "package.json"),
|
|
20313
|
+
resolve42(import.meta.dir, "..", "..", "..", "package.json")
|
|
20049
20314
|
].map((candidate) => readPackageVersionForIosReport(candidate).catch(() => "unknown")));
|
|
20050
20315
|
for (const version2 of versions) {
|
|
20051
20316
|
if (version2 === "unknown")
|
|
@@ -20264,7 +20529,7 @@ Emulator setup verification:`);
|
|
|
20264
20529
|
], "iOS app launch");
|
|
20265
20530
|
await waitForIosHmrClient({ https, port, timeoutMs });
|
|
20266
20531
|
await mkdir14(artifactRoot, { recursive: true });
|
|
20267
|
-
const screenshot =
|
|
20532
|
+
const screenshot = join53(artifactRoot, "ios-simulator.png");
|
|
20268
20533
|
requireCapturedCommand([xcrun, "simctl", "io", simulator.udid, "screenshot", screenshot], "iOS simulator screenshot");
|
|
20269
20534
|
const hmrApply = await waitForRequestedIosHmr(args, instance, timeoutMs);
|
|
20270
20535
|
const report = {
|
|
@@ -20377,6 +20642,10 @@ Emulator setup verification:`);
|
|
|
20377
20642
|
await doctor(args.slice(1));
|
|
20378
20643
|
return;
|
|
20379
20644
|
}
|
|
20645
|
+
if (command === "inspect") {
|
|
20646
|
+
await inspectMobile(args.slice(1));
|
|
20647
|
+
return;
|
|
20648
|
+
}
|
|
20380
20649
|
if (command === "test" && args[1] === "android") {
|
|
20381
20650
|
await testAndroid(args.slice(2));
|
|
20382
20651
|
return;
|
|
@@ -20401,7 +20670,7 @@ Emulator setup verification:`);
|
|
|
20401
20670
|
await publishIos(args.slice(2));
|
|
20402
20671
|
return;
|
|
20403
20672
|
}
|
|
20404
|
-
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]");
|
|
20405
20674
|
};
|
|
20406
20675
|
var init_mobile = __esm(() => {
|
|
20407
20676
|
init_dependencies();
|
|
@@ -20435,6 +20704,7 @@ var init_mobile = __esm(() => {
|
|
|
20435
20704
|
init_nativeAuth();
|
|
20436
20705
|
init_syncSchema();
|
|
20437
20706
|
init_deviceCapabilities();
|
|
20707
|
+
init_mobileInspect();
|
|
20438
20708
|
CAPACITOR_PACKAGES = [
|
|
20439
20709
|
"@capacitor/core",
|
|
20440
20710
|
"@capacitor/app",
|
|
@@ -20470,10 +20740,10 @@ var exports_typecheck = {};
|
|
|
20470
20740
|
__export(exports_typecheck, {
|
|
20471
20741
|
typecheck: () => typecheck
|
|
20472
20742
|
});
|
|
20473
|
-
import { resolve as
|
|
20743
|
+
import { resolve as resolve43, join as join54 } from "path";
|
|
20474
20744
|
import { existsSync as existsSync42, readFileSync as readFileSync40 } from "fs";
|
|
20475
20745
|
import { mkdir as mkdir15, writeFile as writeFile17 } from "fs/promises";
|
|
20476
|
-
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) => {
|
|
20477
20747
|
if (!existsSync42(resolveConfigPath(configPath2))) {
|
|
20478
20748
|
const defaultService = {};
|
|
20479
20749
|
return [defaultService];
|
|
@@ -20495,7 +20765,7 @@ var isCommandService3 = (service) => service.kind === "command" || Array.isArray
|
|
|
20495
20765
|
const exitCode = await proc.exited;
|
|
20496
20766
|
return { exitCode, name, output: (stdout + stderr).trim() };
|
|
20497
20767
|
}, shellEscape = (value) => `'${value.replaceAll("'", "'\\''")}'`, runShell = async (name, command) => run(name, ["/bin/bash", "-lc", command]), findBin = (name) => {
|
|
20498
|
-
const local =
|
|
20768
|
+
const local = resolve43("node_modules", ".bin", name);
|
|
20499
20769
|
return existsSync42(local) ? local : null;
|
|
20500
20770
|
}, ANSI_COLOR_REGEX, ANSI_PURPLE_REGEX, ANSI_CYAN_REGEX, ANSI_TOKEN_END_REGEX, stripAnsi4 = (str) => str.replace(ANSI_COLOR_REGEX, ""), formatSvelteOutput = (output) => {
|
|
20501
20771
|
const cwd = `${process.cwd()}/`;
|
|
@@ -20543,15 +20813,15 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20543
20813
|
return formatted;
|
|
20544
20814
|
}, ABSOLUTE_INTERNAL_EXCLUDES, resolveAbsoluteTypeFile = (fileName) => {
|
|
20545
20815
|
const candidates = [
|
|
20546
|
-
|
|
20547
|
-
|
|
20548
|
-
|
|
20549
|
-
|
|
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)
|
|
20550
20820
|
];
|
|
20551
20821
|
return candidates.find((candidate) => existsSync42(candidate)) ?? candidates[0];
|
|
20552
20822
|
}, ABSOLUTE_TYPECHECK_FILES, readProjectTsconfig = () => {
|
|
20553
20823
|
try {
|
|
20554
|
-
return JSON.parse(readFileSync40(
|
|
20824
|
+
return JSON.parse(readFileSync40(resolve43("tsconfig.json"), "utf-8"));
|
|
20555
20825
|
} catch {
|
|
20556
20826
|
return {};
|
|
20557
20827
|
}
|
|
@@ -20579,27 +20849,27 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20579
20849
|
console.error("\x1B[31m\u2717\x1B[0m vue-tsc is required for Vue type checking. Install it: bun add -d vue-tsc");
|
|
20580
20850
|
process.exit(1);
|
|
20581
20851
|
}
|
|
20582
|
-
const vueTsconfigPath =
|
|
20852
|
+
const vueTsconfigPath = join54(cacheDir, "tsconfig.vue-check.json");
|
|
20583
20853
|
await writeFile17(vueTsconfigPath, JSON.stringify({
|
|
20584
20854
|
compilerOptions: {
|
|
20585
20855
|
rootDir: ".."
|
|
20586
20856
|
},
|
|
20587
20857
|
exclude: getProjectTypecheckExcludes(),
|
|
20588
|
-
extends:
|
|
20858
|
+
extends: resolve43("tsconfig.json"),
|
|
20589
20859
|
include: getProjectTypecheckIncludes()
|
|
20590
20860
|
}, null, "\t"));
|
|
20591
20861
|
const base = [
|
|
20592
20862
|
vueTscBin,
|
|
20593
20863
|
"--noEmit",
|
|
20594
20864
|
"--project",
|
|
20595
|
-
|
|
20865
|
+
resolve43(vueTsconfigPath),
|
|
20596
20866
|
"--pretty"
|
|
20597
20867
|
];
|
|
20598
20868
|
const cached = await run("vue-tsc", [
|
|
20599
20869
|
...base,
|
|
20600
20870
|
"--incremental",
|
|
20601
20871
|
"--tsBuildInfoFile",
|
|
20602
|
-
|
|
20872
|
+
join54(cacheDir, "vue-tsc.tsbuildinfo")
|
|
20603
20873
|
]);
|
|
20604
20874
|
if (cached.exitCode === 0 || cached.output.length > 0)
|
|
20605
20875
|
return cached;
|
|
@@ -20610,7 +20880,7 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20610
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");
|
|
20611
20881
|
process.exit(1);
|
|
20612
20882
|
}
|
|
20613
|
-
const angularTsconfigPath =
|
|
20883
|
+
const angularTsconfigPath = join54(cacheDir, "tsconfig.angular-check.json");
|
|
20614
20884
|
await writeFile17(angularTsconfigPath, JSON.stringify({
|
|
20615
20885
|
angularCompilerOptions: {
|
|
20616
20886
|
strictTemplates: true
|
|
@@ -20620,32 +20890,32 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20620
20890
|
rootDir: ".."
|
|
20621
20891
|
},
|
|
20622
20892
|
exclude: ABSOLUTE_INTERNAL_EXCLUDES.map(toGeneratedConfigPath),
|
|
20623
|
-
extends:
|
|
20893
|
+
extends: resolve43("tsconfig.json"),
|
|
20624
20894
|
include: [`../${angularDir}/**/*`]
|
|
20625
20895
|
}, null, "\t"));
|
|
20626
|
-
return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(
|
|
20896
|
+
return runShell("ngc", `${shellEscape(ngcBin)} -p ${shellEscape(resolve43(angularTsconfigPath))}`);
|
|
20627
20897
|
}, buildTscCheck = (cacheDir) => {
|
|
20628
20898
|
const tscBin = findBin("tsc");
|
|
20629
20899
|
if (!tscBin) {
|
|
20630
20900
|
console.error("\x1B[31m\u2717\x1B[0m typescript is required for type checking. Install it: bun add -d typescript");
|
|
20631
20901
|
process.exit(1);
|
|
20632
20902
|
}
|
|
20633
|
-
const tscConfigPath =
|
|
20903
|
+
const tscConfigPath = join54(cacheDir, "tsconfig.typecheck.json");
|
|
20634
20904
|
return writeFile17(tscConfigPath, JSON.stringify({
|
|
20635
20905
|
compilerOptions: {
|
|
20636
20906
|
rootDir: ".."
|
|
20637
20907
|
},
|
|
20638
20908
|
exclude: getProjectTypecheckExcludes(),
|
|
20639
|
-
extends:
|
|
20909
|
+
extends: resolve43("tsconfig.json"),
|
|
20640
20910
|
include: getProjectTypecheckIncludes()
|
|
20641
20911
|
}, null, "\t")).then(() => run("tsc", [
|
|
20642
20912
|
tscBin,
|
|
20643
20913
|
"--noEmit",
|
|
20644
20914
|
"--project",
|
|
20645
|
-
|
|
20915
|
+
resolve43(tscConfigPath),
|
|
20646
20916
|
"--incremental",
|
|
20647
20917
|
"--tsBuildInfoFile",
|
|
20648
|
-
|
|
20918
|
+
join54(cacheDir, "tsc.tsbuildinfo"),
|
|
20649
20919
|
"--pretty"
|
|
20650
20920
|
]));
|
|
20651
20921
|
}, buildSvelteCheck = async (cacheDir, svelteDir) => {
|
|
@@ -20654,16 +20924,16 @@ Found ${errorCount} error${suffix}.`;
|
|
|
20654
20924
|
console.error("\x1B[31m\u2717\x1B[0m svelte-check is required for Svelte type checking. Install it: bun add -d svelte-check");
|
|
20655
20925
|
process.exit(1);
|
|
20656
20926
|
}
|
|
20657
|
-
const svelteTsconfigPath =
|
|
20927
|
+
const svelteTsconfigPath = join54(cacheDir, "tsconfig.svelte-check.json");
|
|
20658
20928
|
await writeFile17(svelteTsconfigPath, JSON.stringify({
|
|
20659
|
-
extends:
|
|
20929
|
+
extends: resolve43("tsconfig.json"),
|
|
20660
20930
|
files: ABSOLUTE_TYPECHECK_FILES,
|
|
20661
20931
|
include: [`../${svelteDir}/**/*`]
|
|
20662
20932
|
}, null, "\t"));
|
|
20663
20933
|
return run("svelte-check", [
|
|
20664
20934
|
svelteBin,
|
|
20665
20935
|
"--tsconfig",
|
|
20666
|
-
|
|
20936
|
+
resolve43(svelteTsconfigPath),
|
|
20667
20937
|
"--threshold",
|
|
20668
20938
|
"error",
|
|
20669
20939
|
"--compiler-warnings",
|
|
@@ -20857,11 +21127,11 @@ var DEFAULT_RELAY_PORT = 8787, DEFAULT_REQUEST_TIMEOUT_MS = 30000, headersToObje
|
|
|
20857
21127
|
url: url.pathname + url.search,
|
|
20858
21128
|
...bodyBytes && bodyBytes.length > 0 ? { bodyBase64: Buffer.from(bodyBytes).toString("base64") } : {}
|
|
20859
21129
|
};
|
|
20860
|
-
const responsePromise = new Promise((
|
|
20861
|
-
pending.set(id,
|
|
21130
|
+
const responsePromise = new Promise((resolve44) => {
|
|
21131
|
+
pending.set(id, resolve44);
|
|
20862
21132
|
});
|
|
20863
21133
|
client.send(encodeTunnelMessage(message));
|
|
20864
|
-
const timeout = new Promise((
|
|
21134
|
+
const timeout = new Promise((resolve44) => setTimeout(() => resolve44({ id, message: "timeout", type: "error" }), requestTimeoutMs));
|
|
20865
21135
|
const result = await Promise.race([responsePromise, timeout]);
|
|
20866
21136
|
pending.delete(id);
|
|
20867
21137
|
if (result.type === "error") {
|
|
@@ -22472,6 +22742,7 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
22472
22742
|
const serverEntryBasename = absServerEntry.slice(absServerEntry.lastIndexOf("/") + 1);
|
|
22473
22743
|
const configBasename = configPath2 ? configPath2.slice(configPath2.lastIndexOf("/") + 1) : "absolute.config.ts";
|
|
22474
22744
|
const ATOMIC_RECOVERY_WINDOW_MS = 1000;
|
|
22745
|
+
const ATOMIC_RECOVERY_DELAY_MS = 25;
|
|
22475
22746
|
const recentlyHandled = new Map;
|
|
22476
22747
|
const handleCandidate = (filename) => {
|
|
22477
22748
|
if (filename.includes("/") || filename.includes("\\"))
|
|
@@ -22515,18 +22786,28 @@ var dev = async (serverEntry, configPath2, options = {}) => {
|
|
|
22515
22786
|
handleCandidate(entry.name);
|
|
22516
22787
|
}
|
|
22517
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
|
+
};
|
|
22518
22798
|
const watcher = watch3(serverEntryDir, { recursive: false }, (event, filename) => {
|
|
22519
22799
|
if (!filename)
|
|
22520
22800
|
return;
|
|
22521
22801
|
if (isAtomicWriteTemp(filename)) {
|
|
22522
|
-
if (event === "rename")
|
|
22523
|
-
|
|
22524
|
-
}
|
|
22802
|
+
if (event === "rename")
|
|
22803
|
+
scheduleAtomicRecovery();
|
|
22525
22804
|
return;
|
|
22526
22805
|
}
|
|
22527
22806
|
handleCandidate(filename);
|
|
22528
22807
|
});
|
|
22529
22808
|
const closeWatcher = () => {
|
|
22809
|
+
if (atomicRecoveryTimer)
|
|
22810
|
+
clearTimeout(atomicRecoveryTimer);
|
|
22530
22811
|
try {
|
|
22531
22812
|
watcher.close();
|
|
22532
22813
|
} catch {}
|
|
@@ -24763,7 +25044,7 @@ if (command === "dev") {
|
|
|
24763
25044
|
console.error(" prepare [entry] [--outdir dir] Build production assets and server without launching");
|
|
24764
25045
|
console.error(" start [entry] [--outdir dir] [--prebuilt] Start production server");
|
|
24765
25046
|
console.error(" compile [entry] [--outdir dir] [--outfile path] Compile standalone executable");
|
|
24766
|
-
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");
|
|
24767
25048
|
console.error(" config [--port n] Open the unified config UI (ESLint, tsconfig, Prettier)");
|
|
24768
25049
|
console.error(" db <backup|restore|seed> Backup/restore any Postgres DB (ORM-agnostic, upsert by PK) or run the seed script");
|
|
24769
25050
|
console.error(" doctor [--fix] [--json] Diagnose the project (bun, type graph, config, framework dirs, env, port)");
|
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
// src/dev/serverBootstrap.ts
|
|
3
3
|
import { copyFileSync, existsSync, readdirSync, unlinkSync } from "fs";
|
|
4
4
|
import { dirname, extname, join, resolve } from "path";
|
|
5
|
+
|
|
6
|
+
// src/dev/serverEntryCopies.ts
|
|
7
|
+
var ENTRY_COPY_OWNER_PATTERN = /^\.absolutejs-hmr-(\d+)-(?:bootstrap-)?\d+\.[^.]+$/;
|
|
8
|
+
var absoluteServerEntryCopyOwnerPid = (name) => {
|
|
9
|
+
const match = ENTRY_COPY_OWNER_PATTERN.exec(name);
|
|
10
|
+
if (!match)
|
|
11
|
+
return null;
|
|
12
|
+
const pid = Number(match[1]);
|
|
13
|
+
return Number.isSafeInteger(pid) && pid > 0 ? pid : null;
|
|
14
|
+
};
|
|
15
|
+
var isProcessAlive = (pid) => {
|
|
16
|
+
try {
|
|
17
|
+
process.kill(pid, 0);
|
|
18
|
+
return true;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return !(error instanceof Error && ("code" in error) && error.code === "ESRCH");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var isStaleAbsoluteServerEntryCopy = (name, currentPid = process.pid, ownerIsAlive = isProcessAlive) => {
|
|
24
|
+
const ownerPid = absoluteServerEntryCopyOwnerPid(name);
|
|
25
|
+
if (ownerPid === null)
|
|
26
|
+
return false;
|
|
27
|
+
return ownerPid === currentPid || !ownerIsAlive(ownerPid);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// src/dev/serverBootstrap.ts
|
|
5
31
|
var originalEntry = process.env.ABSOLUTE_SERVER_ENTRY;
|
|
6
32
|
if (!originalEntry) {
|
|
7
33
|
throw new Error("ABSOLUTE_SERVER_ENTRY is required by the AbsoluteJS dev bootstrap");
|
|
@@ -24,6 +50,8 @@ if (!isHotReevaluation) {
|
|
|
24
50
|
if (!name.startsWith(copyPrefix) || !name.endsWith(entryExtension)) {
|
|
25
51
|
continue;
|
|
26
52
|
}
|
|
53
|
+
if (!isStaleAbsoluteServerEntryCopy(name))
|
|
54
|
+
continue;
|
|
27
55
|
removeEntryCopy(join(entryDir, name));
|
|
28
56
|
}
|
|
29
57
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const absoluteServerEntryCopyOwnerPid: (name: string) => number | null;
|
|
2
|
+
export declare const isProcessAlive: (pid: number) => boolean;
|
|
3
|
+
export declare const isStaleAbsoluteServerEntryCopy: (name: string, currentPid?: number, ownerIsAlive?: (pid: number) => boolean) => boolean;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { NormalizedAbsoluteMobileConfig } from './config';
|
|
2
|
+
import { inspectAbsoluteMobileRelease } from './releaseDoctor';
|
|
3
|
+
export declare const ABSOLUTE_MOBILE_INSPECTION_FORMAT: 1;
|
|
4
|
+
type MobilePackageInspection = {
|
|
5
|
+
declared: string;
|
|
6
|
+
installed?: string;
|
|
7
|
+
name: string;
|
|
8
|
+
};
|
|
9
|
+
type MobileBundleInspection = {
|
|
10
|
+
appBuild?: string;
|
|
11
|
+
auth?: boolean;
|
|
12
|
+
capabilities?: string[];
|
|
13
|
+
entryResolved?: boolean;
|
|
14
|
+
frameworks?: string[];
|
|
15
|
+
issue?: string;
|
|
16
|
+
manifest: string;
|
|
17
|
+
pageCount?: number;
|
|
18
|
+
routeCount?: number;
|
|
19
|
+
runtime?: string;
|
|
20
|
+
status: 'invalid' | 'missing' | 'valid';
|
|
21
|
+
sync?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type AbsoluteMobileProjectInspection = {
|
|
24
|
+
bundle: MobileBundleInspection;
|
|
25
|
+
capabilities: {
|
|
26
|
+
current: string[];
|
|
27
|
+
embeddedMatchesCurrent?: boolean;
|
|
28
|
+
issue?: string;
|
|
29
|
+
plugins: string[];
|
|
30
|
+
};
|
|
31
|
+
config: {
|
|
32
|
+
appId: string;
|
|
33
|
+
appName: string;
|
|
34
|
+
bundleDirectory: string;
|
|
35
|
+
deepLinkHosts: string[];
|
|
36
|
+
deepLinkScheme?: string;
|
|
37
|
+
engine: 'capacitor';
|
|
38
|
+
entry: string;
|
|
39
|
+
iosVersion?: string;
|
|
40
|
+
nativeProjectDirectory: string;
|
|
41
|
+
platforms: string[];
|
|
42
|
+
productionOrigin: string;
|
|
43
|
+
};
|
|
44
|
+
format: typeof ABSOLUTE_MOBILE_INSPECTION_FORMAT;
|
|
45
|
+
nativeProjects: Array<{
|
|
46
|
+
initialized: boolean;
|
|
47
|
+
path: string;
|
|
48
|
+
platform: string;
|
|
49
|
+
}>;
|
|
50
|
+
packages: MobilePackageInspection[];
|
|
51
|
+
release: {
|
|
52
|
+
checks: Array<{
|
|
53
|
+
id: string;
|
|
54
|
+
status: 'fail' | 'pass' | 'warn';
|
|
55
|
+
}>;
|
|
56
|
+
ready: boolean;
|
|
57
|
+
};
|
|
58
|
+
runtime: {
|
|
59
|
+
absolutejs: string;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export type InspectAbsoluteMobileProjectOptions = {
|
|
63
|
+
absolutejsVersion?: string;
|
|
64
|
+
inspectRelease?: typeof inspectAbsoluteMobileRelease;
|
|
65
|
+
};
|
|
66
|
+
export declare const inspectAbsoluteMobileProject: (config: NormalizedAbsoluteMobileConfig, projectRoot: string, options?: InspectAbsoluteMobileProjectOptions) => Promise<{
|
|
67
|
+
bundle: MobileBundleInspection;
|
|
68
|
+
capabilities: {
|
|
69
|
+
plugins: string[];
|
|
70
|
+
issue?: string | undefined;
|
|
71
|
+
embeddedMatchesCurrent?: boolean | undefined;
|
|
72
|
+
current: string[];
|
|
73
|
+
};
|
|
74
|
+
config: {
|
|
75
|
+
appId: string;
|
|
76
|
+
appName: string;
|
|
77
|
+
bundleDirectory: string;
|
|
78
|
+
deepLinkHosts: string[];
|
|
79
|
+
deepLinkScheme: string | undefined;
|
|
80
|
+
engine: "capacitor";
|
|
81
|
+
entry: string;
|
|
82
|
+
iosVersion: string | undefined;
|
|
83
|
+
nativeProjectDirectory: string;
|
|
84
|
+
platforms: import("..").MobilePlatform[];
|
|
85
|
+
productionOrigin: string;
|
|
86
|
+
};
|
|
87
|
+
format: 1;
|
|
88
|
+
nativeProjects: {
|
|
89
|
+
initialized: boolean;
|
|
90
|
+
path: string;
|
|
91
|
+
platform: import("..").MobilePlatform;
|
|
92
|
+
}[];
|
|
93
|
+
packages: {
|
|
94
|
+
name: string;
|
|
95
|
+
installed?: string | undefined;
|
|
96
|
+
declared: string;
|
|
97
|
+
}[];
|
|
98
|
+
release: {
|
|
99
|
+
checks: {
|
|
100
|
+
id: string;
|
|
101
|
+
status: "pass" | "fail";
|
|
102
|
+
}[];
|
|
103
|
+
ready: boolean;
|
|
104
|
+
};
|
|
105
|
+
runtime: {
|
|
106
|
+
absolutejs: string;
|
|
107
|
+
};
|
|
108
|
+
}>;
|
|
109
|
+
export declare const renderAbsoluteMobileProjectInspection: (report: AbsoluteMobileProjectInspection) => string;
|
|
110
|
+
export {};
|