@1e0zj/dsh-plugin-mall 0.4.2 → 0.4.3
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/src/client.js +8 -5
- package/src/github.js +44 -3
- package/src/index.js +804 -140
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -499,10 +499,10 @@ window.__ModuleLoader__.load({
|
|
|
499
499
|
busy: props.approving === job.spec,
|
|
500
500
|
onApprove: function (names) {
|
|
501
501
|
// 不先 drop:旧条目由重试任务的 track(carryFromId) 原子接管
|
|
502
|
-
// (撤条目 +
|
|
503
|
-
//
|
|
504
|
-
//
|
|
505
|
-
//
|
|
502
|
+
// (撤条目 + 日志接续一拍完成)。install RPC 现在只做本地校验、
|
|
503
|
+
// 立刻返回新 job id,但保留这个次序仍然是它最稳的形态——
|
|
504
|
+
// 万一 RPC 失败,旧条目和日志还在。等待期间按钮由 approving
|
|
505
|
+
// 态显示「继续中…」。
|
|
506
506
|
props.onApprove(job.spec, names, job.approvalToken, id);
|
|
507
507
|
},
|
|
508
508
|
onDismiss: function () { props.onDismiss(id); },
|
|
@@ -1056,7 +1056,10 @@ window.__ModuleLoader__.load({
|
|
|
1056
1056
|
var spec = preflight.spec;
|
|
1057
1057
|
var carry = preflight.jobId;
|
|
1058
1058
|
setPreflight(null);
|
|
1059
|
-
|
|
1059
|
+
// consentDigest 来自预检 job 的 extras,装的时候与当前报告比对:
|
|
1060
|
+
// 用户点「继续」到安装真正开跑之间候选包或 profile 变了,
|
|
1061
|
+
// 布尔同意不得沿用,要重新看新的警告。
|
|
1062
|
+
doRawInstall(spec, { acceptWarnings: true, acceptedReportDigest: preflight.report.consentDigest }, carry);
|
|
1060
1063
|
},
|
|
1061
1064
|
onClose: function () {
|
|
1062
1065
|
if (preflight && preflight.spec) delete approvalTokensRef.current[preflight.spec];
|
package/src/github.js
CHANGED
|
@@ -173,16 +173,19 @@ function normalizeRegistry(registry) {
|
|
|
173
173
|
* @param name - the npm package name.
|
|
174
174
|
* @param options - `registry` defaults to npmjs; pass what pnpm installs from.
|
|
175
175
|
* `signal` cancels the request (and, critically, keeps the cancellation out
|
|
176
|
-
* of the cache — see below).
|
|
176
|
+
* of the cache — see below). `fresh` skips the read side of the cache: a
|
|
177
|
+
* cached "current version" is stale by construction, and the preflight
|
|
178
|
+
* staleness check exists precisely to compare against what the registry
|
|
179
|
+
* says NOW (the write side still populates the cache for other callers).
|
|
177
180
|
* @returns `{latest, repositoryUrl, hostDeps}`, or null when unknown/unreachable.
|
|
178
181
|
*/
|
|
179
|
-
export async function npmPackageInfo(name, { registry, signal } = {}) {
|
|
182
|
+
export async function npmPackageInfo(name, { registry, signal, fresh = false } = {}) {
|
|
180
183
|
const clean = String(name ?? "").trim();
|
|
181
184
|
if (clean.length === 0 || !/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i.test(clean)) return null;
|
|
182
185
|
const base = normalizeRegistry(registry);
|
|
183
186
|
const key = `${base}|${clean}`;
|
|
184
187
|
const cached = npmCache.get(key);
|
|
185
|
-
if (cached !== undefined && Date.now() - cached.at < NPM_CACHE_TTL) return cached.info;
|
|
188
|
+
if (fresh !== true && cached !== undefined && Date.now() - cached.at < NPM_CACHE_TTL) return cached.info;
|
|
186
189
|
let info = null;
|
|
187
190
|
try {
|
|
188
191
|
// 单版本端点返回 latest 的完整 manifest(dependencies + repository 都在)。
|
|
@@ -215,6 +218,44 @@ export async function npmPackageInfo(name, { registry, signal } = {}) {
|
|
|
215
218
|
return info;
|
|
216
219
|
}
|
|
217
220
|
|
|
221
|
+
const npmVersionsCache = new Map();
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* All published version strings of a package, oldest to newest, for resolving
|
|
225
|
+
* a RANGE spec ("pkg@^1.2.0") to the version pnpm would actually pick today.
|
|
226
|
+
* `/latest` cannot answer that — a new release inside the range is invisible
|
|
227
|
+
* to it until it becomes latest. Fetches the full packument (one request),
|
|
228
|
+
* which is why this lives behind its own TTL like npmPackageInfo. Same
|
|
229
|
+
* cancellation rule: AbortError is rethrown, never cached as an empty answer.
|
|
230
|
+
* @returns string[], or null when unreachable/unknown.
|
|
231
|
+
*/
|
|
232
|
+
export async function npmPackageVersions(name, { registry, signal, fresh = false } = {}) {
|
|
233
|
+
const clean = String(name ?? "").trim();
|
|
234
|
+
if (clean.length === 0 || !/^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i.test(clean)) return null;
|
|
235
|
+
const base = normalizeRegistry(registry);
|
|
236
|
+
const key = `${base}|${clean}`;
|
|
237
|
+
const cached = npmVersionsCache.get(key);
|
|
238
|
+
if (fresh !== true && cached !== undefined && Date.now() - cached.at < NPM_CACHE_TTL) return cached.versions;
|
|
239
|
+
let versions = null;
|
|
240
|
+
try {
|
|
241
|
+
const response = await fetch(`${base}/${clean.replace("/", "%2F")}`, {
|
|
242
|
+
headers: { "User-Agent": "dsh-plugin-mall", Accept: "application/json" },
|
|
243
|
+
signal,
|
|
244
|
+
});
|
|
245
|
+
if (response.ok) {
|
|
246
|
+
const body = await response.json();
|
|
247
|
+
if (body?.versions !== null && typeof body?.versions === "object") {
|
|
248
|
+
versions = Object.keys(body.versions);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if (error?.name === "AbortError") throw error;
|
|
253
|
+
versions = null;
|
|
254
|
+
}
|
|
255
|
+
npmVersionsCache.set(key, { versions, at: Date.now() });
|
|
256
|
+
return versions;
|
|
257
|
+
}
|
|
258
|
+
|
|
218
259
|
/**
|
|
219
260
|
* Rewrite "github:owner/repo" (or "owner/repo") to the npm package name when
|
|
220
261
|
* that package exists on npm AND its repository URL points back at the repo
|