@nubjs/nub-win32-x64 0.0.19 → 0.0.21

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/bin/nub.exe CHANGED
Binary file
package/bin/nubx.exe CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nubjs/nub-win32-x64",
3
- "version": "0.0.19",
3
+ "version": "0.0.21",
4
4
  "description": "Nub binary for win32-x64",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/nubjs/nub",
Binary file
@@ -1,51 +1,62 @@
1
- // Shared Yarn PnP ESM-resolution helper, used by BOTH realms that resolve modules:
2
- // the main-thread preload (preload-common.cjs, fast tier) and the compat-tier
3
- // loader worker (preload-async-hooks.mjs). Both resolve PnP specifiers identically
4
- // — through PnP's public, conditions-free `resolveRequest` and both must hand
5
- // Node an explicit module `format`, so the logic lives here once rather than being
6
- // copy-pasted across two threads where it could drift.
7
- //
8
- // Why the explicit format: without it, Node <= 20.11 mis-detects a zip-stored `.js`
9
- // file from a `"type":"module"` package as CommonJS, routes it through the CJS
10
- // translator, and `require()`s the ESM source -> ERR_REQUIRE_ESM. Newer Node gets
11
- // it right on its own; emitting the format makes PnP ESM deps work down to the
12
- // 18.19 floor. (CJS resolution stays in preload-common.cjs's `_resolveFilename`
13
- // branch — it returns a path, not a hook result, and is main-thread-only.)
1
+ // Shared Yarn PnP ESM-resolution helper, used by BOTH realms that resolve ESM
2
+ // imports: the main-thread preload (preload-common.cjs, fast tier) and the
3
+ // compat-tier loader worker (preload-async-hooks.mjs). CJS resolution does NOT live
4
+ // here it just strips the `conditions` option and delegates to PnP's own patched
5
+ // `_resolveFilename` (see installCjsRequireHooks). ESM is different: PnP does not
6
+ // patch the ESM loader, so `import` of a PnP dep must be resolved explicitly, AND it
7
+ // must pass the *import* conditions — otherwise a dual package (separate `import` /
8
+ // `require` exports) resolves to its CJS build and `import { x }` fails. So we go
9
+ // through `pnpapi.resolveRequest` (the only PnP resolver that accepts conditions).
14
10
  const { readFileSync } = require("node:fs");
15
- const { join, sep } = require("node:path");
11
+ const { dirname, join, sep } = require("node:path");
16
12
  const { fileURLToPath, pathToFileURL } = require("node:url");
17
13
 
18
- // A directory issuer for pnpapi.resolveRequest: cwd with a trailing separator so
19
- // PnP treats it as a directory. `path.sep` (not a literal "/") keeps it correct on
20
- // Windows, where cwd uses backslashes and a mixed "C:\x/" can confuse resolution.
14
+ // A directory issuer for resolveRequest: cwd with a trailing separator so PnP treats
15
+ // it as a directory. `path.sep` (not a literal "/") keeps it correct on Windows.
21
16
  const cwdIssuer = () => process.cwd() + sep;
22
17
 
23
- // Module format of a PnP-resolved file. `.mjs`/`.cjs` are unambiguous; a `.js` file
24
- // inherits its package's `type` (read via PnP `fs` is zip-patched in both realms).
25
- // `null` lets Node decide (non-JS, or detection failed).
26
- function pnpFormat(pnp, resolvedPath) {
18
+ // Module format of a resolved file. `.mjs`/`.cjs` are unambiguous; a `.js` file
19
+ // inherits its nearest package's `type`, read by walking up to package.json via the
20
+ // zip-patched `fs` (`.pnp.cjs` patches `fs`, so reads inside `.zip` work in both
21
+ // realms). No pnpapi needed. Defaults to "commonjs" if detection fails.
22
+ function formatOf(resolvedPath) {
27
23
  if (resolvedPath.endsWith(".mjs")) return "module";
28
24
  if (resolvedPath.endsWith(".cjs")) return "commonjs";
29
- if (!resolvedPath.endsWith(".js")) return null;
30
- try {
31
- const info = pnp.getPackageInformation(pnp.findPackageLocator(resolvedPath));
32
- const pj = JSON.parse(readFileSync(join(info.packageLocation, "package.json"), "utf8"));
33
- return pj.type === "module" ? "module" : "commonjs";
34
- } catch {
35
- return null;
25
+ let dir = dirname(resolvedPath);
26
+ for (let i = 0; i < 16; i++) {
27
+ try {
28
+ const pj = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
29
+ return pj.type === "module" ? "module" : "commonjs";
30
+ } catch {}
31
+ const up = dirname(dir);
32
+ if (up === dir) break;
33
+ dir = up;
36
34
  }
35
+ return "commonjs";
37
36
  }
38
37
 
39
- // Resolve an ESM `specifier` (from `parentURL`) through PnP and return a Node
40
- // resolve-hook result `{ url, format?, shortCircuit }`, or `null` if PnP can't
41
- // resolve it (then the caller delegates to Node's default resolver). Throwing is
42
- // the caller's signal to fall through too callers wrap in try/catch.
43
- function pnpResolveEsm(pnp, specifier, parentURL) {
38
+ // Resolve a `specifier` through PnP for a hook `context`, applying the correct
39
+ // exports conditions so a dual package resolves to the right build. Returns a Node
40
+ // resolve-hook result `{ url, format, shortCircuit }`, or `null` if PnP can't resolve
41
+ // it (the caller then delegates). Throwing is also a fall-through signal.
42
+ //
43
+ // Conditions: trust `context.conditions` when Node populates it (Node 24+/26 for both
44
+ // import and require; Node 22.15 for import). But Node 22.15 hands the resolve hook
45
+ // an EMPTY `conditions` for a `require()` — so when it's empty, infer the side from
46
+ // `importAttributes` (`undefined` ⇒ a require, an object ⇒ an import) and apply the
47
+ // matching default. Without this a 22.15 `require()` of a dual package would wrongly
48
+ // get the `import` build.
49
+ function pnpResolveEsm(api, specifier, context) {
50
+ const parentURL = context && context.parentURL;
44
51
  const issuer = parentURL ? fileURLToPath(parentURL) : cwdIssuer();
45
- const resolved = pnp.resolveRequest(specifier, issuer);
52
+ let conds = context && context.conditions;
53
+ if (!conds || !conds.length) {
54
+ const isImport = !!context && context.importAttributes !== undefined;
55
+ conds = isImport ? ["node", "import"] : ["node", "require"];
56
+ }
57
+ const resolved = api.resolveRequest(specifier, issuer, { conditions: new Set(conds) });
46
58
  if (!resolved) return null;
47
- const format = pnpFormat(pnp, resolved);
48
- return { url: pathToFileURL(resolved).href, shortCircuit: true, ...(format && { format }) };
59
+ return { url: pathToFileURL(resolved).href, format: formatOf(resolved), shortCircuit: true };
49
60
  }
50
61
 
51
62
  module.exports = { pnpResolveEsm, cwdIssuer };
@@ -61,10 +61,11 @@ export async function resolve(specifier, context, nextResolve) {
61
61
  const r = resolveSpec(specifier, context.parentURL);
62
62
  if (r) return r;
63
63
  // Yarn PnP: resolve deps through PnP's own resolver — identical to the fast tier,
64
- // via the shared helper (resolveRequest + module-format detection).
64
+ // via the shared helper (resolveRequest with the import conditions + format
65
+ // detection), so dual packages resolve to their `import` build.
65
66
  if (__pnp && !isBuiltin(specifier) && !specifier.startsWith("node:")) {
66
67
  try {
67
- const res = pnpResolveEsm(__pnp, specifier, context.parentURL);
68
+ const res = pnpResolveEsm(__pnp, specifier, context);
68
69
  if (res) return res;
69
70
  } catch { /* fall through to Node's resolver */ }
70
71
  }
@@ -142,19 +142,17 @@ function makeHooks(core, watchReporting) {
142
142
  function resolve(specifier, context, nextResolve) {
143
143
  const r = core.resolveSpec(specifier, context.parentURL);
144
144
  if (r) return r;
145
- // Under Yarn PnP, delegating to `nextResolve` flows into Node's default
146
- // resolution, which calls PnP's patched `_resolveFilename` WITH a `conditions`
147
- // option PnP rejects once a customization hook is registered ("aren't supported
148
- // by PnP yet (conditions)"). PnP exposes its own conditions-free resolver —
149
- // `pnpapi.resolveRequest` so resolve through THAT and hand Node the file URL.
150
- // Still "PnP does the resolution" (its public API); nub adds none of its own.
151
- // Returns a virtual `.zip` path for zip-stored deps, which Node reads via the
152
- // zipfs patch `.pnp.cjs` installed. Falls back to `nextResolve` if PnP can't
153
- // resolve (e.g. a builtin or a relative path PnP defers to Node).
145
+ // Yarn PnP (ESM): PnP doesn't patch the ESM loader, so `import` of a PnP dep must
146
+ // be resolved explicitly through `pnpapi.resolveRequest`, passing Node's
147
+ // `context.conditions` (the import-side set) so a DUAL package resolves to its
148
+ // `import` build, not its `require` build. Returns a virtual `.zip` path Node
149
+ // reads via the zipfs patch. If the api is momentarily unavailable we fall through
150
+ // to `nextResolve`, which reaches nub's `_resolveFilename` override (delegating to
151
+ // PnP) — so a plain dep still resolves; only a dual package's condition is lost.
154
152
  const pnp = pnpApi();
155
153
  if (pnp && !module_.isBuiltin(specifier) && !specifier.startsWith("node:")) {
156
154
  try {
157
- const res = pnpResolveEsm(pnp, specifier, context && context.parentURL);
155
+ const res = pnpResolveEsm(pnp, specifier, context);
158
156
  if (res) return res;
159
157
  } catch { /* fall through to Node's resolver */ }
160
158
  }
@@ -302,46 +300,35 @@ function installCjsRequireHooks(core, withClassicTranspile) {
302
300
  }
303
301
  return resolved;
304
302
  }
305
- // Yarn PnP, FAST TIER ONLY. On the fast tier nub registers a sync
306
- // `module.registerHooks` resolve hook, which makes Node thread a `conditions`
307
- // option into PnP's patched `_resolveFilename` ("aren't supported by PnP yet
308
- // (conditions)") AND re-inject it even if we pass none — so we must resolve
309
- // everything ourselves via PnP's conditions-free `pnpapi.resolveRequest` and the
310
- // native path primitives, never falling through to PnP's `_resolveFilename`. On
311
- // the COMPAT tier there is no sync hook, so PnP's own `_resolveFilename` resolves
312
- // CJS deps fine (no conditions option) and interposing here instead recurses to
313
- // OOM on the Node 18 line so the PnP branch is gated to where registerHooks
314
- // exists. `pnpApi()` is null off-PnP, making this doubly safe.
315
- // On a PnP tree + fast tier (sync `registerHooks` registered), resolve through
316
- // PnP's conditions-free `resolveRequest` and NEVER fall through to
317
- // `origResolveFilename` — that is PnP's patched `_resolveFilename`, which rejects
318
- // the `conditions` option Node injects under a registered hook. The gate is
319
- // `process.versions.pnp` (set the moment `.pnp.cjs` runs), NOT a non-null api:
320
- // if `findPnpApi` momentarily misses we still avoid PnP's resolver and use Node's
321
- // native `_findPath`, so a transient lookup miss can't leak a `conditions` crash.
322
- const inPnp = typeof module_.registerHooks === "function" && !!process.versions.pnp;
323
- if (inPnp) {
324
- if (module_.isBuiltin(request)) return request; // PnP defers builtins to Node
325
- const pnp = pnpApi();
326
- if (pnp) {
327
- try {
328
- const issuer = parent && typeof parent.filename === "string" ? parent.filename : cwdIssuer();
329
- const r = pnp.resolveRequest(request, issuer);
330
- if (r) return r;
331
- } catch { /* fall through to native path resolution below */ }
303
+ // Yarn PnP (CJS): `.pnp.cjs` already patched THIS function (origResolveFilename)
304
+ // to resolve from PnP's manifest, including zip-stored deps so we just delegate
305
+ // to it. The one snag is that a registered customization hook makes Node thread a
306
+ // `conditions` option that PnP rejects ("aren't supported by PnP yet
307
+ // (conditions)"), so strip it first. The require/default condition PnP then
308
+ // applies is exactly right for `require()`. (Stripping is a harmless no-op when
309
+ // origResolveFilename is plain Node i.e. not a PnP project.) This replaces the
310
+ // former `pnpapi.resolveRequest` reimplementation: simpler, and with no
311
+ // `findPnpApi` in the hot path there is no lookup-miss to leak a `conditions`
312
+ // crash on Windows.
313
+ if (options && "conditions" in options) {
314
+ options = { ...options };
315
+ delete options.conditions;
316
+ }
317
+ try {
318
+ return origResolveFilename.call(this, request, parent, isMain, options);
319
+ } catch (e) {
320
+ // Under PnP, an in-tree issuer requiring a dep NOT in its manifest makes PnP
321
+ // throw. That is nub's OWN transpile helpers (e.g. `@oxc-project/runtime`),
322
+ // injected into transpiled user code and resolved via NODE_PATH globalPaths
323
+ // (A30). Fall back to Node's native path resolver, which PnP does NOT patch.
324
+ // Gated to PnP so off-PnP a genuine miss surfaces Node's own error unchanged.
325
+ if (process.versions.pnp && e && e.code === "MODULE_NOT_FOUND") {
326
+ const lookupPaths = module_._resolveLookupPaths(request, parent) || [];
327
+ const found = module_._findPath(request, lookupPaths, isMain);
328
+ if (found) return found;
332
329
  }
333
- // PnP couldn't resolve it (nub's OWN vendored deps, whose issuer is nub's
334
- // out-of-tree install dir) or the api was momentarily unavailable. Use Node's
335
- // native path primitives (`_resolveLookupPaths` + `_findPath`), which PnP does
336
- // NOT patch — never `origResolveFilename` (PnP's, + `conditions`).
337
- const lookupPaths = module_._resolveLookupPaths(request, parent) || [];
338
- const found = module_._findPath(request, lookupPaths, isMain);
339
- if (found) return found;
340
- const err = new Error(`Cannot find module '${request}'`);
341
- err.code = "MODULE_NOT_FOUND";
342
- throw err;
330
+ throw e;
343
331
  }
344
- return origResolveFilename.call(this, request, parent, isMain, options);
345
332
  };
346
333
 
347
334
  if (!withClassicTranspile) return;
@@ -9,4 +9,4 @@
9
9
  // previously lived as a literal inside preload.mjs, which `make version` patched,
10
10
  // while the worker carried a hand-maintained "…-compat" copy that `make version`
11
11
  // never touched — a latent staleness bug this module closes.)
12
- export const NUB_VERSION = "0.0.19";
12
+ export const NUB_VERSION = "0.0.21";