@objectstack/types 17.2.0 → 17.4.0
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/CHANGELOG.md +1106 -0
- package/dist/index.d.mts +649 -11
- package/dist/index.d.ts +649 -11
- package/dist/index.js +331 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +313 -3
- package/dist/index.mjs.map +1 -1
- package/dist/node.d.mts +12 -3
- package/dist/node.d.ts +12 -3
- package/dist/node.js +199 -2
- package/dist/node.js.map +1 -1
- package/dist/node.mjs +201 -4
- package/dist/node.mjs.map +1 -1
- package/package.json +5 -4
package/dist/node.js
CHANGED
|
@@ -87,7 +87,7 @@ function isDeclaredByHost(specifier, hostRoot) {
|
|
|
87
87
|
var HOST_IMPORT_FAILURE_KIND = "objectstackHostImportFailureKind";
|
|
88
88
|
function hostImportFailureKind(err) {
|
|
89
89
|
const kind = err?.[HOST_IMPORT_FAILURE_KIND];
|
|
90
|
-
return kind === "undeclared" || kind === "declared-unresolvable" ? kind : void 0;
|
|
90
|
+
return kind === "undeclared" || kind === "declared-unresolvable" || kind === "declared-no-loadable-entry" ? kind : void 0;
|
|
91
91
|
}
|
|
92
92
|
function hostImportError(kind, message, cause) {
|
|
93
93
|
const err = new Error(message);
|
|
@@ -129,6 +129,186 @@ function unresolvableMessage(declaration, cause) {
|
|
|
129
129
|
\u2022 it IS installed but its "main"/"exports" points at a dist that was never built
|
|
130
130
|
(resolver: ${detail})`;
|
|
131
131
|
}
|
|
132
|
+
var ESM_IMPORT_CONDITIONS = /* @__PURE__ */ new Set([
|
|
133
|
+
"node-addons",
|
|
134
|
+
"node",
|
|
135
|
+
"import",
|
|
136
|
+
"default"
|
|
137
|
+
]);
|
|
138
|
+
var CJS_REQUIRE_CONDITIONS = /* @__PURE__ */ new Set([
|
|
139
|
+
"node-addons",
|
|
140
|
+
"node",
|
|
141
|
+
"require",
|
|
142
|
+
"default"
|
|
143
|
+
]);
|
|
144
|
+
function selectConditionTarget(node, conditions) {
|
|
145
|
+
if (typeof node === "string") return node;
|
|
146
|
+
if (Array.isArray(node)) {
|
|
147
|
+
for (const alternative of node) {
|
|
148
|
+
const hit = selectConditionTarget(alternative, conditions);
|
|
149
|
+
if (hit !== void 0) return hit;
|
|
150
|
+
}
|
|
151
|
+
return void 0;
|
|
152
|
+
}
|
|
153
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
154
|
+
for (const entry of Object.entries(node)) {
|
|
155
|
+
if (!conditions.has(entry[0])) continue;
|
|
156
|
+
const hit = selectConditionTarget(entry[1], conditions);
|
|
157
|
+
if (hit !== void 0) return hit;
|
|
158
|
+
}
|
|
159
|
+
return void 0;
|
|
160
|
+
}
|
|
161
|
+
function resolveExportsSubpath(exportsField, subpath, conditions = ESM_IMPORT_CONDITIONS) {
|
|
162
|
+
if (exportsField === void 0) return void 0;
|
|
163
|
+
const keys = typeof exportsField === "object" && exportsField !== null && !Array.isArray(exportsField) ? Object.keys(exportsField) : void 0;
|
|
164
|
+
const isSubpathMap = keys !== void 0 && keys.length > 0 && keys.every((key) => key === "." || key.indexOf("./") === 0);
|
|
165
|
+
if (!isSubpathMap) {
|
|
166
|
+
return subpath === "." ? selectConditionTarget(exportsField, conditions) : void 0;
|
|
167
|
+
}
|
|
168
|
+
const map = exportsField;
|
|
169
|
+
if (Object.prototype.hasOwnProperty.call(map, subpath)) {
|
|
170
|
+
return selectConditionTarget(map[subpath], conditions);
|
|
171
|
+
}
|
|
172
|
+
let best;
|
|
173
|
+
for (const entry of Object.entries(map)) {
|
|
174
|
+
const star = entry[0].indexOf("*");
|
|
175
|
+
if (star < 0 || entry[0].indexOf("*", star + 1) >= 0) continue;
|
|
176
|
+
const prefix = entry[0].slice(0, star);
|
|
177
|
+
const suffix = entry[0].slice(star + 1);
|
|
178
|
+
if (subpath.indexOf(prefix) !== 0) continue;
|
|
179
|
+
if (suffix !== "" && subpath.slice(subpath.length - suffix.length) !== suffix) continue;
|
|
180
|
+
if (subpath.length < prefix.length + suffix.length) continue;
|
|
181
|
+
if (best !== void 0 && (best.prefix.length > prefix.length || best.prefix.length === prefix.length && best.suffix.length >= suffix.length)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
best = { prefix, suffix, target: entry[1] };
|
|
185
|
+
}
|
|
186
|
+
if (best === void 0) return void 0;
|
|
187
|
+
const matched = subpath.slice(best.prefix.length, subpath.length - best.suffix.length);
|
|
188
|
+
const target = selectConditionTarget(best.target, conditions);
|
|
189
|
+
return target === void 0 ? void 0 : target.split("*").join(matched);
|
|
190
|
+
}
|
|
191
|
+
function exportsSubpathOf(specifier, packageName) {
|
|
192
|
+
return specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
|
|
193
|
+
}
|
|
194
|
+
var ALIAS_DECLARATION_PROTOCOLS = [
|
|
195
|
+
{ prefix: "npm:", rangeRequired: false },
|
|
196
|
+
{ prefix: "workspace:", rangeRequired: true }
|
|
197
|
+
];
|
|
198
|
+
function declaredManifestName(declaration) {
|
|
199
|
+
const { packageName, specifier } = declaration;
|
|
200
|
+
if (specifier === void 0) return packageName;
|
|
201
|
+
const protocol = ALIAS_DECLARATION_PROTOCOLS.find((p) => specifier.indexOf(p.prefix) === 0);
|
|
202
|
+
if (protocol === void 0) return packageName;
|
|
203
|
+
const value = specifier.slice(protocol.prefix.length);
|
|
204
|
+
const at = value.lastIndexOf("@");
|
|
205
|
+
if (at <= 0 && protocol.rangeRequired) return packageName;
|
|
206
|
+
const name = at > 0 ? value.slice(0, at) : value;
|
|
207
|
+
return packageNameFromSpecifier(name) === name ? name : packageName;
|
|
208
|
+
}
|
|
209
|
+
function packageRootOf(resolvedFile, manifestName) {
|
|
210
|
+
let dir = (0, import_node_path.dirname)(resolvedFile);
|
|
211
|
+
for (let hop = 0; hop < 64; hop += 1) {
|
|
212
|
+
try {
|
|
213
|
+
const manifest = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(dir, "package.json"), "utf8"));
|
|
214
|
+
if (manifest.name === manifestName) return dir;
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
const parent = (0, import_node_path.dirname)(dir);
|
|
218
|
+
if (parent === dir) return void 0;
|
|
219
|
+
dir = parent;
|
|
220
|
+
}
|
|
221
|
+
return void 0;
|
|
222
|
+
}
|
|
223
|
+
function esmEntryForDeclared(specifier, declaration, cjsResolved) {
|
|
224
|
+
const { packageName } = declaration;
|
|
225
|
+
const root = packageRootOf(cjsResolved, declaredManifestName(declaration));
|
|
226
|
+
if (root === void 0) return void 0;
|
|
227
|
+
let exportsField;
|
|
228
|
+
try {
|
|
229
|
+
exportsField = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(root, "package.json"), "utf8")).exports;
|
|
230
|
+
} catch {
|
|
231
|
+
return void 0;
|
|
232
|
+
}
|
|
233
|
+
if (exportsField === void 0 || exportsField === null) return void 0;
|
|
234
|
+
const subpath = exportsSubpathOf(specifier, packageName);
|
|
235
|
+
const target = resolveExportsSubpath(exportsField, subpath);
|
|
236
|
+
if (typeof target !== "string" || target.indexOf("./") !== 0) return void 0;
|
|
237
|
+
const entry = (0, import_node_path.resolve)(root, target);
|
|
238
|
+
if (entry.indexOf(root + import_node_path.sep) !== 0) return void 0;
|
|
239
|
+
return (0, import_node_fs.existsSync)(entry) ? entry : void 0;
|
|
240
|
+
}
|
|
241
|
+
function hasInvalidExportsSubpathSegments(subpath) {
|
|
242
|
+
if (subpath === ".") return false;
|
|
243
|
+
return subpath.slice(2).split(/[/\\]/).some((raw) => {
|
|
244
|
+
const segment = raw.toLowerCase();
|
|
245
|
+
return segment === "" || segment === "." || segment === ".." || segment === "node_modules";
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
function hostInstalledPackageDir(declaration) {
|
|
249
|
+
const { packageName, hostRoot } = declaration;
|
|
250
|
+
const linked = (0, import_node_path.join)(hostRoot, "node_modules", ...packageName.split("/"));
|
|
251
|
+
try {
|
|
252
|
+
const manifest = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(linked, "package.json"), "utf8"));
|
|
253
|
+
if (manifest.name !== declaredManifestName(declaration)) return void 0;
|
|
254
|
+
} catch {
|
|
255
|
+
return void 0;
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
return (0, import_node_fs.realpathSync)(linked);
|
|
259
|
+
} catch {
|
|
260
|
+
return linked;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function declaredCjsResolveFallback(specifier, declaration) {
|
|
264
|
+
const { packageName } = declaration;
|
|
265
|
+
const packageDir = hostInstalledPackageDir(declaration);
|
|
266
|
+
if (packageDir === void 0) return { outcome: "absent" };
|
|
267
|
+
let exportsField;
|
|
268
|
+
try {
|
|
269
|
+
exportsField = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(packageDir, "package.json"), "utf8")).exports;
|
|
270
|
+
} catch {
|
|
271
|
+
return { outcome: "absent" };
|
|
272
|
+
}
|
|
273
|
+
if (exportsField === void 0 || exportsField === null) return { outcome: "install-broken" };
|
|
274
|
+
const subpath = exportsSubpathOf(specifier, packageName);
|
|
275
|
+
if (hasInvalidExportsSubpathSegments(subpath)) return { outcome: "invalid-specifier" };
|
|
276
|
+
const importTarget = resolveExportsSubpath(exportsField, subpath, ESM_IMPORT_CONDITIONS);
|
|
277
|
+
if (typeof importTarget === "string" && importTarget.indexOf("./") === 0) {
|
|
278
|
+
const entry = (0, import_node_path.resolve)(packageDir, importTarget);
|
|
279
|
+
if (entry.indexOf(packageDir + import_node_path.sep) === 0 && (0, import_node_fs.existsSync)(entry)) {
|
|
280
|
+
return { outcome: "entry", entry };
|
|
281
|
+
}
|
|
282
|
+
return { outcome: "install-broken" };
|
|
283
|
+
}
|
|
284
|
+
const requireTarget = resolveExportsSubpath(exportsField, subpath, CJS_REQUIRE_CONDITIONS);
|
|
285
|
+
if (typeof requireTarget === "string" && requireTarget.indexOf("./") === 0) {
|
|
286
|
+
return { outcome: "install-broken" };
|
|
287
|
+
}
|
|
288
|
+
return { outcome: "no-loadable-entry", packageDir };
|
|
289
|
+
}
|
|
290
|
+
function noLoadableEntryMessage(declaration, packageDir, subpath, cause) {
|
|
291
|
+
const { packageName, hostRoot, field, specifier } = declaration;
|
|
292
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
293
|
+
const subpathNote = subpath === "." ? 'its main entry (".")' : `the subpath '${subpath}'`;
|
|
294
|
+
return `Cannot load module '${packageName}': the host app DECLARES it (${field}: ${JSON.stringify(specifier)}) and it IS installed, but the package publishes no entry that Node can load.
|
|
295
|
+
host app: ${hostRoot}
|
|
296
|
+
installed at: ${packageDir}
|
|
297
|
+
|
|
298
|
+
This is a problem with the PACKAGE's own published shape, not with the app or
|
|
299
|
+
its install \u2014 the declaration is right and the package is on disk, so neither
|
|
300
|
+
re-reading package.json nor re-running \`pnpm install\` can change anything.
|
|
301
|
+
Measured from its manifest:
|
|
302
|
+
\u2022 its "exports" map names no \`require\`-condition entry for ${subpathNote},
|
|
303
|
+
so a CommonJS resolution cannot see it at all
|
|
304
|
+
\u2022 and no \`import\`-condition entry either, so there is nothing for the ESM
|
|
305
|
+
fallback to load
|
|
306
|
+
The remedy lives in the package: it must publish a runtime entry for this
|
|
307
|
+
subpath (an \`import\` condition suffices here; a dual build adds \`require\`).
|
|
308
|
+
A publish carrying only \`types\` / \`browser\`-style conditions cannot be loaded
|
|
309
|
+
by a Node host at all.
|
|
310
|
+
(resolver: ${detail})`;
|
|
311
|
+
}
|
|
132
312
|
function createHostImporter(hostRoot = process.cwd(), options = {}) {
|
|
133
313
|
const hostRequire = createHostRequire(hostRoot);
|
|
134
314
|
const { fallbackImport } = options;
|
|
@@ -149,13 +329,30 @@ function createHostImporter(hostRoot = process.cwd(), options = {}) {
|
|
|
149
329
|
try {
|
|
150
330
|
resolved = hostRequire.resolve(pkg);
|
|
151
331
|
} catch (cause) {
|
|
332
|
+
const fallback = declaredCjsResolveFallback(pkg, declaration);
|
|
333
|
+
if (fallback.outcome === "entry") {
|
|
334
|
+
return import((0, import_node_url.pathToFileURL)(fallback.entry).href);
|
|
335
|
+
}
|
|
336
|
+
if (fallback.outcome === "no-loadable-entry") {
|
|
337
|
+
throw hostImportError(
|
|
338
|
+
"declared-no-loadable-entry",
|
|
339
|
+
noLoadableEntryMessage(
|
|
340
|
+
declaration,
|
|
341
|
+
fallback.packageDir,
|
|
342
|
+
exportsSubpathOf(pkg, declaration.packageName),
|
|
343
|
+
cause
|
|
344
|
+
),
|
|
345
|
+
cause
|
|
346
|
+
);
|
|
347
|
+
}
|
|
152
348
|
throw hostImportError(
|
|
153
349
|
"declared-unresolvable",
|
|
154
350
|
unresolvableMessage(declaration, cause),
|
|
155
351
|
cause
|
|
156
352
|
);
|
|
157
353
|
}
|
|
158
|
-
|
|
354
|
+
const entry = esmEntryForDeclared(pkg, declaration, resolved) ?? resolved;
|
|
355
|
+
return import((0, import_node_url.pathToFileURL)(entry).href);
|
|
159
356
|
}
|
|
160
357
|
try {
|
|
161
358
|
return await importAsCaller(pkg);
|
package/dist/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/node.ts","../src/module-not-found.ts"],"sourcesContent":["// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * `@objectstack/types/node` — the **node-only** slice of the shared utilities.\n *\n * WHY A SUBPATH AND NOT THE ROOT EXPORT. `@objectstack/types` is a dependency of\n * `@objectstack/hono`, whose whole reason to exist is \"edge-compatible REST API\n * server for Cloudflare Workers, Deno, Bun, and Node\" — and of the plugin/service\n * layer a `LiteKernel` boots on Workers. The root entry (`src/index.ts`) reaches\n * **zero** `node:` builtins today, and that is a property those consumers depend\n * on: a Workers bundle that pulls in `node:module` fails to build (or dies at\n * first call) even when nothing ever invokes it. Everything here needs\n * `node:module` / `node:url` by definition — it exists to drive Node's own\n * resolver — so it lives behind its own entry point instead.\n *\n * The isolation is structural, not conventional: `tsup` builds `src/index.ts` and\n * `src/node.ts` as separate entries with `splitting: false`, so the root bundle\n * contains no reference to this file, and `node-isolation.test.ts` fails the\n * build if anything reachable from the root ever imports a `node:` builtin. Same\n * arrangement `@objectstack/metadata` already ships for `./node`.\n *\n * ── What lives here ──────────────────────────────────────────────────────────\n *\n * Resolving optional packages from the **host app**, not from the framework\n * package doing the importing.\n *\n * Node ESM resolves a bare `import('pkg')` against the **importer's own\n * realpath**. Framework packages (the CLI, `@objectstack/verify`,\n * `@objectstack/dogfood`) are reached through `link:`/workspace dependencies, so\n * their realpath is inside the *framework* workspace — a bare import from any of\n * them can only ever see packages installed in the framework's own\n * `node_modules`. Every package that lives OUTSIDE that workspace and is supplied\n * by the app being served, verified or tested — a cloud-private package such as\n * `@objectstack/organizations` or `@objectstack/service-ai-studio`, or anything a\n * customer installs into their own project — is therefore invisible to a bare\n * import, no matter what the host app declares in its `package.json`\n * (cloud#1013: `objectstack serve` could never load the enterprise multi-org\n * runtime, so every self-hosted walled-posture deployment hit the ADR-0093 D5\n * fail-fast and exited 1; framework#4700: `bootStack({ multiTenant: true })` told\n * apps to install a package they had already installed, and the dogfood\n * multi-org probes were constant-false).\n *\n * The fix is to resolve from the host app's root and import the resolved\n * absolute path. The importing package's own resolution stays as the fallback,\n * for the framework-owned packages it depends on and the host does not declare\n * — and since #10943 that fallback is the base the CALLER hands in\n * ({@link HostImporterOptions.fallbackImport}), because a fallback written here\n * resolved from `@objectstack/types` and could only ever see\n * `@objectstack/spec`. Same defect class as the paragraph above, one level up:\n * a bare import resolves against the module that CONTAINS it, and this module\n * is not the one doing the asking.\n *\n * Resolution failure is the ONLY thing that falls back. A package the host\n * resolves but that throws while it evaluates is a genuine crash and propagates\n * unchanged: re-importing it bare would replace the real cause with a\n * `MODULE_NOT_FOUND`, which every caller here classifies as \"not installed\" —\n * turning a broken package into a silent skip (or, on the organizations path,\n * into a fatal message telling the operator to install what is already there).\n *\n * ── #4719: the host's DECLARATION gates the lookup, not its resolvability ────\n *\n * \"Resolve from the host app\" was implemented as a CJS `createRequire` anchored\n * at the host's `package.json`, and **CJS resolution honours `NODE_PATH`**\n * (`Module.globalPaths`). The first thing a pnpm-generated bin shim does is\n *\n * export NODE_PATH=\"<workspace>/node_modules/.pnpm/node_modules\"\n *\n * and every `serve` / `dev` child process inherits it. Everything any package in\n * the workspace transitively depends on lives in that hoisted store, so\n * `hostRequire.resolve(pkg)` succeeded for packages the host app had never\n * declared — the answer depended on HOW THE PROCESS WAS LAUNCHED, not on the\n * app. Measured on cloud's `apps/objectos-ee`, which did not declare\n * `@objectstack/organizations`: `pnpm start` (through the shim) booted with the\n * organizations plugin mounted and ADR-0093 D5 silent, while\n * `node node_modules/@objectstack/cli/bin/run.js serve` (no shim, no NODE_PATH)\n * hit the D5 fail-fast and exited 1. Same app, same `package.json`, same\n * posture. D5's own message told operators to \"declare it in the app's\n * package.json\" — the one thing the CLI never checked.\n *\n * So the host lookup is now gated on the host's **declaration**: a package name\n * is looked up in the host's `node_modules` only when it appears in the host\n * `package.json` (see {@link HOST_DECLARATION_FIELDS}). Reachability through a\n * hoisted store or `NODE_PATH` is deliberately not accepted — it is precisely\n * the accident that made the contract unenforced. This is the \"declared =\n * enforced\" shape the rest of the repo uses (Prime Directive #10): the\n * declaration is a deliberate authoring act, machine-checkable at the moment of\n * boot, and independent of launcher, package manager and hoist layout.\n *\n * The two failures it separates were, until now, one indistinguishable\n * `MODULE_NOT_FOUND`, with opposite remedies:\n *\n * - **undeclared** — the app never asked for this package. Remedy: declare it\n * in the app's `package.json` and install.\n * - **declared but unresolvable** — the app asked for it and the install is\n * broken/pruned/unbuilt. Remedy: fix the install. Re-reading the\n * `package.json` is wasted effort; the declaration is right there.\n *\n * {@link hostImportFailureKind} exposes that classification to callers so their\n * fail-fast text can say which one it is (`packages/cli` ADR-0093 D5,\n * `packages/verify` `bootStack`, `packages/qa/dogfood`'s enterprise probe).\n */\n\nimport { readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { isModuleNotFoundError } from './module-not-found.js';\n\n/**\n * Imports a package as the host app would see it.\n *\n * `any` is the module namespace of a package this repo does not compile against\n * (it is not a dependency of the importing package at all) — every call site\n * reads an export off it dynamically, exactly as the bare `import()` it replaces\n * did.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HostImporter = (pkg: string) => Promise<any>;\n\n/**\n * The importing package's OWN dynamic import — write it literally, in the\n * calling module:\n *\n * createHostImporter(hostRoot, { fallbackImport: (s) => import(s) })\n *\n * `any` for the same reason {@link HostImporter} uses it: the module namespace\n * belongs to a package this repo does not compile against.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type FallbackImport = (specifier: string) => Promise<any>;\n\n/** Options for {@link createHostImporter}. */\nexport interface HostImporterOptions {\n /**\n * The resolution base for everything the host app does NOT declare — supplied\n * as the caller's own `import()` rather than as a URL string, because a\n * string base was MEASURED to be unimplementable without a regression. See\n * {@link createHostImporter}'s \"why a function\" note for both measurements.\n *\n * Omitted ⇒ the fallback resolves from `@objectstack/types`, which sees only\n * `@objectstack/types`'s own dependencies. That default is retained so an\n * out-of-tree caller cannot be broken by this parameter's arrival, and the\n * `undeclared` failure text names it explicitly so the gap reports itself\n * instead of being rediscovered.\n */\n fallbackImport?: FallbackImport;\n}\n\n/**\n * A `require` anchored at the **host app's** `package.json` — i.e. the project\n * `objectstack serve` was invoked in, or the app `bootStack` is verifying, whose\n * `node_modules` carries the packages it declares.\n *\n * @param hostRoot Directory holding the host app's `package.json` (default: the\n * process CWD, which is where the CLI reads `objectstack.config.ts` from too).\n */\nexport function createHostRequire(hostRoot: string = process.cwd()): NodeRequire {\n return createRequire(join(hostRoot, 'package.json'));\n}\n\n/**\n * The `package.json` fields whose KEYS count as a host-app declaration (#4719).\n *\n * All four are deliberate authoring acts in the app's own manifest that name the\n * package, which is the signal this gate is built on — not \"is it reachable\".\n * Why each is in:\n *\n * - `dependencies` — the obvious one: the app runs with it.\n * - `devDependencies` — the app being served / verified / dogfooded IS the\n * project, not a library someone else consumes, so its dev deps are installed\n * in exactly the environment this resolver runs in.\n * - `optionalDependencies` — npm/pnpm install them and tolerate an install\n * failure. \"Installed ⇒ declared\" holds; and if it did NOT install, the\n * declared-but-unresolvable branch says so precisely instead of pretending the\n * app never asked.\n * - `peerDependencies` — an app is nobody's peer, so this is an unusual place to\n * put an enterprise add-on; but it still NAMES the package on purpose, and\n * `packages/cli`'s own edition gate (`serve`'s AI-service opt-in, #1597) has\n * read all four since it was written. Accepting three here and four there\n * would fork \"declared\" into two dialects for one question — the shape Prime\n * Directive #12 exists to prevent. That gate now delegates to this list, so\n * there is one owner and one answer.\n *\n * `bundleDependencies` is absent on purpose: it is an array of names that must\n * ALSO appear in `dependencies`, so it can never be the only declaration.\n */\nexport const HOST_DECLARATION_FIELDS = [\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n 'peerDependencies',\n] as const;\n\nexport type HostDeclarationField = (typeof HOST_DECLARATION_FIELDS)[number];\n\n/** What the host app's `package.json` says about one package name. */\nexport interface HostDeclaration {\n /** Bare package name the specifier belongs to (subpath stripped). */\n packageName: string;\n /** Directory whose `package.json` was consulted. */\n hostRoot: string;\n /** True when {@link packageName} is a key of one of {@link HOST_DECLARATION_FIELDS}. */\n declared: boolean;\n /** Which field carried it (first match, in {@link HOST_DECLARATION_FIELDS} order). */\n field?: HostDeclarationField;\n /** The version range AS WRITTEN — `^1.2.3`, `workspace:*`, `npm:@acme/x@1`, `link:../x`. */\n specifier?: string;\n /** True when `hostRoot` has no readable / parseable `package.json` at all. */\n manifestMissing?: boolean;\n}\n\n/**\n * The package a bare specifier belongs to, or `undefined` when the specifier is\n * not a bare package name at all (a relative/absolute path, a `file:`/`data:`\n * URL, or a `node:`-prefixed builtin). Those bypass the declaration gate: they\n * are not things a `package.json` can declare.\n *\n * Subpaths are stripped, so `@objectstack/platform-objects/plugin` is declared\n * by `\"@objectstack/platform-objects\"`, which is the only key that can exist.\n * Scoped names keep both segments.\n *\n * Alias dependencies need no special case, and that is the point: with\n * `\"foo\": \"npm:bar@1\"` the importable specifier is `foo` and the manifest key is\n * `foo`, so keying on the KEY (never the value) is exactly right — `import('bar')`\n * correctly reads as undeclared unless `bar` is itself a key. Same for\n * `workspace:` / `link:` / `file:` specifiers: the key is the name, the value is\n * the package manager's business.\n */\nexport function packageNameFromSpecifier(specifier: string): string | undefined {\n if (!specifier || specifier.startsWith('.') || specifier.startsWith('/')) return undefined;\n // A URL-ish or protocol-prefixed specifier (`node:fs`, `file:///…`, `data:…`).\n if (/^[a-z][a-z0-9+.-]*:/i.test(specifier)) return undefined;\n const segments = specifier.split('/');\n if (specifier.startsWith('@')) {\n if (segments.length < 2 || !segments[0] || !segments[1]) return undefined;\n return `${segments[0]}/${segments[1]}`;\n }\n return segments[0] || undefined;\n}\n\n/**\n * Read what the host app's `package.json` declares about `specifier`.\n *\n * Deliberately a plain manifest READ, never a resolution attempt: resolvability\n * is the property #4719 proved unreliable (it moved with `NODE_PATH` and the\n * hoist layout), while the manifest is the same fact in every launcher.\n */\nexport function readHostDeclaration(\n specifier: string,\n hostRoot: string = process.cwd(),\n): HostDeclaration {\n const packageName = packageNameFromSpecifier(specifier) ?? specifier;\n const base: HostDeclaration = { packageName, hostRoot, declared: false };\n\n let manifest: Record<string, unknown>;\n try {\n manifest = JSON.parse(readFileSync(join(hostRoot, 'package.json'), 'utf8')) as Record<\n string,\n unknown\n >;\n } catch {\n // No manifest ⇒ nothing is declared. Recorded rather than swallowed so the\n // failure text can say \"there is no package.json here\" instead of the\n // misleading \"you did not declare it\".\n return { ...base, manifestMissing: true };\n }\n\n for (const field of HOST_DECLARATION_FIELDS) {\n const entries = manifest[field];\n if (!entries || typeof entries !== 'object') continue;\n const specifierValue = (entries as Record<string, unknown>)[packageName];\n if (specifierValue === undefined) continue;\n return { ...base, declared: true, field, specifier: String(specifierValue) };\n }\n return base;\n}\n\n/** Convenience predicate over {@link readHostDeclaration}. */\nexport function isDeclaredByHost(specifier: string, hostRoot?: string): boolean {\n return readHostDeclaration(specifier, hostRoot).declared;\n}\n\n/**\n * Why a {@link HostImporter} could not produce a module.\n *\n * - `undeclared` — the host app's `package.json` never names the package, and\n * the importing framework package cannot supply it either. Remedy: DECLARE it\n * in the app and install.\n * - `declared-unresolvable` — the app declares it and it still would not\n * resolve. Remedy: fix the INSTALL. Re-reading the manifest is wasted effort.\n *\n * An evaluation crash is neither: it propagates untouched and carries no kind.\n */\nexport type HostImportFailureKind = 'undeclared' | 'declared-unresolvable';\n\n/**\n * Property carrying {@link HostImportFailureKind} on a thrown error.\n *\n * A string property, read by {@link hostImportFailureKind} — never `instanceof`.\n * `serve` loads plugins through this importer, so CLI and package can hold\n * different module instances of anything class-shaped; the #4818 comment in\n * `serve.ts` names that trap explicitly.\n */\nexport const HOST_IMPORT_FAILURE_KIND = 'objectstackHostImportFailureKind';\n\n/** The classification on an error thrown by a {@link HostImporter}, if any. */\nexport function hostImportFailureKind(err: unknown): HostImportFailureKind | undefined {\n const kind = (err as Record<string, unknown> | null | undefined)?.[HOST_IMPORT_FAILURE_KIND];\n return kind === 'undeclared' || kind === 'declared-unresolvable' ? kind : undefined;\n}\n\nfunction hostImportError(\n kind: HostImportFailureKind,\n message: string,\n cause: unknown,\n): Error {\n // `cause` is assigned rather than passed to the constructor: this package\n // compiles against a lib without the ES2022 `ErrorOptions` overload.\n const err = new Error(message);\n // Every caller classifies \"missing vs crashed\" through\n // `isModuleNotFoundError`; both of these ARE the missing case, just with\n // different remedies, so they must keep answering true to it.\n return Object.assign(err, {\n cause,\n code: 'MODULE_NOT_FOUND',\n [HOST_IMPORT_FAILURE_KIND]: kind,\n });\n}\n\n/**\n * @param callerBaseSupplied Did the caller state its own resolution base\n * ({@link HostImporterOptions.fallbackImport})? When it did not, the fallback\n * ran from `@objectstack/types`, which sees only `@objectstack/spec` — so the\n * absence being reported may be an artefact of the missing base rather than a\n * real one. #10943 kept that default for out-of-tree callers; saying so here is\n * what stops it being silent, because the alternative is a reader re-deriving\n * the whole measurement from a `MODULE_NOT_FOUND` that names nothing.\n */\nfunction undeclaredMessage(\n declaration: HostDeclaration,\n cause: unknown,\n callerBaseSupplied: boolean,\n): string {\n const { packageName, hostRoot, manifestMissing } = declaration;\n const detail = cause instanceof Error ? cause.message : String(cause);\n const baseNote = callerBaseSupplied\n ? ''\n : '\\n (the caller did not pass `fallbackImport`, so that fallback resolved from\\n' +\n \" @objectstack/types, which can see only its own dependencies — a caller that\\n\" +\n ' needs its own resolution passes `{ fallbackImport: (s) => import(s) }`, #10943)';\n return (\n `Cannot find package '${packageName}': the host app does not declare it.\\n` +\n ` host app: ${hostRoot}\\n` +\n (manifestMissing\n ? ' no readable package.json was found there — nothing can be declared\\n'\n : ` checked: ${HOST_DECLARATION_FIELDS.join(', ')}\\n`) +\n `\\n Declare it in that app's package.json and install it, e.g.\\n` +\n ` cd ${hostRoot} && pnpm add ${packageName}\\n` +\n '\\n Being merely REACHABLE is not enough and is rejected on purpose (#4719):\\n' +\n ' a package hoisted into a workspace store — which is what NODE_PATH points\\n' +\n \" at in every pnpm bin shim — used to resolve here regardless of the app's\\n\" +\n ' package.json, so the same app booted or refused depending on how the\\n' +\n ' process was launched. The declaration is the contract.\\n' +\n ` (fallback resolution also failed: ${detail})${baseNote}`\n );\n}\n\nfunction unresolvableMessage(declaration: HostDeclaration, cause: unknown): string {\n const { packageName, hostRoot, field, specifier } = declaration;\n const detail = cause instanceof Error ? cause.message : String(cause);\n return (\n `Cannot find module '${packageName}': the host app DECLARES it ` +\n `(${field}: ${JSON.stringify(specifier)}) but it could not be resolved.\\n` +\n ` host app: ${hostRoot}\\n` +\n '\\n This is an INSTALL problem, not a declaration problem — the declaration is\\n' +\n ' already there, so re-reading the package.json will not help. Check:\\n' +\n ` • dependencies never installed, or installed before the declaration was added → run \\`pnpm install\\` in ${hostRoot}\\n` +\n ' • a production prune / filtered deploy dropped it (devDependencies and\\n' +\n ' optionalDependencies go first)\\n' +\n ' • it IS installed but its \"main\"/\"exports\" points at a dist that was never built\\n' +\n ` (resolver: ${detail})`\n );\n}\n\n/**\n * Build an importer that loads a package **as the host app declares it**, and\n * otherwise falls back to the importing package's own resolution.\n *\n * Order of operations, and why (#4719):\n *\n * 1. The host `package.json` is READ. Only a declared name is looked up in the\n * host's `node_modules`. An undeclared name never reaches the host resolver,\n * so no amount of `NODE_PATH` / hoisting can make it appear to be the app's.\n * 2. Declared but unresolvable is reported AS SUCH — the app asked for it and\n * the install is broken. It is not retried bare: falling back there would\n * reintroduce exactly the \"some other package happens to supply it\" accident\n * this gate closes, and would report an install problem as an absence.\n * 3. Undeclared falls back to the CALLER's own resolution, which is what keeps\n * every framework-owned load working (`serve`'s plugin-auth / service-i18n\n * path, `bootStack`'s service plugins). Bare `import()` is ESM, and ESM does\n * not honour `NODE_PATH`, so the fallback cannot re-open the hole either.\n * Only when that fails as module-not-found does the undeclared error\n * surface; a package that RESOLVES and then throws while evaluating is a\n * genuine crash and propagates untouched, as before.\n *\n * ── The caller supplies that base, and why it is a FUNCTION (#10943) ─────────\n *\n * Step 3 said \"the importing package's own resolution\" long before anything\n * made it true. The fallback was a bare `import()` written HERE, and ESM\n * resolves a bare specifier against the module containing the call — so it\n * resolved from `@objectstack/types`, which under a pnpm-isolated layout can\n * see only `@objectstack/types`'s own dependencies. Measured on `main` from an\n * app declaring nothing, `@objectstack/plugin-auth`, `@objectstack/plugin-audit`\n * and `chalk` all resolve from `packages/cli` and all failed through this\n * helper; `@objectstack/spec` — the one dependency this package declares — was\n * the only name that came back OK, which is the whole pattern. Under a hoisted\n * npm/yarn layout the same fallback usually DOES find the caller's\n * dependencies, so the claim was green in some installs and absent in others:\n * the layout-dependence class cloud#1013 and #10645 exist to close, one level\n * up. A declared contract the implementation does not keep is the thing this\n * repo fixes at the producer (Prime Directive #12), so the mechanism moved\n * rather than the sentence.\n *\n * The base arrives as the caller's own `import()` and NOT as a `parentURL` /\n * `import.meta.url` string. Both string spellings were measured on Node\n * v22.22.2 and both are wrong:\n *\n * - `import.meta.resolve(specifier, parentURL)` — the parent argument is\n * SILENTLY IGNORED without `--experimental-import-meta-resolve`. Measured:\n * resolving `@objectstack/plugin-auth` against a `packages/types` parent\n * returned `packages/cli/node_modules/...`, i.e. the caller's own answer,\n * byte-identical to passing no parent at all. It would have compiled, run,\n * and pinned green while ignoring the base — a phantom fix of exactly the\n * kind this card is about.\n * - `createRequire(parentURL).resolve(specifier)` — CJS resolution, which\n * honours `NODE_PATH`. Measured against a store reachable only through\n * `NODE_PATH`: the CJS resolve found it (with and without the `paths`\n * option, since GLOBAL_FOLDERS are always appended) while the ESM bare\n * `import()` did not. That is #4719's hole re-opened on the fallback path,\n * and it would have falsified the \"ESM does not honour NODE_PATH\" sentence\n * three lines above.\n *\n * A function written in the calling module is the only spelling that uses\n * Node's real ESM resolver anchored where the caller actually lives: no flag,\n * no `NODE_PATH`, no second resolution algorithm to drift from the first.\n *\n * @param hostRoot Directory holding the host app's `package.json` (default: the\n * process CWD, which is where the CLI reads `objectstack.config.ts` from too).\n * Note this used to take a pre-built `NodeRequire`; it needs the ROOT now,\n * because a `NodeRequire` cannot be asked where it was anchored and the manifest\n * has to be read from there.\n * @param options {@link HostImporterOptions.fallbackImport} carries the caller's\n * resolution base. Omitting it keeps the pre-#10943 behaviour (this package's\n * own resolution) so no out-of-tree caller changes under its feet.\n */\nexport function createHostImporter(\n hostRoot: string = process.cwd(),\n options: HostImporterOptions = {},\n): HostImporter {\n const hostRequire = createHostRequire(hostRoot);\n const { fallbackImport } = options;\n const importAsCaller: FallbackImport =\n fallbackImport ?? ((specifier) => import(/* webpackIgnore: true */ specifier));\n return async (pkg: string): Promise<any> => {\n // Not a bare package name (a path, a URL, a `node:` builtin) — nothing a\n // manifest could declare. Hand it to the normal resolver untouched.\n //\n // ⚠️ Deliberately NOT re-based onto `fallbackImport` (#10943). Every\n // base-INDEPENDENT spelling here — `file://`, `node:`, `data:`, an absolute\n // path — means the same module whoever imports it, so the base is not a\n // question they can even ask. The one spelling it WOULD move is a RELATIVE\n // one, and where that should resolve from is an open policy question owned\n // by #10944 (`serve` refuses a relative `plugins: [...]` entry rather than\n // silently re-basing it) — with a measured consumer count of zero here:\n // `serve` handles non-package specifiers before this helper is reached, and\n // `bootStack` / the dogfood probe pass package names only. Answering half\n // of another card's undecided question, for nobody, is not a repair.\n if (packageNameFromSpecifier(pkg) === undefined) {\n return import(/* webpackIgnore: true */ pkg);\n }\n\n const declaration = readHostDeclaration(pkg, hostRoot);\n\n if (declaration.declared) {\n let resolved: string;\n try {\n resolved = hostRequire.resolve(pkg);\n } catch (cause) {\n throw hostImportError(\n 'declared-unresolvable',\n unresolvableMessage(declaration, cause),\n cause,\n );\n }\n return import(pathToFileURL(resolved).href);\n }\n\n try {\n return await importAsCaller(pkg);\n } catch (cause) {\n // A package that resolved and then exploded is a crash, not an absence.\n if (!isModuleNotFoundError(cause)) throw cause;\n throw hostImportError(\n 'undeclared',\n undeclaredMessage(declaration, cause, fallbackImport !== undefined),\n cause,\n );\n }\n };\n}\n","// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\n/**\n * True when a dynamic `import()` / `require.resolve()` failed because the\n * module is simply NOT INSTALLED — as opposed to the module being present but\n * throwing while it loads (a real crash). Checking `err.code` FIRST matters:\n * ESM reports a missing package as `err.code === 'ERR_MODULE_NOT_FOUND'` with\n * the human message `Cannot find package '...'`; matching only the older\n * `Cannot find module` string mis-classifies that as a crash (framework#1595).\n *\n * Single shared owner for this classification (framework#3265): the CLI's\n * optional-plugin guards and `requires` capability resolver delegate here, and\n * cloud's `objectos-runtime` capability loader is expected to adopt it at its\n * next framework pin bump — so the parallel loaders cannot drift apart and\n * re-introduce the #1595 false-alarm class.\n */\nexport function isModuleNotFoundError(err: unknown): boolean {\n const code = (err as { code?: string } | null | undefined)?.code;\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') return true;\n const msg = err instanceof Error ? err.message : String(err);\n return msg.includes('Cannot find module') || msg.includes('Cannot find package');\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/node.ts","../src/module-not-found.ts"],"mappings":"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","names":[]}
|
package/dist/node.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/node.ts
|
|
2
|
-
import { readFileSync } from "fs";
|
|
2
|
+
import { existsSync, readFileSync, realpathSync } from "fs";
|
|
3
3
|
import { createRequire } from "module";
|
|
4
|
-
import { join } from "path";
|
|
4
|
+
import { dirname, join, resolve, sep } from "path";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
6
|
|
|
7
7
|
// src/module-not-found.ts
|
|
@@ -56,7 +56,7 @@ function isDeclaredByHost(specifier, hostRoot) {
|
|
|
56
56
|
var HOST_IMPORT_FAILURE_KIND = "objectstackHostImportFailureKind";
|
|
57
57
|
function hostImportFailureKind(err) {
|
|
58
58
|
const kind = err?.[HOST_IMPORT_FAILURE_KIND];
|
|
59
|
-
return kind === "undeclared" || kind === "declared-unresolvable" ? kind : void 0;
|
|
59
|
+
return kind === "undeclared" || kind === "declared-unresolvable" || kind === "declared-no-loadable-entry" ? kind : void 0;
|
|
60
60
|
}
|
|
61
61
|
function hostImportError(kind, message, cause) {
|
|
62
62
|
const err = new Error(message);
|
|
@@ -98,6 +98,186 @@ function unresolvableMessage(declaration, cause) {
|
|
|
98
98
|
\u2022 it IS installed but its "main"/"exports" points at a dist that was never built
|
|
99
99
|
(resolver: ${detail})`;
|
|
100
100
|
}
|
|
101
|
+
var ESM_IMPORT_CONDITIONS = /* @__PURE__ */ new Set([
|
|
102
|
+
"node-addons",
|
|
103
|
+
"node",
|
|
104
|
+
"import",
|
|
105
|
+
"default"
|
|
106
|
+
]);
|
|
107
|
+
var CJS_REQUIRE_CONDITIONS = /* @__PURE__ */ new Set([
|
|
108
|
+
"node-addons",
|
|
109
|
+
"node",
|
|
110
|
+
"require",
|
|
111
|
+
"default"
|
|
112
|
+
]);
|
|
113
|
+
function selectConditionTarget(node, conditions) {
|
|
114
|
+
if (typeof node === "string") return node;
|
|
115
|
+
if (Array.isArray(node)) {
|
|
116
|
+
for (const alternative of node) {
|
|
117
|
+
const hit = selectConditionTarget(alternative, conditions);
|
|
118
|
+
if (hit !== void 0) return hit;
|
|
119
|
+
}
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
123
|
+
for (const entry of Object.entries(node)) {
|
|
124
|
+
if (!conditions.has(entry[0])) continue;
|
|
125
|
+
const hit = selectConditionTarget(entry[1], conditions);
|
|
126
|
+
if (hit !== void 0) return hit;
|
|
127
|
+
}
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
function resolveExportsSubpath(exportsField, subpath, conditions = ESM_IMPORT_CONDITIONS) {
|
|
131
|
+
if (exportsField === void 0) return void 0;
|
|
132
|
+
const keys = typeof exportsField === "object" && exportsField !== null && !Array.isArray(exportsField) ? Object.keys(exportsField) : void 0;
|
|
133
|
+
const isSubpathMap = keys !== void 0 && keys.length > 0 && keys.every((key) => key === "." || key.indexOf("./") === 0);
|
|
134
|
+
if (!isSubpathMap) {
|
|
135
|
+
return subpath === "." ? selectConditionTarget(exportsField, conditions) : void 0;
|
|
136
|
+
}
|
|
137
|
+
const map = exportsField;
|
|
138
|
+
if (Object.prototype.hasOwnProperty.call(map, subpath)) {
|
|
139
|
+
return selectConditionTarget(map[subpath], conditions);
|
|
140
|
+
}
|
|
141
|
+
let best;
|
|
142
|
+
for (const entry of Object.entries(map)) {
|
|
143
|
+
const star = entry[0].indexOf("*");
|
|
144
|
+
if (star < 0 || entry[0].indexOf("*", star + 1) >= 0) continue;
|
|
145
|
+
const prefix = entry[0].slice(0, star);
|
|
146
|
+
const suffix = entry[0].slice(star + 1);
|
|
147
|
+
if (subpath.indexOf(prefix) !== 0) continue;
|
|
148
|
+
if (suffix !== "" && subpath.slice(subpath.length - suffix.length) !== suffix) continue;
|
|
149
|
+
if (subpath.length < prefix.length + suffix.length) continue;
|
|
150
|
+
if (best !== void 0 && (best.prefix.length > prefix.length || best.prefix.length === prefix.length && best.suffix.length >= suffix.length)) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
best = { prefix, suffix, target: entry[1] };
|
|
154
|
+
}
|
|
155
|
+
if (best === void 0) return void 0;
|
|
156
|
+
const matched = subpath.slice(best.prefix.length, subpath.length - best.suffix.length);
|
|
157
|
+
const target = selectConditionTarget(best.target, conditions);
|
|
158
|
+
return target === void 0 ? void 0 : target.split("*").join(matched);
|
|
159
|
+
}
|
|
160
|
+
function exportsSubpathOf(specifier, packageName) {
|
|
161
|
+
return specifier === packageName ? "." : `.${specifier.slice(packageName.length)}`;
|
|
162
|
+
}
|
|
163
|
+
var ALIAS_DECLARATION_PROTOCOLS = [
|
|
164
|
+
{ prefix: "npm:", rangeRequired: false },
|
|
165
|
+
{ prefix: "workspace:", rangeRequired: true }
|
|
166
|
+
];
|
|
167
|
+
function declaredManifestName(declaration) {
|
|
168
|
+
const { packageName, specifier } = declaration;
|
|
169
|
+
if (specifier === void 0) return packageName;
|
|
170
|
+
const protocol = ALIAS_DECLARATION_PROTOCOLS.find((p) => specifier.indexOf(p.prefix) === 0);
|
|
171
|
+
if (protocol === void 0) return packageName;
|
|
172
|
+
const value = specifier.slice(protocol.prefix.length);
|
|
173
|
+
const at = value.lastIndexOf("@");
|
|
174
|
+
if (at <= 0 && protocol.rangeRequired) return packageName;
|
|
175
|
+
const name = at > 0 ? value.slice(0, at) : value;
|
|
176
|
+
return packageNameFromSpecifier(name) === name ? name : packageName;
|
|
177
|
+
}
|
|
178
|
+
function packageRootOf(resolvedFile, manifestName) {
|
|
179
|
+
let dir = dirname(resolvedFile);
|
|
180
|
+
for (let hop = 0; hop < 64; hop += 1) {
|
|
181
|
+
try {
|
|
182
|
+
const manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
183
|
+
if (manifest.name === manifestName) return dir;
|
|
184
|
+
} catch {
|
|
185
|
+
}
|
|
186
|
+
const parent = dirname(dir);
|
|
187
|
+
if (parent === dir) return void 0;
|
|
188
|
+
dir = parent;
|
|
189
|
+
}
|
|
190
|
+
return void 0;
|
|
191
|
+
}
|
|
192
|
+
function esmEntryForDeclared(specifier, declaration, cjsResolved) {
|
|
193
|
+
const { packageName } = declaration;
|
|
194
|
+
const root = packageRootOf(cjsResolved, declaredManifestName(declaration));
|
|
195
|
+
if (root === void 0) return void 0;
|
|
196
|
+
let exportsField;
|
|
197
|
+
try {
|
|
198
|
+
exportsField = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).exports;
|
|
199
|
+
} catch {
|
|
200
|
+
return void 0;
|
|
201
|
+
}
|
|
202
|
+
if (exportsField === void 0 || exportsField === null) return void 0;
|
|
203
|
+
const subpath = exportsSubpathOf(specifier, packageName);
|
|
204
|
+
const target = resolveExportsSubpath(exportsField, subpath);
|
|
205
|
+
if (typeof target !== "string" || target.indexOf("./") !== 0) return void 0;
|
|
206
|
+
const entry = resolve(root, target);
|
|
207
|
+
if (entry.indexOf(root + sep) !== 0) return void 0;
|
|
208
|
+
return existsSync(entry) ? entry : void 0;
|
|
209
|
+
}
|
|
210
|
+
function hasInvalidExportsSubpathSegments(subpath) {
|
|
211
|
+
if (subpath === ".") return false;
|
|
212
|
+
return subpath.slice(2).split(/[/\\]/).some((raw) => {
|
|
213
|
+
const segment = raw.toLowerCase();
|
|
214
|
+
return segment === "" || segment === "." || segment === ".." || segment === "node_modules";
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function hostInstalledPackageDir(declaration) {
|
|
218
|
+
const { packageName, hostRoot } = declaration;
|
|
219
|
+
const linked = join(hostRoot, "node_modules", ...packageName.split("/"));
|
|
220
|
+
try {
|
|
221
|
+
const manifest = JSON.parse(readFileSync(join(linked, "package.json"), "utf8"));
|
|
222
|
+
if (manifest.name !== declaredManifestName(declaration)) return void 0;
|
|
223
|
+
} catch {
|
|
224
|
+
return void 0;
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
return realpathSync(linked);
|
|
228
|
+
} catch {
|
|
229
|
+
return linked;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function declaredCjsResolveFallback(specifier, declaration) {
|
|
233
|
+
const { packageName } = declaration;
|
|
234
|
+
const packageDir = hostInstalledPackageDir(declaration);
|
|
235
|
+
if (packageDir === void 0) return { outcome: "absent" };
|
|
236
|
+
let exportsField;
|
|
237
|
+
try {
|
|
238
|
+
exportsField = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8")).exports;
|
|
239
|
+
} catch {
|
|
240
|
+
return { outcome: "absent" };
|
|
241
|
+
}
|
|
242
|
+
if (exportsField === void 0 || exportsField === null) return { outcome: "install-broken" };
|
|
243
|
+
const subpath = exportsSubpathOf(specifier, packageName);
|
|
244
|
+
if (hasInvalidExportsSubpathSegments(subpath)) return { outcome: "invalid-specifier" };
|
|
245
|
+
const importTarget = resolveExportsSubpath(exportsField, subpath, ESM_IMPORT_CONDITIONS);
|
|
246
|
+
if (typeof importTarget === "string" && importTarget.indexOf("./") === 0) {
|
|
247
|
+
const entry = resolve(packageDir, importTarget);
|
|
248
|
+
if (entry.indexOf(packageDir + sep) === 0 && existsSync(entry)) {
|
|
249
|
+
return { outcome: "entry", entry };
|
|
250
|
+
}
|
|
251
|
+
return { outcome: "install-broken" };
|
|
252
|
+
}
|
|
253
|
+
const requireTarget = resolveExportsSubpath(exportsField, subpath, CJS_REQUIRE_CONDITIONS);
|
|
254
|
+
if (typeof requireTarget === "string" && requireTarget.indexOf("./") === 0) {
|
|
255
|
+
return { outcome: "install-broken" };
|
|
256
|
+
}
|
|
257
|
+
return { outcome: "no-loadable-entry", packageDir };
|
|
258
|
+
}
|
|
259
|
+
function noLoadableEntryMessage(declaration, packageDir, subpath, cause) {
|
|
260
|
+
const { packageName, hostRoot, field, specifier } = declaration;
|
|
261
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
262
|
+
const subpathNote = subpath === "." ? 'its main entry (".")' : `the subpath '${subpath}'`;
|
|
263
|
+
return `Cannot load module '${packageName}': the host app DECLARES it (${field}: ${JSON.stringify(specifier)}) and it IS installed, but the package publishes no entry that Node can load.
|
|
264
|
+
host app: ${hostRoot}
|
|
265
|
+
installed at: ${packageDir}
|
|
266
|
+
|
|
267
|
+
This is a problem with the PACKAGE's own published shape, not with the app or
|
|
268
|
+
its install \u2014 the declaration is right and the package is on disk, so neither
|
|
269
|
+
re-reading package.json nor re-running \`pnpm install\` can change anything.
|
|
270
|
+
Measured from its manifest:
|
|
271
|
+
\u2022 its "exports" map names no \`require\`-condition entry for ${subpathNote},
|
|
272
|
+
so a CommonJS resolution cannot see it at all
|
|
273
|
+
\u2022 and no \`import\`-condition entry either, so there is nothing for the ESM
|
|
274
|
+
fallback to load
|
|
275
|
+
The remedy lives in the package: it must publish a runtime entry for this
|
|
276
|
+
subpath (an \`import\` condition suffices here; a dual build adds \`require\`).
|
|
277
|
+
A publish carrying only \`types\` / \`browser\`-style conditions cannot be loaded
|
|
278
|
+
by a Node host at all.
|
|
279
|
+
(resolver: ${detail})`;
|
|
280
|
+
}
|
|
101
281
|
function createHostImporter(hostRoot = process.cwd(), options = {}) {
|
|
102
282
|
const hostRequire = createHostRequire(hostRoot);
|
|
103
283
|
const { fallbackImport } = options;
|
|
@@ -118,13 +298,30 @@ function createHostImporter(hostRoot = process.cwd(), options = {}) {
|
|
|
118
298
|
try {
|
|
119
299
|
resolved = hostRequire.resolve(pkg);
|
|
120
300
|
} catch (cause) {
|
|
301
|
+
const fallback = declaredCjsResolveFallback(pkg, declaration);
|
|
302
|
+
if (fallback.outcome === "entry") {
|
|
303
|
+
return import(pathToFileURL(fallback.entry).href);
|
|
304
|
+
}
|
|
305
|
+
if (fallback.outcome === "no-loadable-entry") {
|
|
306
|
+
throw hostImportError(
|
|
307
|
+
"declared-no-loadable-entry",
|
|
308
|
+
noLoadableEntryMessage(
|
|
309
|
+
declaration,
|
|
310
|
+
fallback.packageDir,
|
|
311
|
+
exportsSubpathOf(pkg, declaration.packageName),
|
|
312
|
+
cause
|
|
313
|
+
),
|
|
314
|
+
cause
|
|
315
|
+
);
|
|
316
|
+
}
|
|
121
317
|
throw hostImportError(
|
|
122
318
|
"declared-unresolvable",
|
|
123
319
|
unresolvableMessage(declaration, cause),
|
|
124
320
|
cause
|
|
125
321
|
);
|
|
126
322
|
}
|
|
127
|
-
|
|
323
|
+
const entry = esmEntryForDeclared(pkg, declaration, resolved) ?? resolved;
|
|
324
|
+
return import(pathToFileURL(entry).href);
|
|
128
325
|
}
|
|
129
326
|
try {
|
|
130
327
|
return await importAsCaller(pkg);
|