@timurproko/a1-install 0.2.1-dev.602 → 0.2.1-dev.604
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/README.md +11 -3
- package/bin/a1-install.js +49 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,18 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Dependency-free installer for [`@timurproko/a1`](https://www.npmjs.com/package/@timurproko/a1).
|
|
4
4
|
|
|
5
|
+
Release:
|
|
6
|
+
|
|
5
7
|
```sh
|
|
6
8
|
npx -y @timurproko/a1-install
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
Develop:
|
|
10
12
|
|
|
11
13
|
```sh
|
|
12
14
|
npx -y @timurproko/a1-install --develop
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
Preview number:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npx -y @timurproko/a1-install --develop 107
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Exact preview:
|
|
16
24
|
|
|
17
25
|
```sh
|
|
18
|
-
npx -y @timurproko/a1-install --
|
|
26
|
+
npx -y @timurproko/a1-install --develop 0.1.8-dev.107
|
|
19
27
|
```
|
package/bin/a1-install.js
CHANGED
|
@@ -21,6 +21,7 @@ const PHASES = new Set([
|
|
|
21
21
|
]);
|
|
22
22
|
const STABLE_VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/u;
|
|
23
23
|
const DEVELOPMENT_VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)-dev\.[1-9]\d*$/u;
|
|
24
|
+
const PREVIEW_NUMBER_PATTERN = /^[1-9]\d*$/u;
|
|
24
25
|
const VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-dev\.[1-9]\d*)?$/u;
|
|
25
26
|
|
|
26
27
|
class InstallationFailure extends Error {
|
|
@@ -59,23 +60,15 @@ export function parseArguments(argv) {
|
|
|
59
60
|
continue;
|
|
60
61
|
}
|
|
61
62
|
if (value === "--develop") {
|
|
62
|
-
if (target.kind === "version") throw new InstallationFailure("--develop cannot be combined with --version", "", 2);
|
|
63
63
|
if (target.kind !== "stable") throw new InstallationFailure("--develop was supplied more than once", "", 2);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
if (!DEVELOPMENT_VERSION_PATTERN.test(version)) {
|
|
73
|
-
throw new InstallationFailure("--version requires an exact development version", "", 2);
|
|
74
|
-
}
|
|
75
|
-
if (target.kind === "develop") throw new InstallationFailure("--develop cannot be combined with --version", "", 2);
|
|
76
|
-
if (target.kind !== "stable") throw new InstallationFailure("--version was supplied more than once", "", 2);
|
|
77
|
-
target = { kind: "version", version };
|
|
78
|
-
index += 1;
|
|
64
|
+
const requested = argv[index + 1];
|
|
65
|
+
if (requested !== undefined && !requested.startsWith("-")) {
|
|
66
|
+
if (!PREVIEW_NUMBER_PATTERN.test(requested) && !DEVELOPMENT_VERSION_PATTERN.test(requested)) {
|
|
67
|
+
throw new InstallationFailure("unexpected argument", requested, 2);
|
|
68
|
+
}
|
|
69
|
+
target = { kind: "preview", requested };
|
|
70
|
+
index += 1;
|
|
71
|
+
} else target = { kind: "develop" };
|
|
79
72
|
continue;
|
|
80
73
|
}
|
|
81
74
|
if (value?.startsWith("-")) throw new InstallationFailure("unsupported option", "", 2);
|
|
@@ -91,7 +84,7 @@ export function installerHelp() {
|
|
|
91
84
|
return [
|
|
92
85
|
"a1-install",
|
|
93
86
|
"a1-install --develop",
|
|
94
|
-
"a1-install --
|
|
87
|
+
"a1-install --develop <preview-or-version>",
|
|
95
88
|
"a1-install --verbose",
|
|
96
89
|
"",
|
|
97
90
|
].join("\n");
|
|
@@ -152,17 +145,15 @@ class ProgressDisplay {
|
|
|
152
145
|
this.interval = options.interval ?? 200;
|
|
153
146
|
this.current = 0;
|
|
154
147
|
this.shown = -1;
|
|
155
|
-
this.label = "Preparing";
|
|
156
148
|
this.timer = null;
|
|
157
149
|
this.visible = false;
|
|
158
|
-
this.maxWidth = PROGRESS_WIDTH + 6
|
|
150
|
+
this.maxWidth = PROGRESS_WIDTH + 6;
|
|
159
151
|
}
|
|
160
152
|
|
|
161
|
-
set(percent,
|
|
153
|
+
set(percent, _label, creepTo = percent) {
|
|
162
154
|
if (!this.enabled) return;
|
|
163
155
|
this.stop();
|
|
164
156
|
this.current = Math.max(this.current, percent);
|
|
165
|
-
if (PHASES.has(label)) this.label = label;
|
|
166
157
|
this.shown = -1;
|
|
167
158
|
this.draw();
|
|
168
159
|
if (creepTo <= this.current) return;
|
|
@@ -179,7 +170,7 @@ class ProgressDisplay {
|
|
|
179
170
|
this.shown = rounded;
|
|
180
171
|
if (!this.visible) this.output.write("\u001b[?25l");
|
|
181
172
|
this.visible = true;
|
|
182
|
-
this.output.write(`\r${renderProgressBar(rounded)}
|
|
173
|
+
this.output.write(`\r${renderProgressBar(rounded)}\u001b[K`);
|
|
183
174
|
}
|
|
184
175
|
|
|
185
176
|
finish() {
|
|
@@ -278,13 +269,19 @@ async function runChild(command, args, options) {
|
|
|
278
269
|
|
|
279
270
|
function targetSpec(target) {
|
|
280
271
|
if (target.kind === "develop") return `${APPLICATION_PACKAGE}@next`;
|
|
281
|
-
if (target.kind === "version") return `${APPLICATION_PACKAGE}@${target.version}`;
|
|
282
272
|
return `${APPLICATION_PACKAGE}@latest`;
|
|
283
273
|
}
|
|
284
274
|
|
|
285
|
-
function
|
|
275
|
+
function resolutionArguments(target) {
|
|
276
|
+
if (target.kind === "preview") {
|
|
277
|
+
return ["view", APPLICATION_PACKAGE, "versions", "--json", "--loglevel=verbose", "--no-fund", "--no-audit"];
|
|
278
|
+
}
|
|
279
|
+
return ["view", targetSpec(target), "version", "--json", "--loglevel=verbose", "--no-fund", "--no-audit"];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function updateArguments(target, targetVersion) {
|
|
286
283
|
if (target.kind === "develop") return ["update", "--develop"];
|
|
287
|
-
if (target.kind === "
|
|
284
|
+
if (target.kind === "preview") return ["update", "--develop", targetVersion];
|
|
288
285
|
return ["update"];
|
|
289
286
|
}
|
|
290
287
|
|
|
@@ -302,10 +299,28 @@ function parseResolvedVersion(stdout, target) {
|
|
|
302
299
|
if (!VERSION_PATTERN.test(value)) throw new InstallationFailure("could not resolve the selected release", text);
|
|
303
300
|
if (target.kind === "stable" && !STABLE_VERSION_PATTERN.test(value)) throw new InstallationFailure("could not resolve the selected release", text);
|
|
304
301
|
if (target.kind === "develop" && !DEVELOPMENT_VERSION_PATTERN.test(value)) throw new InstallationFailure("could not resolve the selected release", text);
|
|
305
|
-
if (target.kind === "
|
|
302
|
+
if (target.kind === "preview" && value !== target.requested) throw new InstallationFailure("the selected release was not found", text);
|
|
306
303
|
return value;
|
|
307
304
|
}
|
|
308
305
|
|
|
306
|
+
export function resolvePublishedPreview(stdout, requested) {
|
|
307
|
+
let published;
|
|
308
|
+
try { published = JSON.parse(String(stdout).trim() || "[]"); }
|
|
309
|
+
catch { throw new InstallationFailure("could not resolve the selected release", String(stdout)); }
|
|
310
|
+
const versions = (Array.isArray(published) ? published : [published])
|
|
311
|
+
.filter(value => typeof value === "string" && DEVELOPMENT_VERSION_PATTERN.test(value));
|
|
312
|
+
if (DEVELOPMENT_VERSION_PATTERN.test(requested)) {
|
|
313
|
+
if (versions.includes(requested)) return requested;
|
|
314
|
+
throw new InstallationFailure("the selected release was not found", `published no preview ${requested}`);
|
|
315
|
+
}
|
|
316
|
+
const matches = versions.filter(version => version.endsWith(`-dev.${requested}`));
|
|
317
|
+
if (matches.length === 1) return matches[0];
|
|
318
|
+
const detail = matches.length === 0
|
|
319
|
+
? `published no preview for ${requested}`
|
|
320
|
+
: `found more than one preview for ${requested}: ${matches.join(", ")}`;
|
|
321
|
+
throw new InstallationFailure("the selected release was not found", detail);
|
|
322
|
+
}
|
|
323
|
+
|
|
309
324
|
function packageRootFor(globalRoot) {
|
|
310
325
|
return resolve(globalRoot, ...APPLICATION_PACKAGE.split("/"));
|
|
311
326
|
}
|
|
@@ -360,11 +375,13 @@ async function verifyLaunchers(globalRoot, platform) {
|
|
|
360
375
|
const paths = launcherPaths(globalRoot, platform);
|
|
361
376
|
const entry = resolve(packageRootFor(globalRoot), "bin", "cli.js");
|
|
362
377
|
const expectedSuffix = `${APPLICATION_PACKAGE}/bin/cli.js`;
|
|
378
|
+
let canonicalEntry = null;
|
|
363
379
|
for (const path of paths) {
|
|
364
380
|
try {
|
|
365
381
|
const metadata = await lstat(path);
|
|
366
382
|
if (metadata.isSymbolicLink()) {
|
|
367
|
-
if (
|
|
383
|
+
if (canonicalEntry === null) canonicalEntry = normalizePath(await realpath(entry), platform);
|
|
384
|
+
if (normalizePath(await realpath(path), platform) !== canonicalEntry) throw new Error("launcher target differs");
|
|
368
385
|
} else if (metadata.isFile()) {
|
|
369
386
|
const content = await readFile(path, "utf8");
|
|
370
387
|
if (content.length > 32_768 || !content.replaceAll("\\", "/").includes(expectedSuffix)) throw new Error("launcher content differs");
|
|
@@ -505,16 +522,16 @@ export async function runInstaller(argv, options = {}) {
|
|
|
505
522
|
try {
|
|
506
523
|
progress.set(3, "Preparing", 10);
|
|
507
524
|
let phase = "Resolving version";
|
|
508
|
-
const resolveResult = await runner.npm(
|
|
509
|
-
"view", targetSpec(parsed.target), "version", "--json", "--loglevel=verbose", "--no-fund", "--no-audit",
|
|
510
|
-
], {
|
|
525
|
+
const resolveResult = await runner.npm(resolutionArguments(parsed.target), {
|
|
511
526
|
onChild: setActiveChild,
|
|
512
527
|
onStderrLine: line => { phase = classifyProgressLine(line, phase); progress.set(10, phase, 18); },
|
|
513
528
|
});
|
|
514
529
|
setActiveChild(null);
|
|
515
530
|
if (cancelled) throw new InstallationCancelled();
|
|
516
531
|
if (resolveResult.code !== 0) throw new InstallationFailure(conciseFailure("resolve", resolveResult.stderr), resolveResult.stderr);
|
|
517
|
-
const targetVersion =
|
|
532
|
+
const targetVersion = parsed.target.kind === "preview"
|
|
533
|
+
? resolvePublishedPreview(resolveResult.stdout, parsed.target.requested)
|
|
534
|
+
: parseResolvedVersion(resolveResult.stdout, parsed.target);
|
|
518
535
|
progress.set(18, "Resolving packages", 24);
|
|
519
536
|
|
|
520
537
|
const rootResult = await runner.npm(["root", "--global", "--loglevel=error", "--no-fund", "--no-audit"], { onChild: setActiveChild });
|
|
@@ -541,7 +558,7 @@ export async function runInstaller(argv, options = {}) {
|
|
|
541
558
|
throw new InstallationFailure("existing installation ownership could not be verified", error instanceof Error ? error.message : String(error));
|
|
542
559
|
}
|
|
543
560
|
progress.set(24, "Installing", 90);
|
|
544
|
-
const updateResult = await runner.node(cli, updateArguments(parsed.target), { onChild: setActiveChild });
|
|
561
|
+
const updateResult = await runner.node(cli, updateArguments(parsed.target, targetVersion), { onChild: setActiveChild });
|
|
545
562
|
setActiveChild(null);
|
|
546
563
|
if (cancelled) throw new InstallationCancelled();
|
|
547
564
|
if (updateResult.code !== 0) {
|