@gjsify/cli 0.4.35 → 0.4.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/dist/cli.gjs.mjs +160 -140
- package/lib/bundler-pick.js +43 -4
- package/lib/commands/affected.d.ts +10 -0
- package/lib/commands/affected.js +303 -0
- package/lib/commands/build.js +1 -1
- package/lib/commands/dlx.js +8 -1
- package/lib/commands/index.d.ts +5 -0
- package/lib/commands/index.js +5 -0
- package/lib/commands/install.d.ts +3 -0
- package/lib/commands/install.js +324 -77
- package/lib/commands/login.d.ts +10 -0
- package/lib/commands/login.js +139 -0
- package/lib/commands/logout.d.ts +8 -0
- package/lib/commands/logout.js +63 -0
- package/lib/commands/publish.js +36 -35
- package/lib/commands/tsc.d.ts +6 -0
- package/lib/commands/tsc.js +109 -0
- package/lib/commands/whoami.d.ts +7 -0
- package/lib/commands/whoami.js +118 -0
- package/lib/commands/workspace.d.ts +4 -0
- package/lib/commands/workspace.js +159 -32
- package/lib/index.js +6 -1
- package/lib/utils/auth-npmrc.d.ts +22 -0
- package/lib/utils/auth-npmrc.js +89 -0
- package/lib/utils/install-backend-native.js +236 -89
- package/lib/utils/install-backend.d.ts +19 -0
- package/lib/utils/install-backend.js +1 -0
- package/lib/utils/install-cache-fs.d.ts +22 -0
- package/lib/utils/install-cache-fs.js +64 -0
- package/lib/utils/install-packument-cache.d.ts +18 -0
- package/lib/utils/install-packument-cache.js +98 -0
- package/lib/utils/install-progress.d.ts +26 -0
- package/lib/utils/install-progress.js +109 -0
- package/lib/utils/install-tarball-cache.d.ts +31 -0
- package/lib/utils/install-tarball-cache.js +192 -0
- package/lib/utils/load-npmrc.d.ts +14 -0
- package/lib/utils/load-npmrc.js +61 -0
- package/lib/utils/prompt.d.ts +8 -0
- package/lib/utils/prompt.js +92 -0
- package/lib/utils/publish-diagnose.d.ts +38 -0
- package/lib/utils/publish-diagnose.js +103 -0
- package/lib/utils/resolve-npm-package.d.ts +21 -0
- package/lib/utils/resolve-npm-package.js +121 -0
- package/package.json +29 -18
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Minimal interactive prompts for `gjsify login` — a visible line prompt and a
|
|
2
|
+
// hidden (no-echo) password prompt. Cross-runtime: `process.stdin.setRawMode`
|
|
3
|
+
// is provided by Node and by `@gjsify/process` (terminal-native) under GJS.
|
|
4
|
+
//
|
|
5
|
+
// Non-TTY stdin (piped input, CI) is supported: both helpers read a single line
|
|
6
|
+
// without raw-mode masking, so `printf 'user\npass\n' | gjsify login` works for
|
|
7
|
+
// automation.
|
|
8
|
+
const CTRL_C = String.fromCharCode(3); // ETX (Ctrl-C)
|
|
9
|
+
const DEL = String.fromCharCode(127); // DEL (Backspace on most terminals)
|
|
10
|
+
const BACKSPACE = String.fromCharCode(8); // BS
|
|
11
|
+
/** Print a question and read one line from stdin (visible). */
|
|
12
|
+
export async function promptLine(question) {
|
|
13
|
+
process.stdout.write(question);
|
|
14
|
+
return readLine();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Print a question and read one line WITHOUT echoing it (passwords). Uses raw
|
|
18
|
+
* mode + manual key handling on a TTY; falls back to a plain line read when
|
|
19
|
+
* stdin is not a TTY (piped). Ctrl-C aborts the process.
|
|
20
|
+
*/
|
|
21
|
+
export async function promptHidden(question) {
|
|
22
|
+
process.stdout.write(question);
|
|
23
|
+
const stdin = process.stdin;
|
|
24
|
+
if (!stdin.isTTY || typeof stdin.setRawMode !== 'function') {
|
|
25
|
+
// Non-interactive: read a line as-is (no masking possible/needed).
|
|
26
|
+
return readLine();
|
|
27
|
+
}
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
let buf = '';
|
|
30
|
+
stdin.setRawMode(true);
|
|
31
|
+
stdin.resume();
|
|
32
|
+
stdin.setEncoding('utf-8');
|
|
33
|
+
const onData = (chunk) => {
|
|
34
|
+
for (const ch of chunk) {
|
|
35
|
+
if (ch === '\r' || ch === '\n') {
|
|
36
|
+
cleanup();
|
|
37
|
+
process.stdout.write('\n');
|
|
38
|
+
resolve(buf);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
else if (ch === CTRL_C) {
|
|
42
|
+
cleanup();
|
|
43
|
+
process.stdout.write('\n');
|
|
44
|
+
process.exit(130);
|
|
45
|
+
}
|
|
46
|
+
else if (ch === DEL || ch === BACKSPACE) {
|
|
47
|
+
if (buf.length > 0) {
|
|
48
|
+
buf = buf.slice(0, -1);
|
|
49
|
+
process.stdout.write('\b \b');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (ch >= ' ') {
|
|
53
|
+
buf += ch;
|
|
54
|
+
process.stdout.write('*');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const cleanup = () => {
|
|
59
|
+
stdin.setRawMode(false);
|
|
60
|
+
stdin.removeListener('data', onData);
|
|
61
|
+
stdin.pause();
|
|
62
|
+
};
|
|
63
|
+
stdin.on('data', onData);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** Read a single line from stdin (shared by both prompts on non-TTY). */
|
|
67
|
+
function readLine() {
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
let buf = '';
|
|
70
|
+
const onData = (chunk) => {
|
|
71
|
+
buf += typeof chunk === 'string' ? chunk : chunk.toString('utf-8');
|
|
72
|
+
const nl = buf.indexOf('\n');
|
|
73
|
+
if (nl >= 0) {
|
|
74
|
+
cleanup();
|
|
75
|
+
resolve(buf.slice(0, nl).replace(/\r$/, ''));
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const onEnd = () => {
|
|
79
|
+
cleanup();
|
|
80
|
+
resolve(buf.replace(/\r$/, '').trim());
|
|
81
|
+
};
|
|
82
|
+
const cleanup = () => {
|
|
83
|
+
process.stdin.removeListener('data', onData);
|
|
84
|
+
process.stdin.removeListener('end', onEnd);
|
|
85
|
+
};
|
|
86
|
+
process.stdin.setEncoding('utf-8');
|
|
87
|
+
if (typeof process.stdin.isPaused === 'function' && process.stdin.isPaused())
|
|
88
|
+
process.stdin.resume();
|
|
89
|
+
process.stdin.on('data', onData);
|
|
90
|
+
process.stdin.once('end', onEnd);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type NpmrcConfig } from '@gjsify/npm-registry';
|
|
2
|
+
export type Diagnose404Reason = 'dead-token' | 'live-token-404' | 'unknown';
|
|
3
|
+
export interface Diagnose404Result {
|
|
4
|
+
/** Discriminant — drives the JSON shape + exit-code path in the caller. */
|
|
5
|
+
reason: Diagnose404Reason;
|
|
6
|
+
/** Username from `/-/whoami` when reason === 'live-token-404'. */
|
|
7
|
+
username?: string;
|
|
8
|
+
/** Multi-line, human-friendly hint ready for stderr emission. */
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
interface Diagnose404Input {
|
|
12
|
+
/** Full package name including scope, e.g. `@gjsify/abort-controller`. */
|
|
13
|
+
packageName: string;
|
|
14
|
+
/** Pinned version we tried to publish. */
|
|
15
|
+
version: string;
|
|
16
|
+
/** Registry URL (with or without trailing slash). */
|
|
17
|
+
registry: string;
|
|
18
|
+
/** Parsed .npmrc — used to derive Authorization on the whoami probe. */
|
|
19
|
+
npmrc: NpmrcConfig | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Probe `/-/whoami` to disambiguate the 404 cause. Best-effort: any thrown
|
|
23
|
+
* error / non-2xx falls through to `reason: 'unknown'` so the caller's
|
|
24
|
+
* generic error path runs untouched.
|
|
25
|
+
*
|
|
26
|
+
* Pure async I/O — no side effects, no process.exit, no console writes.
|
|
27
|
+
* The caller owns presentation (stderr vs stdout, plain vs JSON).
|
|
28
|
+
*/
|
|
29
|
+
export declare function diagnose404(input: Diagnose404Input): Promise<Diagnose404Result>;
|
|
30
|
+
/**
|
|
31
|
+
* Heuristic: is the 404 body the "dead-token-or-missing-package" shape?
|
|
32
|
+
* npm's PUT returns plain text `Not Found` (sometimes empty body). We trigger
|
|
33
|
+
* the diagnostic for both, plus for the JSON `{"error":"Not Found"}` shape
|
|
34
|
+
* just in case. Other 404 bodies (e.g. with a structured npm error code)
|
|
35
|
+
* keep the generic error path.
|
|
36
|
+
*/
|
|
37
|
+
export declare function is404DiagnosticCandidate(body: string): boolean;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Dead-token vs new-package diagnostic for `gjsify publish`.
|
|
2
|
+
//
|
|
3
|
+
// When the publish PUT returns `404 Not Found` (body `"Not Found"` or empty)
|
|
4
|
+
// it is ambiguous between two very different situations:
|
|
5
|
+
//
|
|
6
|
+
// 1. The `_authToken` in ~/.npmrc has been revoked / expired. The npm
|
|
7
|
+
// registry's 404 is its way of saying "we don't recognize this
|
|
8
|
+
// bearer". Easy to mistake for a missing-package error and send the
|
|
9
|
+
// user down the wrong path (Trusted-Publisher-bootstrap setup).
|
|
10
|
+
// 2. The scoped `@gjsify/<pkg>` genuinely doesn't exist on npm yet —
|
|
11
|
+
// the first-publish bootstrap step from AGENTS.md.
|
|
12
|
+
//
|
|
13
|
+
// `GET /-/whoami` with the SAME Authorization header disambiguates: a live
|
|
14
|
+
// token returns `{"username": "..."}`, a dead token returns `{}` (status 200
|
|
15
|
+
// in both cases — the empty body is npm's signal).
|
|
16
|
+
//
|
|
17
|
+
// `npm publish` from npm-cli handles dead tokens with `401 EOTP` + a clear
|
|
18
|
+
// "one-time-password or refresh the token" hint. The 404 path is npm's
|
|
19
|
+
// PUT-specific shape and `gjsify publish` previously just printed the
|
|
20
|
+
// opaque body. This helper closes the diagnostic gap.
|
|
21
|
+
import { whoami } from '@gjsify/npm-registry';
|
|
22
|
+
/**
|
|
23
|
+
* Probe `/-/whoami` to disambiguate the 404 cause. Best-effort: any thrown
|
|
24
|
+
* error / non-2xx falls through to `reason: 'unknown'` so the caller's
|
|
25
|
+
* generic error path runs untouched.
|
|
26
|
+
*
|
|
27
|
+
* Pure async I/O — no side effects, no process.exit, no console writes.
|
|
28
|
+
* The caller owns presentation (stderr vs stdout, plain vs JSON).
|
|
29
|
+
*/
|
|
30
|
+
export async function diagnose404(input) {
|
|
31
|
+
const { packageName, version, registry, npmrc } = input;
|
|
32
|
+
let probe = {};
|
|
33
|
+
try {
|
|
34
|
+
probe = await whoami(registry, npmrc);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { reason: 'unknown', message: formatUnknown(packageName, version) };
|
|
38
|
+
}
|
|
39
|
+
if (probe.username && probe.username.length > 0) {
|
|
40
|
+
return {
|
|
41
|
+
reason: 'live-token-404',
|
|
42
|
+
username: probe.username,
|
|
43
|
+
message: formatLiveToken404(packageName, version, probe.username),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { reason: 'dead-token', message: formatDeadToken(packageName, version) };
|
|
47
|
+
}
|
|
48
|
+
function formatDeadToken(name, version) {
|
|
49
|
+
return [
|
|
50
|
+
`gjsify publish: ${name}@${version} — 404 Not Found`,
|
|
51
|
+
'',
|
|
52
|
+
'The npm token in ~/.npmrc appears to be revoked or expired (the /-/whoami probe',
|
|
53
|
+
'returned {} instead of {"username": "..."}). The 404 is npm\'s response to a PUT',
|
|
54
|
+
'authenticated with an invalid bearer token.',
|
|
55
|
+
'',
|
|
56
|
+
'To refresh:',
|
|
57
|
+
' npm login',
|
|
58
|
+
' # or, future: gjsify login (tracked as project_gjsify_login_goal)',
|
|
59
|
+
'',
|
|
60
|
+
'Then verify before publishing:',
|
|
61
|
+
' curl -s -H "Authorization: Bearer $(grep registry.npmjs.org ~/.npmrc | sed \'s|.*=||\')" \\',
|
|
62
|
+
' https://registry.npmjs.org/-/whoami',
|
|
63
|
+
' # Healthy: {"username":"<you>"}',
|
|
64
|
+
' # Dead: {}',
|
|
65
|
+
].join('\n');
|
|
66
|
+
}
|
|
67
|
+
function formatLiveToken404(name, version, username) {
|
|
68
|
+
return [
|
|
69
|
+
`gjsify publish: ${name}@${version} — 404 Not Found`,
|
|
70
|
+
'',
|
|
71
|
+
`Authenticated as: ${username}`,
|
|
72
|
+
'',
|
|
73
|
+
`Your token authenticates, so this is NOT a dead-token problem. The package`,
|
|
74
|
+
`${name} is not (yet) on npmjs.com. Two cases:`,
|
|
75
|
+
'',
|
|
76
|
+
' 1. First publish of a brand-new scoped package — do the one-time bootstrap',
|
|
77
|
+
' (see AGENTS.md > "New @gjsify/* package: first-publish + Trusted',
|
|
78
|
+
' Publisher bootstrap"). The npm registry can also 404 *transiently*',
|
|
79
|
+
' while provisioning a brand-new package: simply re-run, or do the very',
|
|
80
|
+
' first publish with `npm publish` (then configure the Trusted Publisher).',
|
|
81
|
+
' 2. You lack publish access to the scope — verify with `npm access ls-packages`.',
|
|
82
|
+
].join('\n');
|
|
83
|
+
}
|
|
84
|
+
function formatUnknown(name, version) {
|
|
85
|
+
return `gjsify publish: ${name}@${version} — 404 Not Found`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Heuristic: is the 404 body the "dead-token-or-missing-package" shape?
|
|
89
|
+
* npm's PUT returns plain text `Not Found` (sometimes empty body). We trigger
|
|
90
|
+
* the diagnostic for both, plus for the JSON `{"error":"Not Found"}` shape
|
|
91
|
+
* just in case. Other 404 bodies (e.g. with a structured npm error code)
|
|
92
|
+
* keep the generic error path.
|
|
93
|
+
*/
|
|
94
|
+
export function is404DiagnosticCandidate(body) {
|
|
95
|
+
const trimmed = body.trim();
|
|
96
|
+
if (trimmed.length === 0)
|
|
97
|
+
return true;
|
|
98
|
+
if (/^not found$/i.test(trimmed))
|
|
99
|
+
return true;
|
|
100
|
+
if (/"error"\s*:\s*"Not Found"/i.test(trimmed))
|
|
101
|
+
return true;
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ResolveNpmPackageOptions {
|
|
2
|
+
/** Anchor directory to search from (typically the caller's cwd). */
|
|
3
|
+
cwd?: string;
|
|
4
|
+
/**
|
|
5
|
+
* Bundle path or module URL to anchor the bundle-side createRequire
|
|
6
|
+
* at. Pass `import.meta.url` from the call site so the bundle's
|
|
7
|
+
* own node_modules chain stays reachable even when the CLI is
|
|
8
|
+
* invoked from an unrelated cwd.
|
|
9
|
+
*/
|
|
10
|
+
bundleUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Resolve a bare npm specifier through multiple createRequire anchors.
|
|
14
|
+
* Returns the absolute filesystem path of the resolved module, or null
|
|
15
|
+
* if no anchor succeeded.
|
|
16
|
+
*
|
|
17
|
+
* Each anchor is tried in priority order — `GJSIFY_NODE_PATH` (highest)
|
|
18
|
+
* → caller cwd → workspace root → bundle URL → parent-dir walk from
|
|
19
|
+
* cwd. The first anchor whose `require.resolve()` succeeds wins.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveNpmPackage(specifier: string, opts?: ResolveNpmPackageOptions): string | null;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Multi-anchor npm-package resolver for the GJS-bundled CLI.
|
|
2
|
+
//
|
|
3
|
+
// GJS's native ESM loader has no node_modules walker — a bare
|
|
4
|
+
// `await import('rolldown')` from inside the bundle throws
|
|
5
|
+
// `ImportError: Module not found: rolldown` even when the package is
|
|
6
|
+
// physically present in a node_modules above the caller's cwd.
|
|
7
|
+
//
|
|
8
|
+
// `createRequire(import.meta.url)` works when invoked under Node, and
|
|
9
|
+
// when invoked under GJS *with* `@gjsify/module`'s polyfill it walks the
|
|
10
|
+
// node_modules chain from the URL it was anchored at. But it walks
|
|
11
|
+
// only ONE chain — the one rooted at the anchor's parent. When the
|
|
12
|
+
// bundle lives at `<install>/dist/cli.gjs.mjs` and the user runs
|
|
13
|
+
// `gjs -m <install>/dist/cli.gjs.mjs build …` from a completely
|
|
14
|
+
// unrelated cwd (`/tmp/sandbox/`) whose `node_modules` is the only
|
|
15
|
+
// place rolldown is present, anchoring on the bundle URL misses it.
|
|
16
|
+
//
|
|
17
|
+
// This helper resolves a bare specifier against multiple anchors in
|
|
18
|
+
// order — the first one that resolves wins:
|
|
19
|
+
//
|
|
20
|
+
// 1. `GJSIFY_NODE_PATH` env override (colon-separated dir list,
|
|
21
|
+
// matches Node's NODE_PATH semantics — each entry is treated as a
|
|
22
|
+
// synthetic `node_modules` parent).
|
|
23
|
+
// 2. Caller-supplied anchor dir (typically process.cwd()).
|
|
24
|
+
// 3. Workspace root from `findWorkspaceRoot(anchorDir)` — finds the
|
|
25
|
+
// monorepo top when invoked from a sub-package directory.
|
|
26
|
+
// 4. Bundle path's parent chain (`import.meta.url` of THIS module).
|
|
27
|
+
// 5. Parent dirs of the anchor (fallback for nested-without-workspace
|
|
28
|
+
// setups — matches `oxc-resolve.ts`'s walker).
|
|
29
|
+
//
|
|
30
|
+
// Returns the absolute path on success (the caller usually wraps it in
|
|
31
|
+
// `pathToFileURL().href` before passing to dynamic `import(...)`).
|
|
32
|
+
// Returns null when every anchor failed.
|
|
33
|
+
//
|
|
34
|
+
// Reference: `packages/infra/cli/src/commands/tsc.ts` (workspace-root +
|
|
35
|
+
// cwd anchoring precedent) and `packages/infra/cli/src/utils/oxc-resolve.ts`
|
|
36
|
+
// (parent-dir walker precedent).
|
|
37
|
+
import { createRequire } from 'node:module';
|
|
38
|
+
import { pathToFileURL } from 'node:url';
|
|
39
|
+
import { join, resolve } from 'node:path';
|
|
40
|
+
import { findWorkspaceRoot } from './workspace-root.js';
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a bare npm specifier through multiple createRequire anchors.
|
|
43
|
+
* Returns the absolute filesystem path of the resolved module, or null
|
|
44
|
+
* if no anchor succeeded.
|
|
45
|
+
*
|
|
46
|
+
* Each anchor is tried in priority order — `GJSIFY_NODE_PATH` (highest)
|
|
47
|
+
* → caller cwd → workspace root → bundle URL → parent-dir walk from
|
|
48
|
+
* cwd. The first anchor whose `require.resolve()` succeeds wins.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveNpmPackage(specifier, opts = {}) {
|
|
51
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
52
|
+
// 1. GJSIFY_NODE_PATH env override (NODE_PATH-like) — each entry is
|
|
53
|
+
// treated as a directory whose own `node_modules` participates
|
|
54
|
+
// in the lookup. Mirrors Node's NODE_PATH semantics.
|
|
55
|
+
const envPath = process.env['GJSIFY_NODE_PATH'];
|
|
56
|
+
if (envPath) {
|
|
57
|
+
for (const dir of envPath.split(':').filter(Boolean)) {
|
|
58
|
+
const hit = tryResolveFromDir(specifier, resolve(dir));
|
|
59
|
+
if (hit)
|
|
60
|
+
return hit;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// 2. Caller cwd → walk up for nearest node_modules/<pkg>.
|
|
64
|
+
const fromCwd = tryResolveFromDir(specifier, cwd);
|
|
65
|
+
if (fromCwd)
|
|
66
|
+
return fromCwd;
|
|
67
|
+
// 3. Workspace root (monorepo top, if any).
|
|
68
|
+
const wsRoot = findWorkspaceRoot(cwd);
|
|
69
|
+
if (wsRoot && wsRoot !== cwd) {
|
|
70
|
+
const fromWsRoot = tryResolveFromDir(specifier, wsRoot);
|
|
71
|
+
if (fromWsRoot)
|
|
72
|
+
return fromWsRoot;
|
|
73
|
+
}
|
|
74
|
+
// 4. Bundle path's own parent chain — anchored at the bundle URL
|
|
75
|
+
// so the install-time node_modules layout (e.g.
|
|
76
|
+
// `<install>/node_modules/rolldown` next to the CLI bundle)
|
|
77
|
+
// is reachable even when the user runs the bundle directly from
|
|
78
|
+
// an unrelated cwd.
|
|
79
|
+
if (opts.bundleUrl) {
|
|
80
|
+
try {
|
|
81
|
+
const req = createRequire(opts.bundleUrl);
|
|
82
|
+
return req.resolve(specifier);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Fall through.
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 5. Parent-dir walk from cwd as a last resort (nested
|
|
89
|
+
// package layouts without a workspace marker). Capped at 8
|
|
90
|
+
// levels to avoid runaway filesystem walks on pathological
|
|
91
|
+
// layouts. Matches the depth `oxc-resolve.ts` uses for its
|
|
92
|
+
// equivalent walker.
|
|
93
|
+
let dir = resolve(cwd, '..');
|
|
94
|
+
for (let i = 0; i < 8; i++) {
|
|
95
|
+
const hit = tryResolveFromDir(specifier, dir);
|
|
96
|
+
if (hit)
|
|
97
|
+
return hit;
|
|
98
|
+
const parent = resolve(dir, '..');
|
|
99
|
+
if (parent === dir)
|
|
100
|
+
break;
|
|
101
|
+
dir = parent;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Attempt to resolve `specifier` as if a fictional source file at
|
|
107
|
+
* `<dir>/__gjsify_resolve__.js` were doing the lookup. createRequire's
|
|
108
|
+
* algorithm walks up from the anchor's parent for `node_modules/<pkg>`
|
|
109
|
+
* so seeding it inside `<dir>` makes `<dir>/node_modules/<pkg>` the
|
|
110
|
+
* first hit.
|
|
111
|
+
*/
|
|
112
|
+
function tryResolveFromDir(specifier, dir) {
|
|
113
|
+
try {
|
|
114
|
+
const sentinel = pathToFileURL(join(dir, '__gjsify_resolve__.js')).href;
|
|
115
|
+
const req = createRequire(sentinel);
|
|
116
|
+
return req.resolve(specifier);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.37",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -120,35 +120,46 @@
|
|
|
120
120
|
"cli"
|
|
121
121
|
],
|
|
122
122
|
"dependencies": {
|
|
123
|
-
"@gjsify/buffer": "^0.4.
|
|
124
|
-
"@gjsify/create-app": "^0.4.
|
|
125
|
-
"@gjsify/node-globals": "^0.4.
|
|
126
|
-
"@gjsify/node-polyfills": "^0.4.
|
|
127
|
-
"@gjsify/npm-registry": "^0.4.
|
|
128
|
-
"@gjsify/resolve-npm": "^0.4.
|
|
129
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.4.
|
|
130
|
-
"@gjsify/rolldown-plugin-pnp": "^0.4.
|
|
131
|
-
"@gjsify/semver": "^0.4.
|
|
132
|
-
"@gjsify/tar": "^0.4.
|
|
133
|
-
"@gjsify/
|
|
134
|
-
"@gjsify/
|
|
123
|
+
"@gjsify/buffer": "^0.4.37",
|
|
124
|
+
"@gjsify/create-app": "^0.4.37",
|
|
125
|
+
"@gjsify/node-globals": "^0.4.37",
|
|
126
|
+
"@gjsify/node-polyfills": "^0.4.37",
|
|
127
|
+
"@gjsify/npm-registry": "^0.4.37",
|
|
128
|
+
"@gjsify/resolve-npm": "^0.4.37",
|
|
129
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.4.37",
|
|
130
|
+
"@gjsify/rolldown-plugin-pnp": "^0.4.37",
|
|
131
|
+
"@gjsify/semver": "^0.4.37",
|
|
132
|
+
"@gjsify/tar": "^0.4.37",
|
|
133
|
+
"@gjsify/tsc": "^0.4.37",
|
|
134
|
+
"@gjsify/web-polyfills": "^0.4.37",
|
|
135
|
+
"@gjsify/workspace": "^0.4.37",
|
|
135
136
|
"cosmiconfig": "^9.0.1",
|
|
136
137
|
"get-tsconfig": "^4.14.0",
|
|
137
138
|
"pkg-types": "^2.3.1",
|
|
138
|
-
"rolldown": "^1.0.
|
|
139
|
+
"rolldown": "^1.0.3",
|
|
139
140
|
"yargs": "^18.0.0"
|
|
140
141
|
},
|
|
141
142
|
"devDependencies": {
|
|
142
|
-
"@gjsify/unit": "^0.4.
|
|
143
|
+
"@gjsify/unit": "^0.4.37",
|
|
143
144
|
"@types/yargs": "^17.0.35",
|
|
144
|
-
"typescript": "^
|
|
145
|
+
"typescript": "^5.9.3"
|
|
145
146
|
},
|
|
146
147
|
"peerDependencies": {
|
|
147
|
-
"@gjsify/rolldown-native": "^0.4.
|
|
148
|
+
"@gjsify/rolldown-native": "^0.4.37"
|
|
148
149
|
},
|
|
149
150
|
"peerDependenciesMeta": {
|
|
150
151
|
"@gjsify/rolldown-native": {
|
|
151
152
|
"optional": true
|
|
152
153
|
}
|
|
153
|
-
}
|
|
154
|
+
},
|
|
155
|
+
"license": "MIT",
|
|
156
|
+
"repository": {
|
|
157
|
+
"type": "git",
|
|
158
|
+
"url": "git+https://github.com/gjsify/gjsify.git",
|
|
159
|
+
"directory": "packages/infra/cli"
|
|
160
|
+
},
|
|
161
|
+
"bugs": {
|
|
162
|
+
"url": "https://github.com/gjsify/gjsify/issues"
|
|
163
|
+
},
|
|
164
|
+
"homepage": "https://github.com/gjsify/gjsify/tree/main/packages/infra/cli#readme"
|
|
154
165
|
}
|