@gjsify/cli 0.4.29 → 0.4.30
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 +131 -131
- package/lib/commands/build.d.ts +1 -1
- package/lib/commands/create.d.ts +1 -1
- package/lib/commands/dlx.d.ts +1 -1
- package/lib/commands/flatpak/sync-flathub.js +1 -1
- package/lib/commands/foreach.d.ts +1 -1
- package/lib/commands/generate-installer.d.ts +1 -1
- package/lib/commands/gettext.d.ts +1 -1
- package/lib/commands/gettext.js +6 -5
- package/lib/commands/gresource.d.ts +1 -1
- package/lib/commands/gresource.js +6 -5
- package/lib/commands/gsettings.d.ts +1 -1
- package/lib/commands/gsettings.js +6 -5
- package/lib/commands/info.d.ts +1 -1
- package/lib/commands/install.d.ts +1 -1
- package/lib/commands/install.js +32 -7
- package/lib/commands/pack.d.ts +1 -1
- package/lib/commands/publish.d.ts +1 -1
- package/lib/commands/run.d.ts +1 -1
- package/lib/commands/self-update.d.ts +1 -1
- package/lib/commands/showcase.d.ts +1 -1
- package/lib/commands/system-check.d.ts +1 -1
- package/lib/commands/uninstall.d.ts +1 -1
- package/lib/commands/workspace.d.ts +1 -1
- package/lib/types/command.d.ts +1 -1
- package/lib/types/cosmiconfig-result.d.ts +1 -1
- package/lib/utils/install-backend-native.js +47 -0
- package/package.json +15 -15
package/lib/commands/build.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Command, CliBuildOptions } from '../types/index.js';
|
|
2
|
-
export declare const buildCommand: Command<
|
|
2
|
+
export declare const buildCommand: Command<unknown, CliBuildOptions>;
|
package/lib/commands/create.d.ts
CHANGED
package/lib/commands/dlx.d.ts
CHANGED
|
@@ -152,7 +152,7 @@ async function resolveCommitForTag(cwd, tag, verbose) {
|
|
|
152
152
|
}
|
|
153
153
|
catch (err) {
|
|
154
154
|
throw new Error(`[gjsify flatpak sync-flathub] tag ${tag} not found locally. Run \`git fetch --tags\` or pass --commit <sha>.\n` +
|
|
155
|
-
` underlying error: ${err
|
|
155
|
+
` underlying error: ${err instanceof Error ? err.message : String(err)}`);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
function normaliseBranchSegment(version) {
|
|
@@ -6,5 +6,5 @@ interface GenerateInstallerOptions {
|
|
|
6
6
|
output: string;
|
|
7
7
|
force: boolean;
|
|
8
8
|
}
|
|
9
|
-
export declare const generateInstallerCommand: Command<
|
|
9
|
+
export declare const generateInstallerCommand: Command<unknown, GenerateInstallerOptions>;
|
|
10
10
|
export {};
|
package/lib/commands/gettext.js
CHANGED
|
@@ -179,15 +179,16 @@ export const gettextCommand = {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
catch (err) {
|
|
182
|
-
|
|
182
|
+
const e = err;
|
|
183
|
+
if (e?.code === 'ENOENT') {
|
|
183
184
|
console.error('[gjsify gettext] msgfmt not found. Install it via your distro (package: gettext).');
|
|
184
185
|
}
|
|
185
186
|
else {
|
|
186
|
-
if (
|
|
187
|
-
process.stderr.write(
|
|
188
|
-
console.error(`[gjsify gettext] msgfmt failed${
|
|
187
|
+
if (e?.stderr)
|
|
188
|
+
process.stderr.write(e.stderr);
|
|
189
|
+
console.error(`[gjsify gettext] msgfmt failed${e?.code !== undefined ? ` (exit ${e.code})` : ''}`);
|
|
189
190
|
}
|
|
190
|
-
process.exitCode = typeof
|
|
191
|
+
process.exitCode = typeof e?.code === 'number' ? e.code : 1;
|
|
191
192
|
}
|
|
192
193
|
},
|
|
193
194
|
};
|
|
@@ -62,15 +62,16 @@ export const gresourceCommand = {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
catch (err) {
|
|
65
|
-
|
|
65
|
+
const e = err;
|
|
66
|
+
if (e?.code === 'ENOENT') {
|
|
66
67
|
console.error('[gjsify gresource] glib-compile-resources not found. Install it via your distro (package: glib2-devel / libglib2.0-dev).');
|
|
67
68
|
}
|
|
68
69
|
else {
|
|
69
|
-
if (
|
|
70
|
-
process.stderr.write(
|
|
71
|
-
console.error(`[gjsify gresource] glib-compile-resources failed${
|
|
70
|
+
if (e?.stderr)
|
|
71
|
+
process.stderr.write(e.stderr);
|
|
72
|
+
console.error(`[gjsify gresource] glib-compile-resources failed${e?.code !== undefined ? ` (exit ${e.code})` : ''}`);
|
|
72
73
|
}
|
|
73
|
-
process.exitCode = typeof
|
|
74
|
+
process.exitCode = typeof e?.code === 'number' ? e.code : 1;
|
|
74
75
|
}
|
|
75
76
|
},
|
|
76
77
|
};
|
|
@@ -56,15 +56,16 @@ export const gsettingsCommand = {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
catch (err) {
|
|
59
|
-
|
|
59
|
+
const e = err;
|
|
60
|
+
if (e?.code === 'ENOENT') {
|
|
60
61
|
console.error('[gjsify gsettings] glib-compile-schemas not found. Install it via your distro (package: glib2-devel / libglib2.0-dev).');
|
|
61
62
|
}
|
|
62
63
|
else {
|
|
63
|
-
if (
|
|
64
|
-
process.stderr.write(
|
|
65
|
-
console.error(`[gjsify gsettings] glib-compile-schemas failed${
|
|
64
|
+
if (e?.stderr)
|
|
65
|
+
process.stderr.write(e.stderr);
|
|
66
|
+
console.error(`[gjsify gsettings] glib-compile-schemas failed${e?.code !== undefined ? ` (exit ${e.code})` : ''}`);
|
|
66
67
|
}
|
|
67
|
-
process.exitCode = typeof
|
|
68
|
+
process.exitCode = typeof e?.code === 'number' ? e.code : 1;
|
|
68
69
|
}
|
|
69
70
|
},
|
|
70
71
|
};
|
package/lib/commands/info.d.ts
CHANGED
package/lib/commands/install.js
CHANGED
|
@@ -265,14 +265,39 @@ async function workspaceInstall(cwd, args) {
|
|
|
265
265
|
for (const [depName, spec] of Object.entries(block)) {
|
|
266
266
|
if (typeof spec !== 'string')
|
|
267
267
|
continue;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
268
|
+
// A dependency whose NAME matches a local workspace is always
|
|
269
|
+
// satisfied by that workspace — never by a same-named package on
|
|
270
|
+
// npm. This holds regardless of the spec form: an explicit
|
|
271
|
+
// `workspace:` protocol, a plain semver range (`^1.2.3`), or even
|
|
272
|
+
// a dist-tag. Yarn/npm resolve a workspace-named dep to the local
|
|
273
|
+
// package first; we MUST do the same. Routing such a dep into the
|
|
274
|
+
// native fetch/extract queue is the data-loss bug this guards
|
|
275
|
+
// against — `extractOne` would `rmSync` + drop the published
|
|
276
|
+
// tarball over the workspace's OWN source tree (the published
|
|
277
|
+
// tarball ships only `files`, so `src/**` gets wiped). Symlink
|
|
278
|
+
// it instead, exactly like a `workspace:` ref.
|
|
279
|
+
const localWorkspace = byName.get(depName);
|
|
280
|
+
if (localWorkspace) {
|
|
281
|
+
// Only an EXPLICIT out-of-workspace protocol (link:/file:/
|
|
282
|
+
// portal:/git+/http(s):) opts out of the local workspace. Any
|
|
283
|
+
// other shape — `workspace:` or a plain semver range/dist-tag
|
|
284
|
+
// (`^1.2.3`, `*`, `latest`) — resolves to the local package.
|
|
285
|
+
const explicitOverride = /^(link|file|portal|git\+|https?):/.test(spec);
|
|
286
|
+
if (!explicitOverride) {
|
|
287
|
+
symlinks.push({
|
|
288
|
+
fromWorkspaceName: ws.name,
|
|
289
|
+
depName,
|
|
290
|
+
targetLocation: localWorkspace.location,
|
|
291
|
+
});
|
|
292
|
+
continue;
|
|
273
293
|
}
|
|
274
|
-
|
|
275
|
-
|
|
294
|
+
// explicit override → fall through to the existing handling.
|
|
295
|
+
}
|
|
296
|
+
if (spec.startsWith('workspace:')) {
|
|
297
|
+
// `workspace:` against a name that is NOT a discovered
|
|
298
|
+
// workspace is a hard error (typo / missing package).
|
|
299
|
+
throw new Error(`gjsify install: ${ws.name} declares "${depName}: ${spec}" but ` +
|
|
300
|
+
`no workspace with that name exists`);
|
|
276
301
|
}
|
|
277
302
|
if (/^(link|file|portal|git\+|https?):/.test(spec))
|
|
278
303
|
continue;
|
package/lib/commands/pack.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ interface PackResult {
|
|
|
23
23
|
/** Absolute path of the written .tgz, or null on --dry-run. */
|
|
24
24
|
absolutePath: string | null;
|
|
25
25
|
}
|
|
26
|
-
export declare const packCommand: Command<
|
|
26
|
+
export declare const packCommand: Command<unknown, PackOptions>;
|
|
27
27
|
export interface PackWorkspaceOptions {
|
|
28
28
|
/** Directory to write the .tgz into. Defaults to the workspace itself. */
|
|
29
29
|
destination?: string;
|
package/lib/commands/run.d.ts
CHANGED
package/lib/types/command.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ArgumentsCamelCase, MiddlewareFunction, BuilderCallback } from 'yargs';
|
|
2
|
-
export interface Command<T =
|
|
2
|
+
export interface Command<T = unknown, U = T> {
|
|
3
3
|
command: string | ReadonlyArray<string>;
|
|
4
4
|
description: string;
|
|
5
5
|
builder?: BuilderCallback<T, U>;
|
|
@@ -486,6 +486,15 @@ async function downloadAndExtractAll(nodes, prefix, npmrc, log) {
|
|
|
486
486
|
}
|
|
487
487
|
async function extractOne(node, prefix, npmrc, log) {
|
|
488
488
|
const dest = path.join(prefix, node.installPath);
|
|
489
|
+
// Defense-in-depth against the workspace-source-wipe data-loss bug:
|
|
490
|
+
// every extractable node MUST land inside a `node_modules/` directory.
|
|
491
|
+
// The resolver only ever produces `installPath`s of that shape, so this
|
|
492
|
+
// can only fail if a workspace package leaked into the fetch/extract
|
|
493
|
+
// queue (the root cause fixed in `workspaceInstall`). Refusing here means
|
|
494
|
+
// a regression in the resolver can never again `rmSync` a working-tree
|
|
495
|
+
// source dir — the realpath check additionally rejects a `dest` that
|
|
496
|
+
// resolves THROUGH a symlink into a directory outside node_modules.
|
|
497
|
+
assertNodeModulesDest(dest, node);
|
|
489
498
|
log('fetch: %s@%s ← %s (→ %s)', node.name, node.version, node.tarballUrl, node.installPath);
|
|
490
499
|
const bytes = await fetchTarball(node.tarballUrl, {
|
|
491
500
|
npmrc,
|
|
@@ -498,6 +507,44 @@ async function extractOne(node, prefix, npmrc, log) {
|
|
|
498
507
|
fs.mkdirSync(dest, { recursive: true });
|
|
499
508
|
await extractTarball(bytes, dest);
|
|
500
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Guard: a tarball may only be extracted into a `node_modules/` directory.
|
|
512
|
+
*
|
|
513
|
+
* Two checks, both belt-and-suspenders against ever wiping a working-tree
|
|
514
|
+
* source dir (the install-deletes-workspace-sources data-loss bug):
|
|
515
|
+
*
|
|
516
|
+
* 1. The logical `installPath` must contain a `node_modules` path segment.
|
|
517
|
+
* The resolver always produces such paths; a workspace package that
|
|
518
|
+
* slipped into the queue would not.
|
|
519
|
+
* 2. If `dest` already exists and resolves (via symlink) to a directory
|
|
520
|
+
* whose REAL path is not under a `node_modules/` segment, refuse. This
|
|
521
|
+
* catches the case where `node_modules/<name>` is a symlink to a
|
|
522
|
+
* workspace's source tree — `rmSync(dest, { recursive: true })` would
|
|
523
|
+
* then delete the link's target contents.
|
|
524
|
+
*/
|
|
525
|
+
function assertNodeModulesDest(dest, node) {
|
|
526
|
+
const segments = dest.split(path.sep);
|
|
527
|
+
if (!segments.includes('node_modules')) {
|
|
528
|
+
throw new Error(`gjsify install: refusing to extract ${node.name}@${node.version} into ${dest} — ` +
|
|
529
|
+
`target is not inside a node_modules/ directory. This would overwrite working-tree files. ` +
|
|
530
|
+
`A workspace package likely leaked into the fetch queue (it must be symlinked, not fetched).`);
|
|
531
|
+
}
|
|
532
|
+
let real;
|
|
533
|
+
try {
|
|
534
|
+
real = fs.realpathSync(dest);
|
|
535
|
+
}
|
|
536
|
+
catch {
|
|
537
|
+
// `dest` doesn't exist yet (fresh install) — nothing to resolve, the
|
|
538
|
+
// logical-path check above is sufficient.
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
const realSegments = real.split(path.sep);
|
|
542
|
+
if (!realSegments.includes('node_modules')) {
|
|
543
|
+
throw new Error(`gjsify install: refusing to extract ${node.name}@${node.version} — ${dest} resolves to ${real}, ` +
|
|
544
|
+
`which is outside any node_modules/ directory (likely a symlink to a workspace source tree). ` +
|
|
545
|
+
`Extracting here would delete working-tree source files.`);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
501
548
|
function depth(installPath) {
|
|
502
549
|
// Count `node_modules/` segments to know nesting depth.
|
|
503
550
|
// `node_modules/foo` = 1, `node_modules/foo/node_modules/bar` = 2, etc.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.30",
|
|
4
4
|
"description": "CLI for Gjsify",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -120,18 +120,18 @@
|
|
|
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/web-polyfills": "^0.4.
|
|
134
|
-
"@gjsify/workspace": "^0.4.
|
|
123
|
+
"@gjsify/buffer": "^0.4.30",
|
|
124
|
+
"@gjsify/create-app": "^0.4.30",
|
|
125
|
+
"@gjsify/node-globals": "^0.4.30",
|
|
126
|
+
"@gjsify/node-polyfills": "^0.4.30",
|
|
127
|
+
"@gjsify/npm-registry": "^0.4.30",
|
|
128
|
+
"@gjsify/resolve-npm": "^0.4.30",
|
|
129
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.4.30",
|
|
130
|
+
"@gjsify/rolldown-plugin-pnp": "^0.4.30",
|
|
131
|
+
"@gjsify/semver": "^0.4.30",
|
|
132
|
+
"@gjsify/tar": "^0.4.30",
|
|
133
|
+
"@gjsify/web-polyfills": "^0.4.30",
|
|
134
|
+
"@gjsify/workspace": "^0.4.30",
|
|
135
135
|
"cosmiconfig": "^9.0.1",
|
|
136
136
|
"get-tsconfig": "^4.14.0",
|
|
137
137
|
"pkg-types": "^2.3.1",
|
|
@@ -139,12 +139,12 @@
|
|
|
139
139
|
"yargs": "^18.0.0"
|
|
140
140
|
},
|
|
141
141
|
"devDependencies": {
|
|
142
|
-
"@gjsify/unit": "^0.4.
|
|
142
|
+
"@gjsify/unit": "^0.4.30",
|
|
143
143
|
"@types/yargs": "^17.0.35",
|
|
144
144
|
"typescript": "^6.0.3"
|
|
145
145
|
},
|
|
146
146
|
"peerDependencies": {
|
|
147
|
-
"@gjsify/rolldown-native": "^0.4.
|
|
147
|
+
"@gjsify/rolldown-native": "^0.4.30"
|
|
148
148
|
},
|
|
149
149
|
"peerDependenciesMeta": {
|
|
150
150
|
"@gjsify/rolldown-native": {
|