paperkite 0.1.3 → 0.2.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.
@@ -0,0 +1,272 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join } from "node:path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { CORE_POLICY, evaluateCompatibility, sdkDeclarations } from "./abi.js";
5
+ import { compareVersions, isStableVersion, satisfiesRange } from "./semver.js";
6
+ import { paperkiteHome } from "../config/paths.js";
7
+ import { coreRoot } from "./loader.js";
8
+ export const defaultFetch = (url, init) => fetch(url, init);
9
+ /** core 随包携带的离线快照;读取失败按空清单处理。 */
10
+ export async function readSnapshot(file = join(coreRoot(), "bundles.json")) {
11
+ try {
12
+ const document = JSON.parse(await readFile(file, "utf8"));
13
+ const parsed = parseManifestDocument(document);
14
+ return { ...parsed, origin: "snapshot", warnings: [] };
15
+ }
16
+ catch (error) {
17
+ return {
18
+ name: "",
19
+ origin: "snapshot",
20
+ dependencies: {},
21
+ warnings: ["built-in bundle snapshot is unreadable: " + detailOf(error)]
22
+ };
23
+ }
24
+ }
25
+ export function parseManifestDocument(document) {
26
+ if (!isRecord(document))
27
+ throw new Error("bundle manifest is not an object");
28
+ const name = typeof document.name === "string" ? document.name : "";
29
+ const version = typeof document.version === "string" ? document.version : undefined;
30
+ const dependencies = parseDependencyRecord(document.dependencies);
31
+ if (!Object.keys(dependencies).length)
32
+ throw new Error("bundle manifest declares no dependencies");
33
+ return { name, version, dependencies };
34
+ }
35
+ export async function readBundleManifest(options) {
36
+ const settings = options.settings;
37
+ const source = settings.manifest.trim();
38
+ const snapshot = await readSnapshot();
39
+ if (!source) {
40
+ return { ...snapshot, warnings: ["no bundle manifest configured; using the built-in snapshot"] };
41
+ }
42
+ const cacheFile = join(cacheDirectory(options), "bundle-manifest.json");
43
+ const cached = await readJson(cacheFile);
44
+ const usable = cached && cached.source === source ? cached : undefined;
45
+ if (options.offline) {
46
+ return usable
47
+ ? { ...usable, origin: "cache", warnings: [] }
48
+ : { ...snapshot, warnings: ["offline: using the built-in snapshot for " + source] };
49
+ }
50
+ if (usable && !options.refresh && fresh(usable.fetchedAt, settings.manifestTtlHours, options.now)) {
51
+ return { ...usable, origin: "cache", warnings: [] };
52
+ }
53
+ try {
54
+ const response = await request(source, settings, usable?.etag, options.fetch ?? defaultFetch);
55
+ if (response.status === 304 && usable) {
56
+ const refreshed = { ...usable, fetchedAt: new Date().toISOString() };
57
+ await writeJson(cacheFile, refreshed);
58
+ return { ...refreshed, origin: "cache", warnings: [] };
59
+ }
60
+ if (!response.ok)
61
+ throw new Error("HTTP " + response.status);
62
+ const parsed = parseManifestDocument(response.document);
63
+ await writeJson(cacheFile, {
64
+ source,
65
+ etag: response.etag,
66
+ fetchedAt: new Date().toISOString(),
67
+ name: parsed.name,
68
+ version: parsed.version,
69
+ dependencies: parsed.dependencies
70
+ });
71
+ return { ...parsed, origin: "online", warnings: [] };
72
+ }
73
+ catch (error) {
74
+ const detail = detailOf(error);
75
+ if (usable) {
76
+ return {
77
+ ...usable,
78
+ origin: "cache",
79
+ warnings: ["bundle manifest refresh failed (" + detail + "); using the cached manifest"]
80
+ };
81
+ }
82
+ return {
83
+ ...snapshot,
84
+ warnings: ["bundle manifest unavailable (" + detail + "); using the built-in snapshot"]
85
+ };
86
+ }
87
+ }
88
+ async function request(source, settings, etag, fetcher) {
89
+ const headers = etag ? { "if-none-match": etag } : {};
90
+ if (isHttpSource(source)) {
91
+ const response = await fetcher(source, { headers: { ...headers, accept: "application/json" } });
92
+ return {
93
+ ok: response.ok,
94
+ status: response.status,
95
+ etag: response.headers.get("etag") ?? undefined,
96
+ document: response.ok ? await response.json() : undefined
97
+ };
98
+ }
99
+ const response = await fetcher(registryUrl(settings.registry, source), {
100
+ headers: { ...headers, accept: "application/vnd.npm.install-v1+json" }
101
+ });
102
+ if (response.status === 304)
103
+ return { ok: false, status: 304, etag };
104
+ if (!response.ok)
105
+ return { ok: false, status: response.status };
106
+ return {
107
+ ok: true,
108
+ status: response.status,
109
+ etag: response.headers.get("etag") ?? undefined,
110
+ document: latestRelease(parsePackument(await response.json()))
111
+ };
112
+ }
113
+ /** 插件版本的 packument;离线时只读缓存。 */
114
+ export async function readPackument(name, options) {
115
+ const cacheFile = join(cacheDirectory(options), "packuments", safeName(name) + ".json");
116
+ const cached = await readJson(cacheFile);
117
+ if (options.offline) {
118
+ if (cached)
119
+ return cached.packument;
120
+ throw new Error("offline: no cached packument for " + name);
121
+ }
122
+ if (cached && !options.refresh && fresh(cached.fetchedAt, options.settings.manifestTtlHours, options.now)) {
123
+ return cached.packument;
124
+ }
125
+ const fetcher = options.fetch ?? defaultFetch;
126
+ const full = (options.release?.minimumReleaseAgeMinutes ?? 0) > 0;
127
+ const response = await fetcher(registryUrl(options.settings.registry, name), {
128
+ headers: { accept: full ? "application/json" : "application/vnd.npm.install-v1+json" }
129
+ });
130
+ if (!response.ok)
131
+ throw new Error("HTTP " + response.status + " for " + name);
132
+ const packument = parsePackument(await response.json());
133
+ await writeJson(cacheFile, { fetchedAt: new Date().toISOString(), packument });
134
+ return packument;
135
+ }
136
+ /** 范围内满足 ABI 的最高稳定版;被 core 拒绝的版本排除。 */
137
+ export function selectPluginVersion(packument, range, options = {}) {
138
+ const policy = options.policy ?? CORE_POLICY;
139
+ const release = options.release;
140
+ const now = (options.now ?? Date.now)();
141
+ const candidates = Object.entries(packument.versions)
142
+ .filter(([version]) => isStableVersion(version) && satisfiesRange(version, range))
143
+ .sort(([left], [right]) => compareVersions(right, left));
144
+ for (const [version, manifest] of candidates) {
145
+ if (release && excludedByAge(version, options.name, packument, release, now))
146
+ continue;
147
+ const verdict = evaluateCompatibility(sdkDeclarations(manifest), policy);
148
+ if (verdict.verdict === "reject")
149
+ continue;
150
+ return { version, verdict };
151
+ }
152
+ return undefined;
153
+ }
154
+ function excludedByAge(version, name, packument, release, now) {
155
+ if (!release.minimumReleaseAgeMinutes)
156
+ return false;
157
+ if (name && release.exclude.includes(name))
158
+ return false;
159
+ const published = packument.time[version];
160
+ if (!published)
161
+ return true;
162
+ const at = Date.parse(published);
163
+ if (!Number.isFinite(at))
164
+ return true;
165
+ return now - at < release.minimumReleaseAgeMinutes * 60_000;
166
+ }
167
+ /** 清单 scope 之外的名字跳过;默认只接受 `@paperkite/`。 */
168
+ export function filterScopes(dependencies, scopes) {
169
+ const accepted = {};
170
+ const skipped = [];
171
+ for (const [name, range] of Object.entries(dependencies)) {
172
+ if (scopes.some((scope) => name.startsWith(scope)))
173
+ accepted[name] = range;
174
+ else
175
+ skipped.push(name);
176
+ }
177
+ return { accepted, skipped };
178
+ }
179
+ /** 与 pnpm 对齐的供应链延迟设置,取自 profile 的 pnpm-workspace.yaml。 */
180
+ export async function readReleasePolicy(directory) {
181
+ try {
182
+ const data = parseYaml(await readFile(join(directory, "pnpm-workspace.yaml"), "utf8"));
183
+ if (!isRecord(data))
184
+ return { minimumReleaseAgeMinutes: 0, exclude: [] };
185
+ const age = Number(data.minimumReleaseAge ?? 0);
186
+ const exclude = Array.isArray(data.minimumReleaseAgeExclude)
187
+ ? data.minimumReleaseAgeExclude.filter((item) => typeof item === "string")
188
+ : [];
189
+ return {
190
+ minimumReleaseAgeMinutes: Number.isFinite(age) && age > 0 ? age : 0,
191
+ exclude
192
+ };
193
+ }
194
+ catch {
195
+ return { minimumReleaseAgeMinutes: 0, exclude: [] };
196
+ }
197
+ }
198
+ export function cacheDirectory(options = {}) {
199
+ return options.cacheDir ?? join(paperkiteHome(), "cache");
200
+ }
201
+ function registryUrl(registry, name) {
202
+ const base = (registry.trim() || "https://registry.npmjs.org").replace(/\/+$/, "");
203
+ return base + "/" + encodeURIComponent(name);
204
+ }
205
+ function isHttpSource(source) {
206
+ return /^https?:\/\//i.test(source);
207
+ }
208
+ function parsePackument(document) {
209
+ if (!isRecord(document))
210
+ throw new Error("packument is not an object");
211
+ const versions = isRecord(document.versions) ? document.versions : {};
212
+ const distTags = isRecord(document["dist-tags"])
213
+ ? Object.fromEntries(Object.entries(document["dist-tags"]).filter((entry) => typeof entry[1] === "string"))
214
+ : {};
215
+ const time = isRecord(document.time)
216
+ ? Object.fromEntries(Object.entries(document.time).filter((entry) => typeof entry[1] === "string"))
217
+ : {};
218
+ return {
219
+ name: typeof document.name === "string" ? document.name : undefined,
220
+ versions,
221
+ distTags,
222
+ time
223
+ };
224
+ }
225
+ function latestRelease(packument) {
226
+ const latest = packument.distTags.latest;
227
+ const entry = latest ? packument.versions[latest] : undefined;
228
+ if (!entry)
229
+ throw new Error("packument declares no latest release");
230
+ const dependencies = parseDependencyRecord(entry.dependencies);
231
+ if (!Object.keys(dependencies).length)
232
+ throw new Error("latest release declares no dependencies");
233
+ return { name: packument.name ?? "", version: entry.version ?? latest, dependencies };
234
+ }
235
+ function parseDependencyRecord(value) {
236
+ if (!isRecord(value))
237
+ return {};
238
+ const dependencies = {};
239
+ for (const [name, range] of Object.entries(value)) {
240
+ if (typeof range === "string" && range.trim())
241
+ dependencies[name] = range.trim();
242
+ }
243
+ return dependencies;
244
+ }
245
+ function fresh(fetchedAt, ttlHours, now = Date.now) {
246
+ const at = Date.parse(fetchedAt);
247
+ if (!Number.isFinite(at))
248
+ return false;
249
+ return now() - at < Math.max(0, ttlHours) * 3_600_000;
250
+ }
251
+ async function readJson(file) {
252
+ try {
253
+ return JSON.parse(await readFile(file, "utf8"));
254
+ }
255
+ catch {
256
+ return undefined;
257
+ }
258
+ }
259
+ async function writeJson(file, value) {
260
+ await mkdir(dirname(file), { recursive: true });
261
+ await writeFile(file, JSON.stringify(value, null, 2) + "\n", "utf8");
262
+ }
263
+ function safeName(name) {
264
+ return name.replace(/[^0-9A-Za-z._-]+/g, "-");
265
+ }
266
+ function isRecord(value) {
267
+ return typeof value === "object" && value !== null && !Array.isArray(value);
268
+ }
269
+ function detailOf(error) {
270
+ return error instanceof Error ? error.message : String(error);
271
+ }
272
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/extensions/manifest.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,14 @@ export interface ProfileManifest {
8
8
  readonly paperkite?: {
9
9
  readonly profile?: {
10
10
  readonly plugins?: readonly string[];
11
+ readonly bundles?: Readonly<Record<string, string>>;
11
12
  };
12
13
  };
13
14
  [key: string]: unknown;
14
15
  }
16
+ /** 由清单管理的插件与范围;sync 只管理这一段。 */
17
+ export declare function bundleRanges(manifest: ProfileManifest): Record<string, string>;
18
+ /** 用户显式安装的插件名,清单接管的同名条目不再计入。 */
19
+ export declare function userPlugins(manifest: ProfileManifest): readonly string[];
15
20
  export declare function readProfile(directory: string): Promise<ProfileManifest>;
16
21
  export declare function writeProfile(directory: string, value: ProfileManifest): Promise<void>;
@@ -9,7 +9,7 @@ export function defaultProfileManifest(profile) {
9
9
  private: true,
10
10
  type: "module",
11
11
  dependencies: {},
12
- paperkite: { profile: { plugins: [] } }
12
+ paperkite: { profile: { plugins: [], bundles: {} } }
13
13
  };
14
14
  }
15
15
  export function profileDirectory(profile = "default") {
@@ -30,6 +30,26 @@ export async function ensureProfile(profile = "default") {
30
30
  }
31
31
  return directory;
32
32
  }
33
+ /** 由清单管理的插件与范围;sync 只管理这一段。 */
34
+ export function bundleRanges(manifest) {
35
+ const bundles = manifest.paperkite?.profile?.bundles;
36
+ if (typeof bundles !== "object" || bundles === null || Array.isArray(bundles))
37
+ return {};
38
+ const ranges = {};
39
+ for (const [name, range] of Object.entries(bundles)) {
40
+ if (typeof range === "string" && range.trim())
41
+ ranges[name] = range.trim();
42
+ }
43
+ return ranges;
44
+ }
45
+ /** 用户显式安装的插件名,清单接管的同名条目不再计入。 */
46
+ export function userPlugins(manifest) {
47
+ const declared = manifest.paperkite?.profile?.plugins;
48
+ if (!Array.isArray(declared))
49
+ return [];
50
+ const managed = new Set(Object.keys(bundleRanges(manifest)));
51
+ return declared.filter((name) => typeof name === "string" && Boolean(name.trim()) && !managed.has(name));
52
+ }
33
53
  export async function readProfile(directory) {
34
54
  try {
35
55
  const data = JSON.parse(await readFile(join(directory, "package.json"), "utf8"));
@@ -1 +1 @@
1
- {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../../src/extensions/profile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../../src/extensions/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface Version {
2
+ readonly major: number;
3
+ readonly minor: number;
4
+ readonly patch: number;
5
+ readonly prerelease: readonly (number | string)[];
6
+ }
7
+ export type Operator = ">" | ">=" | "<" | "<=" | "=";
8
+ export interface Comparator {
9
+ readonly op: Operator;
10
+ readonly version: Version;
11
+ }
12
+ export type ComparatorSet = readonly Comparator[];
13
+ export type Range = readonly ComparatorSet[];
14
+ export declare function parseVersion(text: string): Version | undefined;
15
+ export declare function parseRange(text: string): Range | undefined;
16
+ export declare function satisfies(range: Range, current: Version): boolean;
17
+ export declare function compare(left: Version, right: Version): number;
18
+ /** 范围为插件接受的 ABI 代际上限;无上限时取所需的最低代际。 */
19
+ export declare function rangeAbi(range: Range): number;
20
+ /** 版本是否落在范围内;任一侧无法解析都视为不满足。 */
21
+ export declare function satisfiesRange(version: string, range: string): boolean;
22
+ export declare function compareVersions(left: string, right: string): number;
23
+ /** 预发布版本不参与选择。 */
24
+ export declare function isStableVersion(version: string): boolean;
25
+ export declare function maxSatisfying(versions: readonly string[], range: string): string | undefined;
@@ -0,0 +1,260 @@
1
+ const VERSION_PATTERN = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/;
2
+ const PARTIAL_PATTERN = /^v?(\d+|[xX*])(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z.-]+))?$/;
3
+ const COMPARATOR_PATTERN = /^(>=|<=|>|<|=|\^|~>|~)?(.+)$/;
4
+ export function parseVersion(text) {
5
+ const match = VERSION_PATTERN.exec(text);
6
+ if (!match?.[1] || !match[2] || !match[3])
7
+ return undefined;
8
+ return version(Number(match[1]), Number(match[2]), Number(match[3]), identifiers(match[4]));
9
+ }
10
+ function version(major, minor, patch, prerelease = []) {
11
+ return { major, minor, patch, prerelease };
12
+ }
13
+ function identifiers(text) {
14
+ if (!text)
15
+ return [];
16
+ return text.split(".").map((part) => (/^\d+$/.test(part) ? Number(part) : part));
17
+ }
18
+ function component(token) {
19
+ if (token === undefined)
20
+ return undefined;
21
+ if (token === "*" || token === "x" || token === "X")
22
+ return "*";
23
+ return /^\d+$/.test(token) ? Number(token) : undefined;
24
+ }
25
+ function parsePartial(text) {
26
+ const match = PARTIAL_PATTERN.exec(text);
27
+ if (!match)
28
+ return undefined;
29
+ const major = component(match[1]);
30
+ const minor = component(match[2]);
31
+ const patch = component(match[3]);
32
+ if (typeof major !== "number")
33
+ return undefined;
34
+ if (minor === undefined && match[2] !== undefined)
35
+ return undefined;
36
+ if (patch === undefined && match[3] !== undefined)
37
+ return undefined;
38
+ if (minor === "*" && typeof patch === "number")
39
+ return undefined;
40
+ const prerelease = identifiers(match[4]);
41
+ if (prerelease.length && typeof patch !== "number")
42
+ return undefined;
43
+ return {
44
+ major,
45
+ minor: minor === "*" ? undefined : minor,
46
+ patch: patch === "*" ? undefined : patch,
47
+ prerelease
48
+ };
49
+ }
50
+ function expand(op, partial) {
51
+ const { major, minor, patch, prerelease } = partial;
52
+ const atLeast = () => ({
53
+ op: ">=",
54
+ version: version(major, minor ?? 0, patch ?? 0, prerelease)
55
+ });
56
+ const below = (value, middle = 0, last = 0) => ({
57
+ op: "<",
58
+ version: version(value, middle, last)
59
+ });
60
+ const at = (value, middle = 0, last = 0) => ({
61
+ op: ">=",
62
+ version: version(value, middle, last)
63
+ });
64
+ const exact = (operator) => [
65
+ { op: operator, version: version(major, minor ?? 0, patch ?? 0, prerelease) }
66
+ ];
67
+ switch (op) {
68
+ case ">":
69
+ if (patch !== undefined)
70
+ return exact(">");
71
+ if (minor !== undefined)
72
+ return [at(major, minor + 1)];
73
+ return [at(major + 1)];
74
+ case ">=":
75
+ return [atLeast()];
76
+ case "<":
77
+ if (patch !== undefined)
78
+ return exact("<");
79
+ return [below(major, minor ?? 0)];
80
+ case "<=":
81
+ if (patch !== undefined)
82
+ return exact("<=");
83
+ if (minor !== undefined)
84
+ return [below(major, minor + 1)];
85
+ return [below(major + 1)];
86
+ case "^":
87
+ if (major > 0)
88
+ return [atLeast(), below(major + 1)];
89
+ if (minor === undefined)
90
+ return [atLeast(), below(1)];
91
+ if (minor > 0)
92
+ return [atLeast(), below(0, minor + 1)];
93
+ if (patch !== undefined)
94
+ return [atLeast(), below(0, 0, patch + 1)];
95
+ return [atLeast(), below(0, 1)];
96
+ case "~":
97
+ case "~>":
98
+ if (minor === undefined)
99
+ return [atLeast(), below(major + 1)];
100
+ return [atLeast(), below(major, minor + 1)];
101
+ case "=":
102
+ case undefined:
103
+ if (patch !== undefined)
104
+ return exact("=");
105
+ if (minor !== undefined)
106
+ return [atLeast(), below(major, minor + 1)];
107
+ return [atLeast(), below(major + 1)];
108
+ default:
109
+ return undefined;
110
+ }
111
+ }
112
+ export function parseRange(text) {
113
+ const trimmed = text.trim();
114
+ if (!trimmed)
115
+ return undefined;
116
+ const sets = [];
117
+ for (const clause of trimmed.split("||")) {
118
+ const hyphen = /^(.+?)\s+-\s+(.+)$/.exec(clause.trim());
119
+ if (hyphen?.[1] && hyphen[2]) {
120
+ const from = parsePartial(hyphen[1]);
121
+ const to = parsePartial(hyphen[2]);
122
+ if (!from || !to)
123
+ return undefined;
124
+ const lower = expand(">=", from);
125
+ const upper = expand("<=", to);
126
+ if (!lower || !upper)
127
+ return undefined;
128
+ sets.push([...lower, ...upper]);
129
+ continue;
130
+ }
131
+ const comparators = [];
132
+ const normalized = clause.trim().replace(/(>=|<=|>|<|=|\^|~>|~)\s+/g, "$1");
133
+ for (const token of normalized.split(/\s+/)) {
134
+ if (!token)
135
+ continue;
136
+ const match = COMPARATOR_PATTERN.exec(token);
137
+ if (!match?.[2])
138
+ return undefined;
139
+ const partial = parsePartial(match[2]);
140
+ if (!partial)
141
+ return undefined;
142
+ const expanded = expand(match[1], partial);
143
+ if (!expanded)
144
+ return undefined;
145
+ comparators.push(...expanded);
146
+ }
147
+ if (!comparators.length)
148
+ return undefined;
149
+ sets.push(comparators);
150
+ }
151
+ return sets.length ? sets : undefined;
152
+ }
153
+ export function satisfies(range, current) {
154
+ return range.some((set) => set.every((comparator) => holds(comparator, current)));
155
+ }
156
+ function holds(comparator, current) {
157
+ const order = compare(current, comparator.version);
158
+ switch (comparator.op) {
159
+ case "=":
160
+ return order === 0;
161
+ case ">":
162
+ return order > 0;
163
+ case ">=":
164
+ return order >= 0;
165
+ case "<":
166
+ return order < 0;
167
+ case "<=":
168
+ return order <= 0;
169
+ }
170
+ }
171
+ export function compare(left, right) {
172
+ if (left.major !== right.major)
173
+ return left.major < right.major ? -1 : 1;
174
+ if (left.minor !== right.minor)
175
+ return left.minor < right.minor ? -1 : 1;
176
+ if (left.patch !== right.patch)
177
+ return left.patch < right.patch ? -1 : 1;
178
+ return comparePrerelease(left.prerelease, right.prerelease);
179
+ }
180
+ function comparePrerelease(left, right) {
181
+ if (!left.length || !right.length)
182
+ return left.length === right.length ? 0 : left.length ? -1 : 1;
183
+ const length = Math.max(left.length, right.length);
184
+ for (let index = 0; index < length; index += 1) {
185
+ const a = left[index];
186
+ const b = right[index];
187
+ if (a === undefined)
188
+ return -1;
189
+ if (b === undefined)
190
+ return 1;
191
+ if (a === b)
192
+ continue;
193
+ if (typeof a === "number" && typeof b === "number")
194
+ return a < b ? -1 : 1;
195
+ if (typeof a === "number")
196
+ return -1;
197
+ if (typeof b === "number")
198
+ return 1;
199
+ return a < b ? -1 : 1;
200
+ }
201
+ return 0;
202
+ }
203
+ /** 范围为插件接受的 ABI 代际上限;无上限时取所需的最低代际。 */
204
+ export function rangeAbi(range) {
205
+ let abi = 0;
206
+ for (const set of range) {
207
+ let lowest = 0;
208
+ let highest;
209
+ for (const comparator of set) {
210
+ if (comparator.op === "<") {
211
+ highest = Math.min(highest ?? Number.POSITIVE_INFINITY, majorBelow(comparator.version));
212
+ }
213
+ else if (comparator.op === "<=") {
214
+ highest = Math.min(highest ?? Number.POSITIVE_INFINITY, comparator.version.major);
215
+ }
216
+ else {
217
+ lowest = Math.max(lowest, comparator.version.major);
218
+ }
219
+ }
220
+ abi = Math.max(abi, highest ?? lowest);
221
+ }
222
+ return abi;
223
+ }
224
+ function majorBelow(version) {
225
+ return version.minor === 0 && version.patch === 0 ? Math.max(0, version.major - 1) : version.major;
226
+ }
227
+ /** 版本是否落在范围内;任一侧无法解析都视为不满足。 */
228
+ export function satisfiesRange(version, range) {
229
+ const current = parseVersion(version);
230
+ const parsed = parseRange(range);
231
+ if (!current || !parsed)
232
+ return false;
233
+ return satisfies(parsed, current);
234
+ }
235
+ export function compareVersions(left, right) {
236
+ const a = parseVersion(left);
237
+ const b = parseVersion(right);
238
+ if (!a || !b)
239
+ return 0;
240
+ return compare(a, b);
241
+ }
242
+ /** 预发布版本不参与选择。 */
243
+ export function isStableVersion(version) {
244
+ const parsed = parseVersion(version);
245
+ return parsed !== undefined && parsed.prerelease.length === 0;
246
+ }
247
+ export function maxSatisfying(versions, range) {
248
+ const parsed = parseRange(range);
249
+ if (!parsed)
250
+ return undefined;
251
+ const candidates = [];
252
+ for (const text of versions) {
253
+ const current = parseVersion(text);
254
+ if (current && !current.prerelease.length && satisfies(parsed, current))
255
+ candidates.push({ text, version: current });
256
+ }
257
+ candidates.sort((left, right) => compare(right.version, left.version));
258
+ return candidates[0]?.text;
259
+ }
260
+ //# sourceMappingURL=semver.js.map