@edspencer/paddock 0.82.0 → 0.82.1
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/package.json +1 -1
- package/packages/server/dist/cli/args.js +2 -2
- package/packages/server/dist/cli/busy-command.js +1 -1
- package/packages/server/dist/cli/busy.js +10 -12
- package/packages/server/dist/cli/exit-codes.d.ts +21 -45
- package/packages/server/dist/cli/exit-codes.js +42 -45
- package/packages/server/dist/cli/output.js +5 -6
- package/packages/server/dist/cli/paddock.js +9 -9
- package/packages/server/dist/cli/service/index.d.ts +2 -2
- package/packages/server/dist/cli/service/index.js +30 -24
- package/packages/server/dist/cli/service/launchd.d.ts +31 -84
- package/packages/server/dist/cli/service/launchd.js +104 -304
- package/packages/server/dist/cli/service/logs.d.ts +9 -28
- package/packages/server/dist/cli/service/logs.js +33 -75
- package/packages/server/dist/cli/service/manager.d.ts +93 -0
- package/packages/server/dist/cli/service/manager.js +21 -0
- package/packages/server/dist/cli/service/path-env.d.ts +7 -18
- package/packages/server/dist/cli/service/path-env.js +30 -81
- package/packages/server/dist/cli/service/spec.d.ts +4 -31
- package/packages/server/dist/cli/service/spec.js +9 -0
- package/packages/server/dist/cli/service/systemd.d.ts +27 -101
- package/packages/server/dist/cli/service/systemd.js +106 -262
- package/packages/server/dist/cli/update/health.d.ts +48 -0
- package/packages/server/dist/cli/update/health.js +64 -0
- package/packages/server/dist/cli/update/install-method.d.ts +29 -76
- package/packages/server/dist/cli/update/install-method.js +103 -178
- package/packages/server/dist/cli/update/lock.d.ts +7 -12
- package/packages/server/dist/cli/update/lock.js +28 -62
- package/packages/server/dist/cli/update/package-manager.d.ts +39 -74
- package/packages/server/dist/cli/update/package-manager.js +95 -160
- package/packages/server/dist/cli/update/registry.d.ts +17 -54
- package/packages/server/dist/cli/update/registry.js +46 -89
- package/packages/server/dist/cli/update/semver.d.ts +18 -41
- package/packages/server/dist/cli/update/semver.js +74 -124
- package/packages/server/dist/cli/update/update-check.d.ts +15 -26
- package/packages/server/dist/cli/update/update-check.js +30 -60
- package/packages/server/dist/cli/update/update.d.ts +57 -91
- package/packages/server/dist/cli/update/update.js +230 -431
- package/packages/server/dist/cli/update-command.js +3 -5
- package/packages/server/package.json +1 -1
- package/packages/web/dist/assets/{DeleteProjectDialog-CphdGB3R.js → DeleteProjectDialog-CgHpQctt.js} +1 -1
- package/packages/web/dist/assets/DiscoverPage-CG6cf-0i.js +2 -0
- package/packages/web/dist/assets/{DiscoverView-B_kcF4sm.js → DiscoverView-BKqI0I1E.js} +1 -1
- package/packages/web/dist/assets/{InstanceConfigPage-CvUK5DKW.js → InstanceConfigPage-DL3raCK1.js} +1 -1
- package/packages/web/dist/assets/{MarkdownRenderer-DvZ-j_Ao.js → MarkdownRenderer-DcjEuf3s.js} +1 -1
- package/packages/web/dist/assets/{ProjectRedirect-DayHvUH2.js → ProjectRedirect-DerkA-nE.js} +1 -1
- package/packages/web/dist/assets/{ProjectView-CCw83gUi.js → ProjectView-NwfC3_w7.js} +3 -3
- package/packages/web/dist/assets/{ProjectsGrid-B3Klg2H4.js → ProjectsGrid-BeORa0UH.js} +1 -1
- package/packages/web/dist/assets/{RootHome-BxcDvpgI.js → RootHome-BYJs8qJ6.js} +1 -1
- package/packages/web/dist/assets/{Surfaces-7UlhFBSG.js → Surfaces-w-kEaAYU.js} +1 -1
- package/packages/web/dist/assets/{arc-DNkh5o5Q.js → arc-Bv56hasM.js} +1 -1
- package/packages/web/dist/assets/{architectureDiagram-3BPJPVTR-BrgN3oLF.js → architectureDiagram-3BPJPVTR-BHEknx9i.js} +1 -1
- package/packages/web/dist/assets/{blockDiagram-GPEHLZMM-D05XOJSk.js → blockDiagram-GPEHLZMM-DtxTMrPX.js} +1 -1
- package/packages/web/dist/assets/{c4Diagram-AAUBKEIU-CKaMBhMP.js → c4Diagram-AAUBKEIU-DRpEYOlM.js} +1 -1
- package/packages/web/dist/assets/channel-CdIiAqY2.js +2 -0
- package/packages/web/dist/assets/{chunk-2J33WTMH-8hgadCQc.js → chunk-2J33WTMH-S4s7GCg7.js} +1 -1
- package/packages/web/dist/assets/{chunk-4BX2VUAB-CBfEC-pu.js → chunk-4BX2VUAB-BkWVPLf1.js} +1 -1
- package/packages/web/dist/assets/{chunk-55IACEB6-DV1eMgHk.js → chunk-55IACEB6-4-FQp01F.js} +1 -1
- package/packages/web/dist/assets/{chunk-727SXJPM-Cfgl5fxY.js → chunk-727SXJPM-BeyDWdIb.js} +1 -1
- package/packages/web/dist/assets/{chunk-AQP2D5EJ-BXhqD295.js → chunk-AQP2D5EJ-ZSxKy745.js} +1 -1
- package/packages/web/dist/assets/{chunk-FMBD7UC4-TFGOPtek.js → chunk-FMBD7UC4-Bq8uV9j-.js} +1 -1
- package/packages/web/dist/assets/{chunk-ND2GUHAM-CHFM665R.js → chunk-ND2GUHAM-BOFsRyHk.js} +1 -1
- package/packages/web/dist/assets/{chunk-QZHKN3VN-CqEf6MMT.js → chunk-QZHKN3VN-uZ6oNc4m.js} +1 -1
- package/packages/web/dist/assets/classDiagram-4FO5ZUOK-DCCUHba0.js +2 -0
- package/packages/web/dist/assets/classDiagram-v2-Q7XG4LA2-DCCUHba0.js +2 -0
- package/packages/web/dist/assets/{core-DmEaKxBb.js → core-CYuJAM2U.js} +1 -1
- package/packages/web/dist/assets/{cose-bilkent-S5V4N54A-BnGI6jkr.js → cose-bilkent-S5V4N54A-DIzkVSFb.js} +1 -1
- package/packages/web/dist/assets/{dagre-BM42HDAG-CKoPx61E.js → dagre-BM42HDAG-CHR6jJBv.js} +1 -1
- package/packages/web/dist/assets/{diagram-2AECGRRQ-mMmtlBl1.js → diagram-2AECGRRQ-BAFXCH8Q.js} +1 -1
- package/packages/web/dist/assets/{diagram-5GNKFQAL-Cdz9Mtnt.js → diagram-5GNKFQAL-BJ5t5gbz.js} +1 -1
- package/packages/web/dist/assets/{diagram-KO2AKTUF-DQxM3wYj.js → diagram-KO2AKTUF-D9Xt0IVg.js} +1 -1
- package/packages/web/dist/assets/{diagram-LMA3HP47-BWrinPsq.js → diagram-LMA3HP47-Bq38u6sy.js} +1 -1
- package/packages/web/dist/assets/{diagram-OG6HWLK6-U6MYUve2.js → diagram-OG6HWLK6-CMQVqkpi.js} +1 -1
- package/packages/web/dist/assets/{documentTitle-DGjRXuTP.js → documentTitle-M1lrfXRU.js} +1 -1
- package/packages/web/dist/assets/{erDiagram-TEJ5UH35-xqMCsXxY.js → erDiagram-TEJ5UH35-C63M1g9b.js} +1 -1
- package/packages/web/dist/assets/{flowDiagram-I6XJVG4X-PMfy_czF.js → flowDiagram-I6XJVG4X-D3j8ACN7.js} +1 -1
- package/packages/web/dist/assets/{ganttDiagram-6RSMTGT7-whhYYE4N.js → ganttDiagram-6RSMTGT7-B1Fd1A2Y.js} +1 -1
- package/packages/web/dist/assets/{gitGraphDiagram-PVQCEYII-C51JW4tf.js → gitGraphDiagram-PVQCEYII-CEhZhDdR.js} +1 -1
- package/packages/web/dist/assets/{index-CHOtvlnO.js → index-1E9yHciS.js} +2 -2
- package/packages/web/dist/assets/{infoDiagram-5YYISTIA-SH8cr905.js → infoDiagram-5YYISTIA-Ctquaew6.js} +1 -1
- package/packages/web/dist/assets/{ishikawaDiagram-YF4QCWOH-BjqaoU3U.js → ishikawaDiagram-YF4QCWOH-DV4GvA1R.js} +1 -1
- package/packages/web/dist/assets/{journeyDiagram-JHISSGLW-CBmdEVrd.js → journeyDiagram-JHISSGLW-C_Cy9waA.js} +1 -1
- package/packages/web/dist/assets/{kanban-definition-UN3LZRKU-U8njjMLZ.js → kanban-definition-UN3LZRKU-CGr9ctEf.js} +1 -1
- package/packages/web/dist/assets/{linear-DF66GPs1.js → linear-D3U8NOkt.js} +1 -1
- package/packages/web/dist/assets/{mermaid.core-CouJz7Ph.js → mermaid.core-BiArdWKV.js} +4 -4
- package/packages/web/dist/assets/{mindmap-definition-RKZ34NQL-BYIf0oFt.js → mindmap-definition-RKZ34NQL-CZIpzj8Z.js} +1 -1
- package/packages/web/dist/assets/{pieDiagram-4H26LBE5-Cm8rgg09.js → pieDiagram-4H26LBE5-1MaeS3rt.js} +1 -1
- package/packages/web/dist/assets/{quadrantDiagram-W4KKPZXB-C3Il5kOH.js → quadrantDiagram-W4KKPZXB-B5pgQ54e.js} +1 -1
- package/packages/web/dist/assets/{requirementDiagram-4Y6WPE33-D3PE2nTe.js → requirementDiagram-4Y6WPE33-BNnxrpGr.js} +1 -1
- package/packages/web/dist/assets/{sankeyDiagram-5OEKKPKP-DdmvBM18.js → sankeyDiagram-5OEKKPKP-DsxVH-hM.js} +1 -1
- package/packages/web/dist/assets/{sequenceDiagram-3UESZ5HK-B8M_GAIq.js → sequenceDiagram-3UESZ5HK-Ke9LcFZI.js} +1 -1
- package/packages/web/dist/assets/{stateDiagram-AJRCARHV-DZkXnK1_.js → stateDiagram-AJRCARHV-UJzmflND.js} +1 -1
- package/packages/web/dist/assets/stateDiagram-v2-BHNVJYJU-DgUc3HkP.js +2 -0
- package/packages/web/dist/assets/{timeline-definition-PNZ67QCA-IHXq7rqi.js → timeline-definition-PNZ67QCA-BRjNALVI.js} +1 -1
- package/packages/web/dist/assets/{vennDiagram-CIIHVFJN-Dga7tLtT.js → vennDiagram-CIIHVFJN-ClMAspxz.js} +1 -1
- package/packages/web/dist/assets/{wardley-L42UT6IY-CmcwnEJ-.js → wardley-L42UT6IY-UPv4JEmz.js} +1 -1
- package/packages/web/dist/assets/{wardleyDiagram-YWT4CUSO-zHuSLrD4.js → wardleyDiagram-YWT4CUSO-BgYJbdEx.js} +1 -1
- package/packages/web/dist/assets/{xychartDiagram-2RQKCTM6-D93MU_ic.js → xychartDiagram-2RQKCTM6-Bfk5HjGx.js} +1 -1
- package/packages/web/dist/index.html +1 -1
- package/packages/web/dist/sw.js +1 -1
- package/packages/server/dist/cli/service/backend.d.ts +0 -115
- package/packages/server/dist/cli/service/backend.js +0 -19
- package/packages/web/dist/assets/DiscoverPage-C4OPLNO8.js +0 -2
- package/packages/web/dist/assets/channel-JrEedxB8.js +0 -2
- package/packages/web/dist/assets/classDiagram-4FO5ZUOK-CHJiQp-W.js +0 -2
- package/packages/web/dist/assets/classDiagram-v2-Q7XG4LA2-CHJiQp-W.js +0 -2
- package/packages/web/dist/assets/stateDiagram-v2-BHNVJYJU-CjCdT9Ls.js +0 -2
|
@@ -1,55 +1,24 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The npm registry, as `update` asks it (CLI contract SPEC §5 step 3).
|
|
3
|
-
*
|
|
4
|
-
* Two requests, both with `fetch` and a 10-second abort, and nothing else:
|
|
5
|
-
*
|
|
6
|
-
* GET <registry>/-/package/<name>/dist-tags which version is `latest`
|
|
7
|
-
* GET <registry>/<name>/<version> that version's `engines`
|
|
8
|
-
*
|
|
9
|
-
* Deliberately NOT `npm view`: spawning npm to read two small JSON documents
|
|
10
|
-
* costs a second of process start-up, needs npm to be on PATH at all, and puts
|
|
11
|
-
* the registry's answer through a program whose output format is not a
|
|
12
|
-
* contract. `fetch` is in Node 22 and the registry's REST surface has been
|
|
13
|
-
* stable for a decade.
|
|
14
|
-
*
|
|
15
|
-
* **Nothing here is called except by a person.** SPEC §3: only `update`,
|
|
16
|
-
* `update --check` and `doctor` contact the registry, and only when someone
|
|
17
|
-
* runs them. There is no background check and no check at startup, which is why
|
|
18
|
-
* this module is reachable from the CLI and from nowhere in the server.
|
|
19
|
-
*
|
|
20
|
-
* Generic: wave C4 lifts it into `reference/registry.ts`.
|
|
21
|
-
*/
|
|
22
|
-
/** SPEC §5: 10 seconds, and it is the budget for each request rather than the pair. */
|
|
1
|
+
/** SPEC §5: 10 seconds for each request. */
|
|
23
2
|
export declare const REGISTRY_TIMEOUT_MS = 10000;
|
|
24
3
|
export declare const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
25
4
|
export interface RegistryOptions {
|
|
26
5
|
packageName: string;
|
|
27
|
-
/**
|
|
6
|
+
/** The base URL; a trailing slash is fine. */
|
|
28
7
|
registry: string;
|
|
29
8
|
fetch?: typeof globalThis.fetch;
|
|
30
9
|
timeoutMs?: number;
|
|
31
10
|
}
|
|
32
11
|
/**
|
|
33
|
-
* Which registry to ask: `npm_config_registry`, else `npm config get registry`,
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* The first is what makes the fake-registry tests possible without touching a
|
|
37
|
-
* global npm config — an `npm_config_registry` in the environment is how npm
|
|
38
|
-
* itself takes the same setting, so a test and a real `.npmrc` arrive by the
|
|
39
|
-
* same door.
|
|
12
|
+
* Which registry to ask: `npm_config_registry`, else `npm config get registry`, else the public one (SPEC §5 step 3).
|
|
13
|
+
* The variable comes first because it's how npm itself takes the setting, so a test and a real `.npmrc` arrive the
|
|
14
|
+
* same way.
|
|
40
15
|
*/
|
|
41
16
|
export declare function resolveRegistry(env: NodeJS.ProcessEnv, npmConfigGet?: (key: string) => string | undefined): string;
|
|
42
|
-
/**
|
|
43
|
-
* Join a path onto the registry base.
|
|
44
|
-
*
|
|
45
|
-
* A scoped name's `/` is written `%2f` (SPEC §5 step 3). That is required by
|
|
46
|
-
* the dist-tags route and accepted by the manifest route, so both are built the
|
|
47
|
-
* same way — one rule instead of two, and no chance of only one of them being
|
|
48
|
-
* right for `@scope/name`.
|
|
49
|
-
*/
|
|
17
|
+
/** Joins path parts onto the registry, writing a scoped name's `/` as `%2f` (SPEC §5 step 3). Both routes take it. */
|
|
50
18
|
export declare function registryUrl(registry: string, ...parts: string[]): string;
|
|
51
|
-
/**
|
|
19
|
+
/** Anything that went wrong talking to the registry, with the URL, as one reportable error. */
|
|
52
20
|
export declare class RegistryError extends Error {
|
|
21
|
+
name: string;
|
|
53
22
|
readonly url: string;
|
|
54
23
|
constructor(url: string, message: string);
|
|
55
24
|
}
|
|
@@ -62,28 +31,22 @@ export interface PackageManifest {
|
|
|
62
31
|
node?: string;
|
|
63
32
|
};
|
|
64
33
|
}
|
|
65
|
-
/** One version's manifest
|
|
34
|
+
/** One version's manifest, read for `engines`. */
|
|
66
35
|
export declare function fetchManifest(o: RegistryOptions & {
|
|
67
36
|
version: string;
|
|
68
37
|
}): Promise<PackageManifest>;
|
|
69
|
-
export interface ResolveTargetInput extends RegistryOptions {
|
|
70
|
-
/** `--to <version|tag>`, or undefined for `latest`. */
|
|
71
|
-
to?: string;
|
|
72
|
-
}
|
|
73
38
|
export interface ResolvedTarget {
|
|
74
39
|
version: string;
|
|
75
|
-
/** The dist-tag asked for, or null when `--to` named a version
|
|
40
|
+
/** The dist-tag asked for, or null when `--to` named a version. */
|
|
76
41
|
tag: string | null;
|
|
42
|
+
/** The target's `engines.node`. */
|
|
77
43
|
engines: string | null;
|
|
78
44
|
}
|
|
79
45
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* asking: anything that parses as a version is a version, everything else is a
|
|
84
|
-
* tag. That ordering matters because a registry will happily serve a manifest
|
|
85
|
-
* for a tag name as well, and resolving `--to next` as a literal version would
|
|
86
|
-
* silently install whatever `next` pointed at while REPORTING the target as
|
|
87
|
-
* "next".
|
|
46
|
+
* `--to` (or `latest` without it) as one version, with its `engines`. A version and a tag are told apart by shape:
|
|
47
|
+
* anything that looks like a version is one. Asking first would be wrong, since a registry may serve a manifest for a
|
|
48
|
+
* tag's name too, and `--to next` would then install `next` while reporting it as a version called "next".
|
|
88
49
|
*/
|
|
89
|
-
export declare function resolveTarget(o:
|
|
50
|
+
export declare function resolveTarget(o: RegistryOptions & {
|
|
51
|
+
to?: string;
|
|
52
|
+
}): Promise<ResolvedTarget>;
|
|
@@ -1,60 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* the registry's answer through a program whose output format is not a
|
|
12
|
-
* contract. `fetch` is in Node 22 and the registry's REST surface has been
|
|
13
|
-
* stable for a decade.
|
|
14
|
-
*
|
|
15
|
-
* **Nothing here is called except by a person.** SPEC §3: only `update`,
|
|
16
|
-
* `update --check` and `doctor` contact the registry, and only when someone
|
|
17
|
-
* runs them. There is no background check and no check at startup, which is why
|
|
18
|
-
* this module is reachable from the CLI and from nowhere in the server.
|
|
19
|
-
*
|
|
20
|
-
* Generic: wave C4 lifts it into `reference/registry.ts`.
|
|
21
|
-
*/
|
|
22
|
-
/** SPEC §5: 10 seconds, and it is the budget for each request rather than the pair. */
|
|
1
|
+
// From edspencer/cli-contract reference/registry.ts @ 0.2; local changes: `.ts` import specifiers → `.js`.
|
|
2
|
+
// The npm registry, as `update` asks it (SPEC §5 step 3): two requests with `fetch` and a 10-second abort.
|
|
3
|
+
//
|
|
4
|
+
// GET <registry>/-/package/<name>/dist-tags which version `latest` (or `--to <tag>`) is
|
|
5
|
+
// GET <registry>/<name>/<version> that version's `engines`
|
|
6
|
+
//
|
|
7
|
+
// Not `npm view`: that's a second of start-up to read two small documents, through a program whose output isn't a
|
|
8
|
+
// contract. Only `update`, `update --check` and `doctor` call this, and only when a person runs them (SPEC §3).
|
|
9
|
+
// Node built-ins only.
|
|
10
|
+
/** SPEC §5: 10 seconds for each request. */
|
|
23
11
|
export const REGISTRY_TIMEOUT_MS = 10_000;
|
|
24
|
-
export const DEFAULT_REGISTRY =
|
|
12
|
+
export const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
|
|
25
13
|
/**
|
|
26
|
-
* Which registry to ask: `npm_config_registry`, else `npm config get registry`,
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* The first is what makes the fake-registry tests possible without touching a
|
|
30
|
-
* global npm config — an `npm_config_registry` in the environment is how npm
|
|
31
|
-
* itself takes the same setting, so a test and a real `.npmrc` arrive by the
|
|
32
|
-
* same door.
|
|
14
|
+
* Which registry to ask: `npm_config_registry`, else `npm config get registry`, else the public one (SPEC §5 step 3).
|
|
15
|
+
* The variable comes first because it's how npm itself takes the setting, so a test and a real `.npmrc` arrive the
|
|
16
|
+
* same way.
|
|
33
17
|
*/
|
|
34
18
|
export function resolveRegistry(env, npmConfigGet) {
|
|
35
19
|
const fromEnv = env.npm_config_registry ?? env.NPM_CONFIG_REGISTRY;
|
|
36
|
-
if (fromEnv !== undefined && fromEnv.trim() !==
|
|
20
|
+
if (fromEnv !== undefined && fromEnv.trim() !== '')
|
|
37
21
|
return fromEnv.trim();
|
|
38
|
-
const fromNpm = npmConfigGet?.(
|
|
39
|
-
if (fromNpm !== undefined && fromNpm
|
|
40
|
-
return fromNpm
|
|
41
|
-
}
|
|
22
|
+
const fromNpm = npmConfigGet?.('registry')?.trim();
|
|
23
|
+
if (fromNpm !== undefined && fromNpm !== '' && fromNpm !== 'undefined')
|
|
24
|
+
return fromNpm;
|
|
42
25
|
return DEFAULT_REGISTRY;
|
|
43
26
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Join a path onto the registry base.
|
|
46
|
-
*
|
|
47
|
-
* A scoped name's `/` is written `%2f` (SPEC §5 step 3). That is required by
|
|
48
|
-
* the dist-tags route and accepted by the manifest route, so both are built the
|
|
49
|
-
* same way — one rule instead of two, and no chance of only one of them being
|
|
50
|
-
* right for `@scope/name`.
|
|
51
|
-
*/
|
|
27
|
+
/** Joins path parts onto the registry, writing a scoped name's `/` as `%2f` (SPEC §5 step 3). Both routes take it. */
|
|
52
28
|
export function registryUrl(registry, ...parts) {
|
|
53
|
-
|
|
54
|
-
return `${base}/${parts.map((p) => p.replace(/\//g, "%2f")).join("/")}`;
|
|
29
|
+
return `${registry.replace(/\/+$/, '')}/${parts.map((p) => p.replace(/\//g, '%2f')).join('/')}`;
|
|
55
30
|
}
|
|
56
|
-
/**
|
|
31
|
+
/** Anything that went wrong talking to the registry, with the URL, as one reportable error. */
|
|
57
32
|
export class RegistryError extends Error {
|
|
33
|
+
name = 'RegistryError';
|
|
58
34
|
url;
|
|
59
35
|
constructor(url, message) {
|
|
60
36
|
super(message);
|
|
@@ -62,83 +38,64 @@ export class RegistryError extends Error {
|
|
|
62
38
|
}
|
|
63
39
|
}
|
|
64
40
|
async function getJson(url, o) {
|
|
65
|
-
const
|
|
41
|
+
const timeoutMs = o.timeoutMs ?? REGISTRY_TIMEOUT_MS;
|
|
66
42
|
let res;
|
|
67
43
|
try {
|
|
68
|
-
res = await
|
|
69
|
-
signal: AbortSignal.timeout(o.timeoutMs ?? REGISTRY_TIMEOUT_MS),
|
|
70
|
-
headers: { accept: "application/json" },
|
|
71
|
-
});
|
|
44
|
+
res = await (o.fetch ?? globalThis.fetch)(url, { signal: AbortSignal.timeout(timeoutMs), headers: { accept: 'application/json' } });
|
|
72
45
|
}
|
|
73
46
|
catch (err) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
throw new RegistryError(url, `could not reach the registry: ${why}`);
|
|
47
|
+
const name = err.name;
|
|
48
|
+
const why = name === 'TimeoutError' || name === 'AbortError' ? `no answer within ${timeoutMs / 1000} seconds` : (err.message ?? String(err));
|
|
49
|
+
throw new RegistryError(url, `couldn't reach the registry: ${why}`);
|
|
78
50
|
}
|
|
79
51
|
if (res.status === 404)
|
|
80
|
-
throw new RegistryError(url,
|
|
52
|
+
throw new RegistryError(url, 'the registry has no such package or version');
|
|
81
53
|
if (!res.ok)
|
|
82
54
|
throw new RegistryError(url, `the registry answered HTTP ${res.status}`);
|
|
83
55
|
try {
|
|
84
56
|
return (await res.json());
|
|
85
57
|
}
|
|
86
58
|
catch {
|
|
87
|
-
throw new RegistryError(url, "the registry's answer
|
|
59
|
+
throw new RegistryError(url, "the registry's answer isn't JSON");
|
|
88
60
|
}
|
|
89
61
|
}
|
|
90
62
|
/** `{ latest: "0.81.0", next: "0.82.0-rc.1" }`. */
|
|
91
63
|
export async function fetchDistTags(o) {
|
|
92
|
-
const url = registryUrl(o.registry,
|
|
93
|
-
const body = await getJson(url, o);
|
|
64
|
+
const url = registryUrl(o.registry, '-', 'package', o.packageName, 'dist-tags');
|
|
94
65
|
const tags = {};
|
|
95
|
-
for (const [k, v] of Object.entries(
|
|
96
|
-
if (typeof v ===
|
|
66
|
+
for (const [k, v] of Object.entries(await getJson(url, o)))
|
|
67
|
+
if (typeof v === 'string')
|
|
97
68
|
tags[k] = v;
|
|
98
69
|
if (Object.keys(tags).length === 0)
|
|
99
|
-
throw new RegistryError(url,
|
|
70
|
+
throw new RegistryError(url, 'the registry lists no dist-tags');
|
|
100
71
|
return tags;
|
|
101
72
|
}
|
|
102
|
-
/** One version's manifest
|
|
103
|
-
export
|
|
104
|
-
|
|
105
|
-
return getJson(url, o);
|
|
73
|
+
/** One version's manifest, read for `engines`. */
|
|
74
|
+
export function fetchManifest(o) {
|
|
75
|
+
return getJson(registryUrl(o.registry, o.packageName, o.version), o);
|
|
106
76
|
}
|
|
107
77
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* asking: anything that parses as a version is a version, everything else is a
|
|
112
|
-
* tag. That ordering matters because a registry will happily serve a manifest
|
|
113
|
-
* for a tag name as well, and resolving `--to next` as a literal version would
|
|
114
|
-
* silently install whatever `next` pointed at while REPORTING the target as
|
|
115
|
-
* "next".
|
|
78
|
+
* `--to` (or `latest` without it) as one version, with its `engines`. A version and a tag are told apart by shape:
|
|
79
|
+
* anything that looks like a version is one. Asking first would be wrong, since a registry may serve a manifest for a
|
|
80
|
+
* tag's name too, and `--to next` would then install `next` while reporting it as a version called "next".
|
|
116
81
|
*/
|
|
117
82
|
export async function resolveTarget(o) {
|
|
118
|
-
const
|
|
83
|
+
const to = o.to?.trim();
|
|
119
84
|
let version;
|
|
120
85
|
let tag;
|
|
121
|
-
if (to
|
|
122
|
-
|
|
123
|
-
const latest = tags.latest;
|
|
124
|
-
if (latest === undefined) {
|
|
125
|
-
throw new RegistryError(registryUrl(o.registry, "-", "package", o.packageName, "dist-tags"), "the registry has no `latest` dist-tag for this package");
|
|
126
|
-
}
|
|
127
|
-
version = latest;
|
|
128
|
-
tag = "latest";
|
|
129
|
-
}
|
|
130
|
-
else if (/^v?\d+\.\d+\.\d+/.test(to.trim())) {
|
|
131
|
-
version = to.trim().replace(/^v/, "");
|
|
86
|
+
if (to !== undefined && /^v?\d+\.\d+\.\d+/.test(to)) {
|
|
87
|
+
version = to.replace(/^v/, '');
|
|
132
88
|
tag = null;
|
|
133
89
|
}
|
|
134
90
|
else {
|
|
91
|
+
tag = to ?? 'latest';
|
|
135
92
|
const tags = await fetchDistTags(o);
|
|
136
|
-
const resolved = tags[
|
|
93
|
+
const resolved = tags[tag];
|
|
137
94
|
if (resolved === undefined) {
|
|
138
|
-
|
|
95
|
+
const url = registryUrl(o.registry, '-', 'package', o.packageName, 'dist-tags');
|
|
96
|
+
throw new RegistryError(url, `no dist-tag \`${tag}\` (the registry has: ${Object.keys(tags).sort().join(', ')})`);
|
|
139
97
|
}
|
|
140
98
|
version = resolved;
|
|
141
|
-
tag = to;
|
|
142
99
|
}
|
|
143
100
|
const manifest = await fetchManifest({ ...o, version });
|
|
144
101
|
return { version, tag, engines: manifest.engines?.node ?? null };
|
|
@@ -1,67 +1,44 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The small semver `update` needs, and no more (CLI contract SPEC §5 step 4).
|
|
3
|
-
*
|
|
4
|
-
* Three questions are asked of versions in this contract: is the target newer
|
|
5
|
-
* than what we have, is it a prerelease, and does the target's `engines.node`
|
|
6
|
-
* accept the Node running the update. That is it — so this is ~120 lines of
|
|
7
|
-
* Node built-ins rather than a dependency, which is what SPEC §5 asks for and
|
|
8
|
-
* what keeps `update` runnable from a CLI that must not load the server.
|
|
9
|
-
*
|
|
10
|
-
* **What it deliberately does not do.** No `semver` package behaviours beyond
|
|
11
|
-
* the above: no ranges with hyphens (`1.2 - 2.3`), no `x`-ranges (`1.x`), no
|
|
12
|
-
* build metadata ordering. An `engines.node` we cannot parse is reported as
|
|
13
|
-
* "cannot tell" rather than as "fails", because refusing an update on the
|
|
14
|
-
* strength of a range this file does not understand would be the worse error of
|
|
15
|
-
* the two — see {@link satisfiesEngines}.
|
|
16
|
-
*
|
|
17
|
-
* Generic: wave C4 lifts this into `reference/` with the rest of `update`.
|
|
18
|
-
*/
|
|
19
1
|
export interface Version {
|
|
20
2
|
major: number;
|
|
21
3
|
minor: number;
|
|
22
4
|
patch: number;
|
|
23
|
-
/** The dot-separated identifiers after
|
|
5
|
+
/** The dot-separated identifiers after `-`; empty for a release. */
|
|
24
6
|
prerelease: (string | number)[];
|
|
25
7
|
}
|
|
26
|
-
/** `1.2.3-rc.1`
|
|
8
|
+
/** `1.2.3-rc.1` as a `Version`, or undefined if it isn't one. */
|
|
27
9
|
export declare function parseVersion(raw: string): Version | undefined;
|
|
28
|
-
/**
|
|
10
|
+
/** SPEC §5: prereleases count only when `--to` names them. */
|
|
29
11
|
export declare function isPrerelease(raw: string): boolean;
|
|
30
12
|
/**
|
|
31
|
-
* -1, 0 or 1, by
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* longer run of identifiers wins when every shared one is equal.
|
|
35
|
-
*
|
|
36
|
-
* Build metadata is ignored, as semver says it must be.
|
|
13
|
+
* -1, 0 or 1, by semver's rules: `1.0.0-rc.1` is lower than `1.0.0`, numeric identifiers compare as numbers and sort
|
|
14
|
+
* below alphanumeric ones, and a longer run of identifiers wins when the shared ones are equal. Build metadata is
|
|
15
|
+
* ignored. Something that isn't a version compares as equal rather than throwing.
|
|
37
16
|
*/
|
|
38
17
|
export declare function compareVersions(a: string, b: string): number;
|
|
39
|
-
/**
|
|
18
|
+
/** Whether `a` is strictly newer than `b`. */
|
|
40
19
|
export declare const isNewer: (a: string, b: string) => boolean;
|
|
41
|
-
/** The highest of a list, ignoring anything
|
|
20
|
+
/** The highest of a list, ignoring anything that isn't a version. */
|
|
42
21
|
export declare function maxVersion(versions: readonly string[]): string | undefined;
|
|
22
|
+
/** `0.82.0` → `0.83.0` (`minor`), or `0.82.1` (`patch`). A prerelease's suffix is dropped. */
|
|
23
|
+
export declare function bumpVersion(raw: string, part: 'major' | 'minor' | 'patch'): string;
|
|
43
24
|
/**
|
|
44
|
-
*
|
|
25
|
+
* Whether `version` satisfies `range`; undefined when this file can't tell.
|
|
45
26
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
27
|
+
* Reads what `engines.node` uses in practice: `>=22`, `>=22.0.0`, `^22.1.0`, `~22.1`, `22`, `22.x`, `>=20 <23`, and
|
|
28
|
+
* `||` between them. `*` and an empty range accept everything. Alternatives it can't read are ignored; if it can read
|
|
29
|
+
* none of them, the answer is undefined.
|
|
49
30
|
*/
|
|
50
31
|
export declare function satisfies(version: string, range: string): boolean | undefined;
|
|
51
32
|
export interface EnginesVerdict {
|
|
52
|
-
/**
|
|
33
|
+
/** true passes, false fails, undefined when the range couldn't be read. */
|
|
53
34
|
ok: boolean | undefined;
|
|
54
35
|
/** The range as published, for the message. */
|
|
55
36
|
range: string | undefined;
|
|
56
37
|
}
|
|
57
38
|
/**
|
|
58
|
-
* Will the target
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* one whose range this file cannot parse, must NOT block an update: the cost of
|
|
62
|
-
* a false refusal is a tool that cannot update itself and says something the
|
|
63
|
-
* user cannot act on, while the cost of letting an incompatible Node through is
|
|
64
|
-
* the failure `engines` would have produced anyway, with a rollback behind it.
|
|
39
|
+
* Will the target run on this Node? (SPEC §5 step 4.) No `engines.node`, or one this file can't read, doesn't block
|
|
40
|
+
* an update: callers treat `ok: undefined` as a pass. A false refusal leaves a tool that can't update itself, saying
|
|
41
|
+
* something nobody can act on; letting an unsuitable Node through fails the install, and the rollback runs.
|
|
65
42
|
*/
|
|
66
43
|
export declare function satisfiesEngines(nodeVersion: string, engines: {
|
|
67
44
|
node?: string;
|