@gjsify/cli 0.44.0 → 0.45.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/dist/cli.gjs.mjs +192 -165
- package/lib/commands/gettext.d.ts +2 -1
- package/lib/commands/gettext.js +105 -47
- package/lib/commands/onboard.d.ts +7 -0
- package/lib/commands/onboard.js +349 -96
- package/lib/commands/ship.d.ts +3 -0
- package/lib/commands/ship.js +833 -54
- package/lib/commands/trust.d.ts +6 -0
- package/lib/commands/trust.js +1 -1
- package/lib/types/config-data.d.ts +63 -1
- package/lib/utils/msgfmt-merge.d.ts +35 -0
- package/lib/utils/msgfmt-merge.js +102 -0
- package/lib/utils/npm-otp.d.ts +27 -2
- package/lib/utils/npm-otp.js +82 -7
- package/lib/utils/onboard-discovery.d.ts +68 -0
- package/lib/utils/onboard-discovery.js +178 -0
- package/lib/utils/onboard-probe.d.ts +118 -1
- package/lib/utils/onboard-probe.js +153 -4
- package/lib/utils/prompt-output.d.ts +12 -0
- package/lib/utils/prompt-output.js +54 -0
- package/lib/utils/prompt.js +22 -2
- package/lib/utils/publishable-packages.d.ts +1 -1
- package/lib/utils/publishable-packages.js +1 -0
- package/lib/utils/resolve-npm-package.d.ts +56 -0
- package/lib/utils/resolve-npm-package.js +69 -0
- package/lib/utils/ship/app-runtime.d.ts +214 -0
- package/lib/utils/ship/app-runtime.js +429 -0
- package/lib/utils/ship/depends.d.ts +50 -0
- package/lib/utils/ship/depends.js +117 -3
- package/lib/utils/ship/discover.js +18 -1
- package/lib/utils/ship/dmg.d.ts +71 -0
- package/lib/utils/ship/dmg.js +181 -0
- package/lib/utils/ship/flatpak.js +1 -1
- package/lib/utils/ship/formats.d.ts +85 -7
- package/lib/utils/ship/formats.js +734 -15
- package/lib/utils/ship/launcher.d.ts +13 -3
- package/lib/utils/ship/launcher.js +362 -17
- package/lib/utils/ship/layout.d.ts +268 -0
- package/lib/utils/ship/layout.js +351 -0
- package/lib/utils/ship/localize-metadata.d.ts +22 -0
- package/lib/utils/ship/localize-metadata.js +126 -0
- package/lib/utils/ship/mime.js +1 -9
- package/lib/utils/ship/msi.d.ts +126 -0
- package/lib/utils/ship/msi.js +417 -0
- package/lib/utils/ship/node-runtime.d.ts +71 -0
- package/lib/utils/ship/node-runtime.js +122 -0
- package/lib/utils/ship/payload.d.ts +156 -5
- package/lib/utils/ship/payload.js +580 -14
- package/lib/utils/ship/plan.d.ts +21 -0
- package/lib/utils/ship/plan.js +20 -7
- package/lib/utils/ship/plist.d.ts +58 -0
- package/lib/utils/ship/plist.js +198 -0
- package/lib/utils/ship/rpm.js +9 -3
- package/lib/utils/ship/schemas.d.ts +61 -0
- package/lib/utils/ship/schemas.js +118 -0
- package/lib/utils/ship/scripts.js +7 -3
- package/lib/utils/ship/settings.d.ts +19 -1
- package/lib/utils/ship/settings.js +12 -1
- package/lib/utils/ship/share-dirs.d.ts +23 -0
- package/lib/utils/ship/share-dirs.js +46 -0
- package/lib/utils/ship/signing.d.ts +195 -0
- package/lib/utils/ship/signing.js +317 -0
- package/lib/utils/ship/stage-manifest.d.ts +40 -12
- package/lib/utils/ship/stage-manifest.js +99 -13
- package/lib/utils/ship/stage-writer.d.ts +48 -0
- package/lib/utils/ship/stage-writer.js +71 -1
- package/lib/utils/ship/types.d.ts +158 -13
- package/lib/utils/ship/xml.d.ts +7 -0
- package/lib/utils/ship/xml.js +25 -0
- package/lib/utils/ship/zip.d.ts +69 -0
- package/lib/utils/ship/zip.js +245 -0
- package/lib/utils/trust-registry.js +5 -0
- package/package.json +19 -19
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Layout, type LayoutIdentity } from './layout.js';
|
|
1
2
|
/** One file in the payload, with its bytes. */
|
|
2
3
|
export interface PayloadEntry {
|
|
3
4
|
/** Prefix-relative path, POSIX-separated, e.g. `bin/learn6502`. */
|
|
@@ -46,6 +47,14 @@ export declare function buildTimestamp(bundlePath: string, env?: Record<string,
|
|
|
46
47
|
* Path-only, on purpose — `isArchIndependent` is the sibling that reads BYTES, and the two answer
|
|
47
48
|
* different questions from the same payload. The same split as `plan.ts`'s `isExecutableAsset`
|
|
48
49
|
* (by name) versus this module's magic sniffing (by content).
|
|
50
|
+
*
|
|
51
|
+
* NOT EVERY QUESTION BELONGS HERE, and one that does not was briefly added: "does this package need
|
|
52
|
+
* a Node interpreter", derived from a `*.node.mjs` filename anywhere in the tree. Every fact above
|
|
53
|
+
* is about something the package INSTALLS at a well-known path, which is why a path answers it.
|
|
54
|
+
* That one was about what the launcher EXECS — and `discoverPayload` stages the whole directory
|
|
55
|
+
* beside the bundle, so a `--app gjs` project that also builds a Node bundle carried the file and
|
|
56
|
+
* ran neither. It lives on `settings.app` now, with `assertLauncherMatchesInterpreter` below as the
|
|
57
|
+
* check. Before adding a field here, ask whether a path can answer it or only correlate with it.
|
|
49
58
|
*/
|
|
50
59
|
export interface PayloadFacts {
|
|
51
60
|
/** The payload installs a `share/applications/*.desktop`. */
|
|
@@ -70,6 +79,123 @@ export interface PayloadFacts {
|
|
|
70
79
|
export declare function readPayloadFacts(entries: readonly {
|
|
71
80
|
path: string;
|
|
72
81
|
}[]): PayloadFacts;
|
|
82
|
+
/**
|
|
83
|
+
* Every interpreter the STAGED launcher could exec, resolved to a bare name.
|
|
84
|
+
*
|
|
85
|
+
* WHY THIS IS READ BACK AT ALL, when `settings.app` already says so. Because
|
|
86
|
+
* `settings.app` says what the launcher was RENDERED from, and the dependency is
|
|
87
|
+
* a claim about what the installed package will RUN. Those were once two
|
|
88
|
+
* different things: the Node dependency was derived from a filename glob over
|
|
89
|
+
* the staged tree while `renderLauncher` execed `gjs` unconditionally, and the
|
|
90
|
+
* packer emitted `Depends: gjs (>= 1.86), nodejs (>= 24)` for a package that
|
|
91
|
+
* runs neither combination. Nothing in the pipeline compared them, and no
|
|
92
|
+
* structural check could: both artifacts were individually well-formed.
|
|
93
|
+
*
|
|
94
|
+
* A LIST, and every `exec` rather than one of them. The first cut took the first
|
|
95
|
+
* match while its own comment claimed the last — `/\nexec\s+/` is not global, so
|
|
96
|
+
* the two disagreed and the comment was the wrong one. Neither is right for a
|
|
97
|
+
* script this tree did not write: a launcher may exec different interpreters on
|
|
98
|
+
* different branches, and picking one branch's answer is a guess. Collecting
|
|
99
|
+
* them lets {@link assertLauncherMatchesInterpreter} ask the only question that
|
|
100
|
+
* is safe on a foreign script — see there.
|
|
101
|
+
*
|
|
102
|
+
* NAMES, not the tokens as written. `exec /usr/bin/gjs -m …` execs gjs, and an
|
|
103
|
+
* `env` prefix (`exec env NODE_OPTIONS=… node …`) execs whatever follows its
|
|
104
|
+
* assignments. Both are things `gjsify.ship.extraFiles` legitimately writes, and
|
|
105
|
+
* the raw-token version REFUSED them: measured, an untouched `--app gjs` project
|
|
106
|
+
* whose `extraFiles` replaced the launcher with `exec /usr/bin/gjs -m …` failed
|
|
107
|
+
* the pack at exit 1 with "execs `/usr/bin/gjs`, but this package would declare
|
|
108
|
+
* a dependency on `gjs`" — a working artifact rejected over a parser, which is
|
|
109
|
+
* exactly what the `null` branch was written to prevent and did not.
|
|
110
|
+
*/
|
|
111
|
+
export declare function readLauncherInterpreters(payload: readonly PayloadEntry[], layout: Layout, identity: LayoutIdentity): string[];
|
|
112
|
+
/**
|
|
113
|
+
* Refuse a package whose launcher execs an interpreter the package does not
|
|
114
|
+
* depend on.
|
|
115
|
+
*
|
|
116
|
+
* THE RULE, and it is deliberately asymmetric: fail ONLY when the launcher
|
|
117
|
+
* positively names the OTHER known interpreter and never names the declared one.
|
|
118
|
+
* Everything else passes — no launcher, no `exec` this reader resolves, a program
|
|
119
|
+
* that is neither `gjs` nor `node`, or a script whose branches include the
|
|
120
|
+
* declared one.
|
|
121
|
+
*
|
|
122
|
+
* That asymmetry is the correction. The first cut failed whenever the resolved
|
|
123
|
+
* token was not equal to the declared interpreter, and its own doc comment
|
|
124
|
+
* claimed the opposite ("`null` is SILENT ... refusing a package because this
|
|
125
|
+
* function did not understand a launcher somebody else wrote would fail a
|
|
126
|
+
* working artifact over a parser"). The parser's failure mode is not `null` — it
|
|
127
|
+
* answers confidently wrong. Measured on an otherwise untouched `--app gjs`
|
|
128
|
+
* project whose `gjsify.ship.extraFiles` replaced `bin/<name>`:
|
|
129
|
+
*
|
|
130
|
+
* exec /usr/bin/gjs -m … → exit 1, "execs `/usr/bin/gjs`"
|
|
131
|
+
* exec env NODE_OPTIONS=… node… → exit 1, "execs `env`"
|
|
132
|
+
*
|
|
133
|
+
* Both worked before the check existed. A guard that turns working packages into
|
|
134
|
+
* failures buys nothing over the defect it prevents.
|
|
135
|
+
*
|
|
136
|
+
* The advice in the message is also fixed. It used to say "re-run the `--stage`
|
|
137
|
+
* phase", which is FALSE for the case that actually reaches a user: re-staging
|
|
138
|
+
* an `extraFiles` override reproduces it forever. The two real causes are named
|
|
139
|
+
* instead.
|
|
140
|
+
*/
|
|
141
|
+
export declare function assertLauncherMatchesInterpreter(payload: readonly PayloadEntry[], layout: Layout, identity: LayoutIdentity, interpreter: 'gjs' | 'node'): void;
|
|
142
|
+
/**
|
|
143
|
+
* How a `share/` entry behaves once it leaves the layout a Linux package installs.
|
|
144
|
+
*
|
|
145
|
+
* `aborts` and `inert` are not one severity, and printing them as one was a
|
|
146
|
+
* measured presentation defect: every launcher exports `XDG_DATA_DIRS` at the
|
|
147
|
+
* staged `share/`, so a `.app` built from a stage with an UNCOMPILED schema
|
|
148
|
+
* directory points GSettings at an `.xml` with no `gschemas.compiled` beside it —
|
|
149
|
+
* `g_settings_new()` ABORTS. The others merely do nothing. Ranking them
|
|
150
|
+
* identically in a list of five buried the one that stops the app.
|
|
151
|
+
*
|
|
152
|
+
* #1354 M2a compiles that cache into every non-Linux stage, so `aborts` is empty
|
|
153
|
+
* for a stage this gjsify wrote. The variant STAYS, and reachable — see
|
|
154
|
+
* {@link SHARE_VERDICTS}'s schema row.
|
|
155
|
+
*/
|
|
156
|
+
export type ShareVerdict = 'aborts' | 'inert' | 'unknown';
|
|
157
|
+
/** One `share/` entry a non-Linux layout carries, and what happens to it there. */
|
|
158
|
+
export interface CarriedShareEntry {
|
|
159
|
+
path: string;
|
|
160
|
+
verdict: ShareVerdict;
|
|
161
|
+
why: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Every `share/` entry a non-Linux layout carries, classified — including the
|
|
165
|
+
* ones nothing here has a rule for.
|
|
166
|
+
*
|
|
167
|
+
* WHY THIS EXISTS, and it is the hole the layout axis opened. `planStage` emits
|
|
168
|
+
* one prefix-relative plan and every layout carries it, so the darwin and windows
|
|
169
|
+
* trees hold the same `share/…` files the `.deb` does — and on Linux most of those
|
|
170
|
+
* are only correct because `cacheRefreshCommands` compiles or reindexes them at
|
|
171
|
+
* install time (`scripts.ts`), which is a `.deb`/`.rpm` scriptlet and nothing else.
|
|
172
|
+
*
|
|
173
|
+
* The equality `tests/e2e/ship-layout` checks — same file set, same bytes, modulo
|
|
174
|
+
* the map — is structurally blind to all of it, because SAMENESS IS THE DEFECT:
|
|
175
|
+
* the Linux tree is right for a reason the other two do not have.
|
|
176
|
+
*
|
|
177
|
+
* EXHAUSTIVE, not an allow-list, and that direction is the point. A closed list of
|
|
178
|
+
* five was measured to say "carries 5 file(s)" for a payload carrying six — a
|
|
179
|
+
* `share/dbus-1/services/*.service` added through `gjsify.ship.extraFiles` is
|
|
180
|
+
* meaningful on Linux only because the package installs it into a system prefix,
|
|
181
|
+
* and it went unnamed. Anything under `share/` that is neither classified nor
|
|
182
|
+
* known-portable comes back as `unknown` rather than silently passing.
|
|
183
|
+
*
|
|
184
|
+
* ONE ENTRY IS ANSWERED BY THE SET, not by its own path: the GSettings schema
|
|
185
|
+
* directory aborts the app when it holds a source `.gschema.xml` and no compiled
|
|
186
|
+
* cache, and is merely inert when the cache is beside it. #1354 M2a compiles that
|
|
187
|
+
* cache into every non-Linux stage, so the `aborts` branch is empty for a stage
|
|
188
|
+
* this gjsify wrote — and it is still REACHABLE, which is the point: a stage
|
|
189
|
+
* assembled before the compile step existed, or one whose cache was removed,
|
|
190
|
+
* classifies as `aborts` again with no rule to remember to re-add.
|
|
191
|
+
*
|
|
192
|
+
* What the rest BECOME — an `Info.plist` `CFBundleDocumentTypes`, a Windows
|
|
193
|
+
* registry association, or nothing — is ADR 0024 stages 4 and 5. The `.app`
|
|
194
|
+
* container exists as of M2a; the file-type and icon halves do not.
|
|
195
|
+
*/
|
|
196
|
+
export declare function linuxInstallDependent(entries: readonly {
|
|
197
|
+
path: string;
|
|
198
|
+
}[]): CarriedShareEntry[];
|
|
73
199
|
/**
|
|
74
200
|
* The interpreters the payload's own executables need, read off their shebangs.
|
|
75
201
|
*
|
|
@@ -108,11 +234,22 @@ export declare function isArchIndependent(payload: readonly PayloadEntry[]): boo
|
|
|
108
234
|
* The `process.arch` token an image says it is built for, or `null` when the
|
|
109
235
|
* question cannot be answered from the bytes.
|
|
110
236
|
*
|
|
111
|
-
* `null` covers three different things on purpose, and all three must stay
|
|
112
|
-
* silent: a file that is not a native binary at all (most of a payload),
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
237
|
+
* `null` still covers three different things on purpose, and all three must stay
|
|
238
|
+
* silent: a file that is not a native binary at all (most of a payload), an image
|
|
239
|
+
* whose machine constant is not in the tables above, and a Mach-O fat archive,
|
|
240
|
+
* which carries several architectures and therefore matches any label a caller
|
|
241
|
+
* could pass.
|
|
242
|
+
*
|
|
243
|
+
* PE WAS A FOURTH, AND IT WAS THE WORST ONE. This comment used to say PE was
|
|
244
|
+
* silent because "this tree has never parsed" the COFF machine field — true, and
|
|
245
|
+
* it made `assertPayloadMatchesArch` VACUOUS on the one layout whose native format
|
|
246
|
+
* IS PE. #1354 M2b made that check non-vacuous for darwin by staging Mach-O into a
|
|
247
|
+
* `.app`; M3 stages `node.exe` and a win32 GTK closure into a Windows program
|
|
248
|
+
* directory, so a windows stage built with the wrong `--arch` would have carried
|
|
249
|
+
* x64 DLLs under an `arm64` label with nothing to notice. Two reads — `e_lfanew`
|
|
250
|
+
* at 0x3c, then `Machine` four bytes past the `PE\0\0` signature — close it. A
|
|
251
|
+
* truncated `MZ` with no reachable PE header stays `null`, which is what
|
|
252
|
+
* `packers.spec.ts` has always asserted and still does.
|
|
116
253
|
*/
|
|
117
254
|
export declare function readBinaryArch(data: Uint8Array): string | null;
|
|
118
255
|
/**
|
|
@@ -139,3 +276,17 @@ export declare function readBinaryArch(data: Uint8Array): string | null;
|
|
|
139
276
|
* comparison would refuse the very case the split exists to allow.
|
|
140
277
|
*/
|
|
141
278
|
export declare function assertPayloadMatchesArch(payload: readonly PayloadEntry[], arch: string): void;
|
|
279
|
+
/**
|
|
280
|
+
* Which executable format these bytes are, or `null` for anything else.
|
|
281
|
+
*
|
|
282
|
+
* The FAMILY and not merely "is it native", because the signer needs the
|
|
283
|
+
* distinction: `codesign` signs Mach-O and `signtool` signs PE, and an ELF in a
|
|
284
|
+
* darwin payload is neither — it is a file that should not be there. A caller
|
|
285
|
+
* asking only "is this native" would have handed one to `codesign`, whose
|
|
286
|
+
* refusal names a file rather than the mistake.
|
|
287
|
+
*
|
|
288
|
+
* Magic numbers rather than suffixes, and that is load-bearing on darwin: a GTK
|
|
289
|
+
* closure names its images `.dylib`, `.so`, `.node` and nothing at all (the
|
|
290
|
+
* interpreter), so a suffix list signs three of those four.
|
|
291
|
+
*/
|
|
292
|
+
export declare function classifyBinary(data: Uint8Array): 'elf' | 'macho' | 'pe' | null;
|