mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 17:53:39 +00:00
The ClawHub release planner and prepared-artifact resolver read the new public publication-state endpoint (/api/v1/packages/{name}/versions/{version}/publication). Only absent versions are republished; pending ones are skipped, and failed ones are excluded, with the recover command printed to the step summary. A 404, or a 200 without a state field, falls back to the legacy version probe.
47 lines
1.6 KiB
JavaScript
47 lines
1.6 KiB
JavaScript
export function isClawHubPublishAttemptId(value) {
|
|
return typeof value === "string" && /^[A-Za-z0-9_-]{1,200}$/u.test(value);
|
|
}
|
|
|
|
// A legacy router returns version JSON here. Only a missing state permits fallback;
|
|
// a new server's unknown or malformed state must never authorize another publish.
|
|
export function classifyClawHubPublication(body, { name, version }) {
|
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
throw new Error(`Invalid ClawHub publication state for ${name}@${version}.`);
|
|
}
|
|
if (!Object.hasOwn(body, "state")) {
|
|
return null;
|
|
}
|
|
const { state, stage, attemptId, recoverable, ...identity } = body;
|
|
let fields;
|
|
switch (state) {
|
|
case "published":
|
|
case "absent":
|
|
fields = [];
|
|
break;
|
|
case "pending":
|
|
fields = ["stage", "attemptId"];
|
|
if (
|
|
!["staging", "checks", "finalization"].includes(stage) ||
|
|
(stage === "staging"
|
|
? Object.hasOwn(body, "attemptId")
|
|
: !isClawHubPublishAttemptId(attemptId))
|
|
) {
|
|
fields = null;
|
|
}
|
|
break;
|
|
case "failed":
|
|
fields = typeof recoverable === "boolean" ? ["recoverable", "attemptId"] : null;
|
|
break;
|
|
}
|
|
if (
|
|
!fields ||
|
|
identity.name !== name ||
|
|
identity.version !== version ||
|
|
Object.keys(body).some((key) => !["name", "version", "state", ...fields].includes(key)) ||
|
|
(Object.hasOwn(body, "attemptId") && !isClawHubPublishAttemptId(attemptId))
|
|
) {
|
|
throw new Error(`Invalid ClawHub publication state for ${name}@${version}.`);
|
|
}
|
|
const { name: _name, version: _version, ...publication } = body;
|
|
return publication;
|
|
}
|