diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7a2a0a4..543ea6e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,6 +20,7 @@ jobs:
go-version: "1.26.5"
cache: false
- run: npm ci
+ - run: npm run release:check
- name: Build pinned HF Broker
run: |
brokerkit_version="$(node -p 'require("./package.json").config.brokerkitVersion')"
@@ -30,8 +31,6 @@ jobs:
test "$(git -C "$RUNNER_TEMP/brokerkit" rev-parse "refs/tags/$brokerkit_version^{commit}")" = \
"$(git -C "$RUNNER_TEMP/brokerkit" rev-parse HEAD)"
go build -C "$RUNNER_TEMP/brokerkit" -o "$RUNNER_TEMP/hf-broker" ./brokers/huggingface/cmd/hf-broker
- "$RUNNER_TEMP/hf-broker" credential requirements > "$RUNNER_TEMP/hf-broker-credential-requirements.json"
- cmp src/mlclaw/hf-broker-credential-requirements.json "$RUNNER_TEMP/hf-broker-credential-requirements.json"
- name: Test pinned BrokerKit agent tools
env:
MLCLAW_HF_BROKER_BINARY: ${{ runner.temp }}/hf-broker
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 93c277b..abc5dd3 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -70,6 +70,7 @@ jobs:
echo "runtime_image=${runtime_image}" >> "$GITHUB_OUTPUT"
echo "runtime_tag=${version}-openclaw-${openclaw_version}" >> "$GITHUB_OUTPUT"
- run: npm ci
+ - run: npm run release:check
- name: Build pinned HF Broker
run: |
git init "$RUNNER_TEMP/brokerkit"
@@ -80,8 +81,6 @@ jobs:
"refs/tags/${{ steps.runtime-config.outputs.brokerkit_version }}^{commit}")" = \
"$(git -C "$RUNNER_TEMP/brokerkit" rev-parse HEAD)"
go build -C "$RUNNER_TEMP/brokerkit" -o "$RUNNER_TEMP/hf-broker" ./brokers/huggingface/cmd/hf-broker
- "$RUNNER_TEMP/hf-broker" credential requirements > "$RUNNER_TEMP/hf-broker-credential-requirements.json"
- cmp src/mlclaw/hf-broker-credential-requirements.json "$RUNNER_TEMP/hf-broker-credential-requirements.json"
- name: Test pinned BrokerKit agent tools
env:
MLCLAW_HF_BROKER_BINARY: ${{ runner.temp }}/hf-broker
diff --git a/AGENTS.md b/AGENTS.md
index 3423469..2b67a53 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -12,6 +12,24 @@ Do not run mutation testing during ordinary implementation work. Keep its
configuration and CI declaration current so a dedicated mutation run can be
performed separately.
+Do not report work as complete until the original user-visible workflow has
+been reproduced and verified end to end in its real target environment. Tests,
+mocks, CI, health checks, successful builds, and deployments are supporting
+evidence, not substitutes. If full verification is impossible, state that
+clearly and report the work as unverified.
+
+## Release Versions
+
+- Treat `package.json` as the only hand-edited source for the MLClaw package,
+ OpenClaw, BrokerKit package, BrokerKit binary, and runtime image versions.
+- Keep the `openclaw-brokerkit` dependency exactly equal to
+ `config.brokerkitPluginVersion`.
+- Do not hand-edit Dockerfile release defaults or
+ `src/mlclaw/release-config.generated.ts`. After editing release metadata, run
+ `npm install --package-lock-only` if dependency metadata changed, then run
+ `npm run release:sync`.
+- Run `npm run release:check` before committing. CI rejects version drift.
+
## Runtime Boundary
- Treat the OpenClaw process and agent account as untrusted.
diff --git a/Dockerfile b/Dockerfile
index 7a3842a..3bd500a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,8 @@
ARG OPENCLAW_VERSION=2026.7.1
ARG OPENCLAW_BASE_IMAGE=ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}
-ARG BROKERKIT_PLUGIN_VERSION=0.3.3
-ARG BROKERKIT_VERSION=hf-broker/v0.4.0
-ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/huggingface/mlclaw:0.4.7-openclaw-2026.7.1
+ARG BROKERKIT_PLUGIN_VERSION=0.3.4
+ARG BROKERKIT_VERSION=hf-broker/v0.4.2
+ARG MLCLAW_RUNTIME_IMAGE=ghcr.io/huggingface/mlclaw:0.4.8-openclaw-2026.7.1
FROM golang:1.26.5-bookworm AS hf-broker-build
ARG BROKERKIT_VERSION
diff --git a/README.md b/README.md
index dd65cec..4809f53 100644
--- a/README.md
+++ b/README.md
@@ -54,21 +54,24 @@ app; the bootstrapper runs locally.
The `hf` CLI login is a provisioning credential: ML Claw uses it to create and
configure resources owned by your account. HF Broker uses a separate, durable
-fine-grained credential whose required permissions are versioned by BrokerKit.
-Interactive bootstrap opens Hugging Face's token form with those fields
-preselected, then accepts the new token through a hidden local prompt. Creating
-or replacing this credential never changes the active `hf` CLI login. For
-automation, pass a `0600` file through `--broker-hf-token-file`; ML Claw does
-not accept the token as a command-line value.
+fine-grained credential whose selected permissions form BrokerKit's hard
+upstream authority ceiling. Interactive bootstrap opens an empty Hugging Face
+token form so you can choose those permissions and resources, then accepts the
+new token through a hidden local prompt. Creating or replacing this credential
+never changes the active `hf` CLI login. For automation, pass a `0600` file
+through `--broker-hf-token-file`; ML Claw does not accept the token as a
+command-line value.
The broker owns the selected credential; OpenClaw receives only a separate
agent credential that can call the broker's typed, policy-checked routes. It
cannot read the token or use the admin-only operator API. Rerunning bootstrap
reuses a healthy saved broker credential without reopening the form. A missing,
-invalid, wrong-account, or under-scoped credential must be repaired before ML
-Claw continues; it never silently substitutes the active CLI login. Existing
-dedicated inference tokens remain supported through `MLCLAW_ROUTER_TOKEN`,
-`HF_ROUTER_TOKEN`, or `--router-token-file` during migration.
+invalid, or wrong-account credential must be repaired before ML Claw continues;
+it never silently substitutes the active CLI login. When a selected permission
+does not cover an operation, HF Broker denies that operation without weakening
+the rest of the deployment. Existing dedicated inference tokens remain
+supported through `MLCLAW_ROUTER_TOKEN`, `HF_ROUTER_TOKEN`, or
+`--router-token-file`.
## Default Flow
diff --git a/dist/mlclaw-space-runtime.js b/dist/mlclaw-space-runtime.js
index ecd408b..db4cf74 100755
--- a/dist/mlclaw-space-runtime.js
+++ b/dist/mlclaw-space-runtime.js
@@ -1,10 +1,309 @@
#!/usr/bin/env node
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
+var __create = Object.create;
var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __commonJS = (cb, mod) => function __require() {
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
+};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
+ // If the importer is in node compatibility mode or this is not an ESM
+ // file that has been converted to a CommonJS file using a Babel-
+ // compatible transform (i.e. "__esModule" has not been set), then set
+ // "default" to the CommonJS "module.exports" for node compatibility.
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
+ mod
+));
+
+// node_modules/ajv-formats/dist/formats.js
+var require_formats = __commonJS({
+ "node_modules/ajv-formats/dist/formats.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.formatNames = exports.fastFormats = exports.fullFormats = void 0;
+ function fmtDef(validate, compare) {
+ return { validate, compare };
+ }
+ exports.fullFormats = {
+ // date: http://tools.ietf.org/html/rfc3339#section-5.6
+ date: fmtDef(date, compareDate),
+ // date-time: http://tools.ietf.org/html/rfc3339#section-5.6
+ time: fmtDef(getTime(true), compareTime),
+ "date-time": fmtDef(getDateTime(true), compareDateTime),
+ "iso-time": fmtDef(getTime(), compareIsoTime),
+ "iso-date-time": fmtDef(getDateTime(), compareIsoDateTime),
+ // duration: https://tools.ietf.org/html/rfc3339#appendix-A
+ duration: /^P(?!$)((\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?|(\d+W)?)$/,
+ uri,
+ "uri-reference": /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,
+ // uri-template: https://tools.ietf.org/html/rfc6570
+ "uri-template": /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,
+ // For the source: https://gist.github.com/dperini/729294
+ // For test cases: https://mathiasbynens.be/demo/url-regex
+ url: /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,
+ email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,
+ hostname: /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,
+ // optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
+ ipv4: /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/,
+ ipv6: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,
+ regex,
+ // uuid: http://tools.ietf.org/html/rfc4122
+ uuid: /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,
+ // JSON-pointer: https://tools.ietf.org/html/rfc6901
+ // uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
+ "json-pointer": /^(?:\/(?:[^~/]|~0|~1)*)*$/,
+ "json-pointer-uri-fragment": /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
+ // relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00
+ "relative-json-pointer": /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
+ // the following formats are used by the openapi specification: https://spec.openapis.org/oas/v3.0.0#data-types
+ // byte: https://github.com/miguelmota/is-base64
+ byte,
+ // signed 32 bit integer
+ int32: { type: "number", validate: validateInt32 },
+ // signed 64 bit integer
+ int64: { type: "number", validate: validateInt64 },
+ // C-type float
+ float: { type: "number", validate: validateNumber },
+ // C-type double
+ double: { type: "number", validate: validateNumber },
+ // hint to the UI to hide input strings
+ password: true,
+ // unchecked string payload
+ binary: true
+ };
+ exports.fastFormats = {
+ ...exports.fullFormats,
+ date: fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\d$/, compareDate),
+ time: fmtDef(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, compareTime),
+ "date-time": fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\dt(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)$/i, compareDateTime),
+ "iso-time": fmtDef(/^(?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, compareIsoTime),
+ "iso-date-time": fmtDef(/^\d\d\d\d-[0-1]\d-[0-3]\d[t\s](?:[0-2]\d:[0-5]\d:[0-5]\d|23:59:60)(?:\.\d+)?(?:z|[+-]\d\d(?::?\d\d)?)?$/i, compareIsoDateTime),
+ // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
+ uri: /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/)?[^\s]*$/i,
+ "uri-reference": /^(?:(?:[a-z][a-z0-9+\-.]*:)?\/?\/)?(?:[^\\\s#][^\s#]*)?(?:#[^\\\s]*)?$/i,
+ // email (sources from jsen validator):
+ // http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address#answer-8829363
+ // http://www.w3.org/TR/html5/forms.html#valid-e-mail-address (search for 'wilful violation')
+ email: /^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i
+ };
+ exports.formatNames = Object.keys(exports.fullFormats);
+ function isLeapYear(year) {
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
+ }
+ var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
+ var DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+ function date(str) {
+ const matches = DATE.exec(str);
+ if (!matches)
+ return false;
+ const year = +matches[1];
+ const month = +matches[2];
+ const day = +matches[3];
+ return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]);
+ }
+ function compareDate(d1, d2) {
+ if (!(d1 && d2))
+ return void 0;
+ if (d1 > d2)
+ return 1;
+ if (d1 < d2)
+ return -1;
+ return 0;
+ }
+ var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
+ function getTime(strictTimeZone) {
+ return function time(str) {
+ const matches = TIME.exec(str);
+ if (!matches)
+ return false;
+ const hr = +matches[1];
+ const min = +matches[2];
+ const sec = +matches[3];
+ const tz = matches[4];
+ const tzSign = matches[5] === "-" ? -1 : 1;
+ const tzH = +(matches[6] || 0);
+ const tzM = +(matches[7] || 0);
+ if (tzH > 23 || tzM > 59 || strictTimeZone && !tz)
+ return false;
+ if (hr <= 23 && min <= 59 && sec < 60)
+ return true;
+ const utcMin = min - tzM * tzSign;
+ const utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0);
+ return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61;
+ };
+ }
+ function compareTime(s1, s2) {
+ if (!(s1 && s2))
+ return void 0;
+ const t1 = (/* @__PURE__ */ new Date("2020-01-01T" + s1)).valueOf();
+ const t2 = (/* @__PURE__ */ new Date("2020-01-01T" + s2)).valueOf();
+ if (!(t1 && t2))
+ return void 0;
+ return t1 - t2;
+ }
+ function compareIsoTime(t1, t2) {
+ if (!(t1 && t2))
+ return void 0;
+ const a1 = TIME.exec(t1);
+ const a2 = TIME.exec(t2);
+ if (!(a1 && a2))
+ return void 0;
+ t1 = a1[1] + a1[2] + a1[3];
+ t2 = a2[1] + a2[2] + a2[3];
+ if (t1 > t2)
+ return 1;
+ if (t1 < t2)
+ return -1;
+ return 0;
+ }
+ var DATE_TIME_SEPARATOR = /t|\s/i;
+ function getDateTime(strictTimeZone) {
+ const time = getTime(strictTimeZone);
+ return function date_time(str) {
+ const dateTime = str.split(DATE_TIME_SEPARATOR);
+ return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1]);
+ };
+ }
+ function compareDateTime(dt1, dt2) {
+ if (!(dt1 && dt2))
+ return void 0;
+ const d1 = new Date(dt1).valueOf();
+ const d2 = new Date(dt2).valueOf();
+ if (!(d1 && d2))
+ return void 0;
+ return d1 - d2;
+ }
+ function compareIsoDateTime(dt1, dt2) {
+ if (!(dt1 && dt2))
+ return void 0;
+ const [d1, t1] = dt1.split(DATE_TIME_SEPARATOR);
+ const [d2, t2] = dt2.split(DATE_TIME_SEPARATOR);
+ const res = compareDate(d1, d2);
+ if (res === void 0)
+ return void 0;
+ return res || compareTime(t1, t2);
+ }
+ var NOT_URI_FRAGMENT = /\/|:/;
+ var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
+ function uri(str) {
+ return NOT_URI_FRAGMENT.test(str) && URI.test(str);
+ }
+ var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
+ function byte(str) {
+ BYTE.lastIndex = 0;
+ return BYTE.test(str);
+ }
+ var MIN_INT32 = -(2 ** 31);
+ var MAX_INT32 = 2 ** 31 - 1;
+ function validateInt32(value) {
+ return Number.isInteger(value) && value <= MAX_INT32 && value >= MIN_INT32;
+ }
+ function validateInt64(value) {
+ return Number.isInteger(value);
+ }
+ function validateNumber() {
+ return true;
+ }
+ var Z_ANCHOR = /[^\\]\\Z/;
+ function regex(str) {
+ if (Z_ANCHOR.test(str))
+ return false;
+ try {
+ new RegExp(str);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+ }
+});
+
+// node_modules/fast-deep-equal/index.js
+var require_fast_deep_equal = __commonJS({
+ "node_modules/fast-deep-equal/index.js"(exports, module) {
+ "use strict";
+ module.exports = function equal2(a, b) {
+ if (a === b) return true;
+ if (a && b && typeof a == "object" && typeof b == "object") {
+ if (a.constructor !== b.constructor) return false;
+ var length, i, keys;
+ if (Array.isArray(a)) {
+ length = a.length;
+ if (length != b.length) return false;
+ for (i = length; i-- !== 0; )
+ if (!equal2(a[i], b[i])) return false;
+ return true;
+ }
+ if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
+ if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
+ if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
+ keys = Object.keys(a);
+ length = keys.length;
+ if (length !== Object.keys(b).length) return false;
+ for (i = length; i-- !== 0; )
+ if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
+ for (i = length; i-- !== 0; ) {
+ var key = keys[i];
+ if (!equal2(a[key], b[key])) return false;
+ }
+ return true;
+ }
+ return a !== a && b !== b;
+ };
+ }
+});
+
+// node_modules/openclaw-brokerkit/node_modules/ajv/dist/runtime/equal.js
+var require_equal = __commonJS({
+ "node_modules/openclaw-brokerkit/node_modules/ajv/dist/runtime/equal.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ var equal2 = require_fast_deep_equal();
+ equal2.code = 'require("ajv/dist/runtime/equal").default';
+ exports.default = equal2;
+ }
+});
+
+// node_modules/openclaw-brokerkit/node_modules/ajv/dist/runtime/ucs2length.js
+var require_ucs2length = __commonJS({
+ "node_modules/openclaw-brokerkit/node_modules/ajv/dist/runtime/ucs2length.js"(exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ function ucs2length2(str) {
+ const len = str.length;
+ let length = 0;
+ let pos = 0;
+ let value;
+ while (pos < len) {
+ length++;
+ value = str.charCodeAt(pos++);
+ if (value >= 55296 && value <= 56319 && pos < len) {
+ value = str.charCodeAt(pos);
+ if ((value & 64512) === 56320)
+ pos++;
+ }
+ }
+ return length;
+ }
+ exports.default = ucs2length2;
+ ucs2length2.code = 'require("ajv/dist/runtime/ucs2length").default';
+ }
+});
// src/mlclaw-space-runtime/cli.ts
import { spawn as spawn2 } from "node:child_process";
@@ -640,7309 +939,10241 @@ function positiveNumber(value) {
import { isAbsolute } from "node:path";
import { readFileSync } from "node:fs";
-// node_modules/zod/v3/external.js
-var external_exports = {};
-__export(external_exports, {
- BRAND: () => BRAND,
- DIRTY: () => DIRTY,
- EMPTY_PATH: () => EMPTY_PATH,
- INVALID: () => INVALID,
- NEVER: () => NEVER,
- OK: () => OK,
- ParseStatus: () => ParseStatus,
- Schema: () => ZodType,
- ZodAny: () => ZodAny,
- ZodArray: () => ZodArray,
- ZodBigInt: () => ZodBigInt,
- ZodBoolean: () => ZodBoolean,
- ZodBranded: () => ZodBranded,
- ZodCatch: () => ZodCatch,
- ZodDate: () => ZodDate,
- ZodDefault: () => ZodDefault,
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
- ZodEffects: () => ZodEffects,
- ZodEnum: () => ZodEnum,
- ZodError: () => ZodError,
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
- ZodFunction: () => ZodFunction,
- ZodIntersection: () => ZodIntersection,
- ZodIssueCode: () => ZodIssueCode,
- ZodLazy: () => ZodLazy,
- ZodLiteral: () => ZodLiteral,
- ZodMap: () => ZodMap,
- ZodNaN: () => ZodNaN,
- ZodNativeEnum: () => ZodNativeEnum,
- ZodNever: () => ZodNever,
- ZodNull: () => ZodNull,
- ZodNullable: () => ZodNullable,
- ZodNumber: () => ZodNumber,
- ZodObject: () => ZodObject,
- ZodOptional: () => ZodOptional,
- ZodParsedType: () => ZodParsedType,
- ZodPipeline: () => ZodPipeline,
- ZodPromise: () => ZodPromise,
- ZodReadonly: () => ZodReadonly,
- ZodRecord: () => ZodRecord,
- ZodSchema: () => ZodType,
- ZodSet: () => ZodSet,
- ZodString: () => ZodString,
- ZodSymbol: () => ZodSymbol,
- ZodTransformer: () => ZodEffects,
- ZodTuple: () => ZodTuple,
- ZodType: () => ZodType,
- ZodUndefined: () => ZodUndefined,
- ZodUnion: () => ZodUnion,
- ZodUnknown: () => ZodUnknown,
- ZodVoid: () => ZodVoid,
- addIssueToContext: () => addIssueToContext,
- any: () => anyType,
- array: () => arrayType,
- bigint: () => bigIntType,
- boolean: () => booleanType,
- coerce: () => coerce,
- custom: () => custom,
- date: () => dateType,
- datetimeRegex: () => datetimeRegex,
- defaultErrorMap: () => en_default,
- discriminatedUnion: () => discriminatedUnionType,
- effect: () => effectsType,
- enum: () => enumType,
- function: () => functionType,
- getErrorMap: () => getErrorMap,
- getParsedType: () => getParsedType,
- instanceof: () => instanceOfType,
- intersection: () => intersectionType,
- isAborted: () => isAborted,
- isAsync: () => isAsync,
- isDirty: () => isDirty,
- isValid: () => isValid,
- late: () => late,
- lazy: () => lazyType,
- literal: () => literalType,
- makeIssue: () => makeIssue,
- map: () => mapType,
- nan: () => nanType,
- nativeEnum: () => nativeEnumType,
- never: () => neverType,
- null: () => nullType,
- nullable: () => nullableType,
- number: () => numberType,
- object: () => objectType,
- objectUtil: () => objectUtil,
- oboolean: () => oboolean,
- onumber: () => onumber,
- optional: () => optionalType,
- ostring: () => ostring,
- pipeline: () => pipelineType,
- preprocess: () => preprocessType,
- promise: () => promiseType,
- quotelessJson: () => quotelessJson,
- record: () => recordType,
- set: () => setType,
- setErrorMap: () => setErrorMap,
- strictObject: () => strictObjectType,
- string: () => stringType,
- symbol: () => symbolType,
- transformer: () => effectsType,
- tuple: () => tupleType,
- undefined: () => undefinedType,
- union: () => unionType,
- unknown: () => unknownType,
- util: () => util,
- void: () => voidType
-});
-
-// node_modules/zod/v3/helpers/util.js
-var util;
-(function(util2) {
- util2.assertEqual = (_) => {
- };
- function assertIs(_arg) {
- }
- util2.assertIs = assertIs;
- function assertNever(_x) {
- throw new Error();
- }
- util2.assertNever = assertNever;
- util2.arrayToEnum = (items) => {
- const obj = {};
- for (const item of items) {
- obj[item] = item;
- }
- return obj;
- };
- util2.getValidEnumValues = (obj) => {
- const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
- const filtered = {};
- for (const k of validKeys) {
- filtered[k] = obj[k];
- }
- return util2.objectValues(filtered);
- };
- util2.objectValues = (obj) => {
- return util2.objectKeys(obj).map(function(e) {
- return obj[e];
- });
- };
- util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object2) => {
- const keys = [];
- for (const key in object2) {
- if (Object.prototype.hasOwnProperty.call(object2, key)) {
- keys.push(key);
+// node_modules/openclaw-brokerkit/dist/src/generated/operator-validators.js
+var import_formats = __toESM(require_formats(), 1);
+var import_equal = __toESM(require_equal(), 1);
+var import_ucs2length = __toESM(require_ucs2length(), 1);
+var formats = import_formats.default.fullFormats;
+var equal = import_equal.default.default ?? import_equal.default;
+var ucs2length = import_ucs2length.default.default ?? import_ucs2length.default;
+var validateDescriptor = validate20;
+function validate20(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate20.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ const _errs0 = errors;
+ if (errors === _errs0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.api_version === void 0 && (missing0 = "api_version")) {
+ validate20.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Descriptor/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs2 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "api_version")) {
+ validate20.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Descriptor/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs2 === errors) {
+ if (data.api_version !== void 0) {
+ let data0 = data.api_version;
+ if (typeof data0 !== "string") {
+ validate20.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Descriptor/properties/api_version/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if ("brokerkit.io/operator/v1" !== data0) {
+ validate20.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Descriptor/properties/api_version/const", keyword: "const", params: { allowedValue: "brokerkit.io/operator/v1" }, message: "must be equal to constant" }];
+ return false;
+ }
+ }
+ }
}
+ } else {
+ validate20.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Descriptor/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return keys;
- };
- util2.find = (arr, checker) => {
- for (const item of arr) {
- if (checker(item))
- return item;
- }
- return void 0;
- };
- util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
- function joinValues(array, separator = " | ") {
- return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
}
- util2.joinValues = joinValues;
- util2.jsonStringifyReplacer = (_, value) => {
- if (typeof value === "bigint") {
- return value.toString();
+ validate20.errors = vErrors;
+ return errors === 0;
+}
+validate20.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var func1 = ucs2length;
+function validate22(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate22.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ const _errs0 = errors;
+ if (errors === _errs0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.status === void 0 && (missing0 = "status")) {
+ validate22.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs2 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "status")) {
+ validate22.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs2 === errors) {
+ if (data.status !== void 0) {
+ let data0 = data.status;
+ const _errs3 = errors;
+ if (errors === _errs3) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 128) {
+ validate22.errors = [{ instancePath: instancePath + "/status", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/properties/status/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate22.errors = [{ instancePath: instancePath + "/status", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/properties/status/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate22.errors = [{ instancePath: instancePath + "/status", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/properties/status/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate22.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/Health/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return value;
- };
-})(util || (util = {}));
-var objectUtil;
-(function(objectUtil2) {
- objectUtil2.mergeShapes = (first, second) => {
- return {
- ...first,
- ...second
- // second overwrites first
- };
- };
-})(objectUtil || (objectUtil = {}));
-var ZodParsedType = util.arrayToEnum([
- "string",
- "nan",
- "number",
- "integer",
- "float",
- "boolean",
- "date",
- "bigint",
- "symbol",
- "function",
- "undefined",
- "null",
- "array",
- "object",
- "unknown",
- "promise",
- "void",
- "never",
- "map",
- "set"
-]);
-var getParsedType = (data) => {
- const t = typeof data;
- switch (t) {
- case "undefined":
- return ZodParsedType.undefined;
- case "string":
- return ZodParsedType.string;
- case "number":
- return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
- case "boolean":
- return ZodParsedType.boolean;
- case "function":
- return ZodParsedType.function;
- case "bigint":
- return ZodParsedType.bigint;
- case "symbol":
- return ZodParsedType.symbol;
- case "object":
- if (Array.isArray(data)) {
- return ZodParsedType.array;
- }
- if (data === null) {
- return ZodParsedType.null;
- }
- if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
- return ZodParsedType.promise;
- }
- if (typeof Map !== "undefined" && data instanceof Map) {
- return ZodParsedType.map;
- }
- if (typeof Set !== "undefined" && data instanceof Set) {
- return ZodParsedType.set;
- }
- if (typeof Date !== "undefined" && data instanceof Date) {
- return ZodParsedType.date;
- }
- return ZodParsedType.object;
- default:
- return ZodParsedType.unknown;
- }
-};
-
-// node_modules/zod/v3/ZodError.js
-var ZodIssueCode = util.arrayToEnum([
- "invalid_type",
- "invalid_literal",
- "custom",
- "invalid_union",
- "invalid_union_discriminator",
- "invalid_enum_value",
- "unrecognized_keys",
- "invalid_arguments",
- "invalid_return_type",
- "invalid_date",
- "invalid_string",
- "too_small",
- "too_big",
- "invalid_intersection_types",
- "not_multiple_of",
- "not_finite"
-]);
-var quotelessJson = (obj) => {
- const json = JSON.stringify(obj, null, 2);
- return json.replace(/"([^"]+)":/g, "$1:");
-};
-var ZodError = class _ZodError extends Error {
- get errors() {
- return this.issues;
}
- constructor(issues) {
- super();
- this.issues = [];
- this.addIssue = (sub) => {
- this.issues = [...this.issues, sub];
- };
- this.addIssues = (subs = []) => {
- this.issues = [...this.issues, ...subs];
- };
- const actualProto = new.target.prototype;
- if (Object.setPrototypeOf) {
- Object.setPrototypeOf(this, actualProto);
+ validate22.errors = vErrors;
+ return errors === 0;
+}
+validate22.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var validateBrokerRequest = validate23;
+var schema37 = { "type": "object", "additionalProperties": false, "required": ["id", "revision", "requester", "operation", "status", "requested_at", "requested_duration_seconds", "requested_max_uses", "granted_max_uses", "used_count", "presentation", "allowed_actions"], "properties": { "id": { "type": "string", "minLength": 1, "maxLength": 128 }, "revision": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "requester": { "type": "string", "minLength": 1, "maxLength": 80 }, "operation": { "type": "string", "minLength": 1, "maxLength": 500 }, "status": { "$ref": "#/$defs/Status" }, "requested_at": { "type": "string", "format": "date-time" }, "pending_expires_at": { "type": "string", "format": "date-time" }, "active_expires_at": { "type": "string", "format": "date-time" }, "requested_duration_seconds": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "requested_max_uses": { "type": ["integer", "null"], "minimum": 1, "maximum": 9007199254740991 }, "granted_max_uses": { "type": ["integer", "null"], "minimum": 1, "maximum": 9007199254740991 }, "used_count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "request_reason": { "type": "string", "maxLength": 2e3 }, "decided_at": { "type": "string", "format": "date-time" }, "decided_by": { "type": "string", "maxLength": 200 }, "decided_on_behalf_of": { "type": "string", "maxLength": 200 }, "presentation": { "$ref": "#/$defs/Presentation" }, "presentation_unavailable": { "type": "boolean" }, "allowed_actions": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/Action" } }, "approval_bounds": { "$ref": "#/$defs/ApprovalBounds" } } };
+var schema38 = { "type": "string", "enum": ["pending", "active", "denied", "canceled", "expired", "consumed", "revoked"] };
+var schema44 = { "type": "string", "enum": ["approve", "deny", "revoke"] };
+var schema45 = { "type": "object", "additionalProperties": false, "required": ["max_duration_seconds", "max_uses"], "properties": { "max_duration_seconds": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "max_uses": { "type": ["integer", "null"], "minimum": 1, "maximum": 9007199254740991 } } };
+var func3 = Object.prototype.hasOwnProperty;
+var func0 = equal;
+var formats0 = formats["date-time"];
+var schema40 = { "type": "string", "enum": ["unknown", "low", "medium", "high", "critical"] };
+function validate26(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate26.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.severity === void 0 && (missing0 = "severity") || data.text === void 0 && (missing0 = "text")) {
+ validate26.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "severity" || key0 === "text")) {
+ validate26.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.severity !== void 0) {
+ let data0 = data.severity;
+ const _errs2 = errors;
+ if (typeof data0 !== "string") {
+ validate26.errors = [{ instancePath: instancePath + "/severity", schemaPath: "#/$defs/PresentationRisk/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data0 === "unknown" || data0 === "low" || data0 === "medium" || data0 === "high" || data0 === "critical")) {
+ validate26.errors = [{ instancePath: instancePath + "/severity", schemaPath: "#/$defs/PresentationRisk/enum", keyword: "enum", params: { allowedValues: schema40.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.text !== void 0) {
+ let data1 = data.text;
+ const _errs5 = errors;
+ if (errors === _errs5) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 500) {
+ validate26.errors = [{ instancePath: instancePath + "/text", schemaPath: "#/properties/text/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate26.errors = [{ instancePath: instancePath + "/text", schemaPath: "#/properties/text/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate26.errors = [{ instancePath: instancePath + "/text", schemaPath: "#/properties/text/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs5 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
} else {
- this.__proto__ = actualProto;
+ validate26.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- this.name = "ZodError";
- this.issues = issues;
}
- format(_mapper) {
- const mapper = _mapper || function(issue) {
- return issue.message;
- };
- const fieldErrors = { _errors: [] };
- const processError = (error) => {
- for (const issue of error.issues) {
- if (issue.code === "invalid_union") {
- issue.unionErrors.map(processError);
- } else if (issue.code === "invalid_return_type") {
- processError(issue.returnTypeError);
- } else if (issue.code === "invalid_arguments") {
- processError(issue.argumentsError);
- } else if (issue.path.length === 0) {
- fieldErrors._errors.push(mapper(issue));
- } else {
- let curr = fieldErrors;
- let i = 0;
- while (i < issue.path.length) {
- const el = issue.path[i];
- const terminal = i === issue.path.length - 1;
- if (!terminal) {
- curr[el] = curr[el] || { _errors: [] };
+ validate26.errors = vErrors;
+ return errors === 0;
+}
+validate26.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate25(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate25.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.risk === void 0 && (missing0 = "risk") || data.title === void 0 && (missing0 = "title") || data.target === void 0 && (missing0 = "target")) {
+ validate25.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "risk" || key0 === "title" || key0 === "summary" || key0 === "target" || key0 === "facts" || key0 === "warnings" || key0 === "plan_hash")) {
+ validate25.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.risk !== void 0) {
+ let data0 = data.risk;
+ const _errs2 = errors;
+ if (typeof data0 !== "string") {
+ validate25.errors = [{ instancePath: instancePath + "/risk", schemaPath: "#/$defs/PresentationRisk/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data0 === "unknown" || data0 === "low" || data0 === "medium" || data0 === "high" || data0 === "critical")) {
+ validate25.errors = [{ instancePath: instancePath + "/risk", schemaPath: "#/$defs/PresentationRisk/enum", keyword: "enum", params: { allowedValues: schema40.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.title !== void 0) {
+ let data1 = data.title;
+ const _errs5 = errors;
+ if (errors === _errs5) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 200) {
+ validate25.errors = [{ instancePath: instancePath + "/title", schemaPath: "#/properties/title/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate25.errors = [{ instancePath: instancePath + "/title", schemaPath: "#/properties/title/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/title", schemaPath: "#/properties/title/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs5 === errors;
} else {
- curr[el] = curr[el] || { _errors: [] };
- curr[el]._errors.push(mapper(issue));
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.summary !== void 0) {
+ let data2 = data.summary;
+ const _errs7 = errors;
+ if (errors === _errs7) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 2e3) {
+ validate25.errors = [{ instancePath: instancePath + "/summary", schemaPath: "#/properties/summary/maxLength", keyword: "maxLength", params: { limit: 2e3 }, message: "must NOT have more than 2000 characters" }];
+ return false;
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/summary", schemaPath: "#/properties/summary/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs7 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.target !== void 0) {
+ let data3 = data.target;
+ const _errs9 = errors;
+ if (errors === _errs9) {
+ if (typeof data3 === "string") {
+ if (func1(data3) > 500) {
+ validate25.errors = [{ instancePath: instancePath + "/target", schemaPath: "#/properties/target/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data3) < 1) {
+ validate25.errors = [{ instancePath: instancePath + "/target", schemaPath: "#/properties/target/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/target", schemaPath: "#/properties/target/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs9 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.facts !== void 0) {
+ let data4 = data.facts;
+ const _errs11 = errors;
+ if (errors === _errs11) {
+ if (Array.isArray(data4)) {
+ if (data4.length > 20) {
+ validate25.errors = [{ instancePath: instancePath + "/facts", schemaPath: "#/properties/facts/maxItems", keyword: "maxItems", params: { limit: 20 }, message: "must NOT have more than 20 items" }];
+ return false;
+ } else {
+ var valid2 = true;
+ const len0 = data4.length;
+ for (let i0 = 0; i0 < len0; i0++) {
+ let data5 = data4[i0];
+ const _errs13 = errors;
+ const _errs14 = errors;
+ if (errors === _errs14) {
+ if (data5 && typeof data5 == "object" && !Array.isArray(data5)) {
+ let missing1;
+ if (data5.label === void 0 && (missing1 = "label") || data5.value === void 0 && (missing1 = "value")) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0, schemaPath: "#/$defs/Fact/required", keyword: "required", params: { missingProperty: missing1 }, message: "must have required property '" + missing1 + "'" }];
+ return false;
+ } else {
+ const _errs16 = errors;
+ for (const key1 in data5) {
+ if (!(key1 === "label" || key1 === "value")) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0, schemaPath: "#/$defs/Fact/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key1 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs16 === errors) {
+ if (data5.label !== void 0) {
+ let data6 = data5.label;
+ const _errs17 = errors;
+ if (errors === _errs17) {
+ if (typeof data6 === "string") {
+ if (func1(data6) > 80) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/label", schemaPath: "#/$defs/Fact/properties/label/maxLength", keyword: "maxLength", params: { limit: 80 }, message: "must NOT have more than 80 characters" }];
+ return false;
+ } else {
+ if (func1(data6) < 1) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/label", schemaPath: "#/$defs/Fact/properties/label/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/label", schemaPath: "#/$defs/Fact/properties/label/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid4 = _errs17 === errors;
+ } else {
+ var valid4 = true;
+ }
+ if (valid4) {
+ if (data5.value !== void 0) {
+ let data7 = data5.value;
+ const _errs19 = errors;
+ if (errors === _errs19) {
+ if (typeof data7 === "string") {
+ if (func1(data7) > 500) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/value", schemaPath: "#/$defs/Fact/properties/value/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data7) < 1) {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/value", schemaPath: "#/$defs/Fact/properties/value/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0 + "/value", schemaPath: "#/$defs/Fact/properties/value/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid4 = _errs19 === errors;
+ } else {
+ var valid4 = true;
+ }
+ }
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/facts/" + i0, schemaPath: "#/$defs/Fact/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ var valid2 = _errs13 === errors;
+ if (!valid2) {
+ break;
+ }
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/facts", schemaPath: "#/properties/facts/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs11 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.warnings !== void 0) {
+ let data8 = data.warnings;
+ const _errs21 = errors;
+ if (errors === _errs21) {
+ if (Array.isArray(data8)) {
+ if (data8.length > 10) {
+ validate25.errors = [{ instancePath: instancePath + "/warnings", schemaPath: "#/properties/warnings/maxItems", keyword: "maxItems", params: { limit: 10 }, message: "must NOT have more than 10 items" }];
+ return false;
+ } else {
+ var valid5 = true;
+ const len1 = data8.length;
+ for (let i1 = 0; i1 < len1; i1++) {
+ const _errs23 = errors;
+ if (!validate26(data8[i1], { instancePath: instancePath + "/warnings/" + i1, parentData: data8, parentDataProperty: i1, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate26.errors : vErrors.concat(validate26.errors);
+ errors = vErrors.length;
+ }
+ var valid5 = _errs23 === errors;
+ if (!valid5) {
+ break;
+ }
+ }
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/warnings", schemaPath: "#/properties/warnings/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs21 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.plan_hash !== void 0) {
+ let data10 = data.plan_hash;
+ const _errs24 = errors;
+ if (errors === _errs24) {
+ if (typeof data10 === "string") {
+ if (func1(data10) > 128) {
+ validate25.errors = [{ instancePath: instancePath + "/plan_hash", schemaPath: "#/properties/plan_hash/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ }
+ } else {
+ validate25.errors = [{ instancePath: instancePath + "/plan_hash", schemaPath: "#/properties/plan_hash/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs24 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
}
- curr = curr[el];
- i++;
}
}
}
- };
- processError(this);
- return fieldErrors;
- }
- static assert(value) {
- if (!(value instanceof _ZodError)) {
- throw new Error(`Not a ZodError: ${value}`);
+ } else {
+ validate25.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
}
- toString() {
- return this.message;
+ validate25.errors = vErrors;
+ return errors === 0;
+}
+validate25.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate24(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate24.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
- get message() {
- return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
}
- get isEmpty() {
- return this.issues.length === 0;
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.id === void 0 && (missing0 = "id") || data.revision === void 0 && (missing0 = "revision") || data.requester === void 0 && (missing0 = "requester") || data.operation === void 0 && (missing0 = "operation") || data.status === void 0 && (missing0 = "status") || data.requested_at === void 0 && (missing0 = "requested_at") || data.requested_duration_seconds === void 0 && (missing0 = "requested_duration_seconds") || data.requested_max_uses === void 0 && (missing0 = "requested_max_uses") || data.granted_max_uses === void 0 && (missing0 = "granted_max_uses") || data.used_count === void 0 && (missing0 = "used_count") || data.presentation === void 0 && (missing0 = "presentation") || data.allowed_actions === void 0 && (missing0 = "allowed_actions")) {
+ validate24.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!func3.call(schema37.properties, key0)) {
+ validate24.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.id !== void 0) {
+ let data0 = data.id;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 128) {
+ validate24.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate24.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.revision !== void 0) {
+ let data1 = data.revision;
+ const _errs4 = errors;
+ if (!(typeof data1 == "number" && (!(data1 % 1) && !isNaN(data1)) && isFinite(data1))) {
+ validate24.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs4) {
+ if (typeof data1 == "number" && isFinite(data1)) {
+ if (data1 > 9007199254740991 || isNaN(data1)) {
+ validate24.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data1 < 1 || isNaN(data1)) {
+ validate24.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requester !== void 0) {
+ let data2 = data.requester;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 80) {
+ validate24.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/maxLength", keyword: "maxLength", params: { limit: 80 }, message: "must NOT have more than 80 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 1) {
+ validate24.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.operation !== void 0) {
+ let data3 = data.operation;
+ const _errs8 = errors;
+ if (errors === _errs8) {
+ if (typeof data3 === "string") {
+ if (func1(data3) > 500) {
+ validate24.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data3) < 1) {
+ validate24.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.status !== void 0) {
+ let data4 = data.status;
+ const _errs10 = errors;
+ if (typeof data4 !== "string") {
+ validate24.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data4 === "pending" || data4 === "active" || data4 === "denied" || data4 === "canceled" || data4 === "expired" || data4 === "consumed" || data4 === "revoked")) {
+ validate24.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/enum", keyword: "enum", params: { allowedValues: schema38.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs10 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_at !== void 0) {
+ let data5 = data.requested_at;
+ const _errs13 = errors;
+ if (errors === _errs13) {
+ if (errors === _errs13) {
+ if (typeof data5 === "string") {
+ if (!formats0.validate(data5)) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_at", schemaPath: "#/properties/requested_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/requested_at", schemaPath: "#/properties/requested_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs13 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.pending_expires_at !== void 0) {
+ let data6 = data.pending_expires_at;
+ const _errs15 = errors;
+ if (errors === _errs15) {
+ if (errors === _errs15) {
+ if (typeof data6 === "string") {
+ if (!formats0.validate(data6)) {
+ validate24.errors = [{ instancePath: instancePath + "/pending_expires_at", schemaPath: "#/properties/pending_expires_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/pending_expires_at", schemaPath: "#/properties/pending_expires_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs15 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.active_expires_at !== void 0) {
+ let data7 = data.active_expires_at;
+ const _errs17 = errors;
+ if (errors === _errs17) {
+ if (errors === _errs17) {
+ if (typeof data7 === "string") {
+ if (!formats0.validate(data7)) {
+ validate24.errors = [{ instancePath: instancePath + "/active_expires_at", schemaPath: "#/properties/active_expires_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/active_expires_at", schemaPath: "#/properties/active_expires_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs17 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_duration_seconds !== void 0) {
+ let data8 = data.requested_duration_seconds;
+ const _errs19 = errors;
+ if (!(typeof data8 == "number" && (!(data8 % 1) && !isNaN(data8)) && isFinite(data8))) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs19) {
+ if (typeof data8 == "number" && isFinite(data8)) {
+ if (data8 > 9007199254740991 || isNaN(data8)) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data8 < 1 || isNaN(data8)) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs19 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_max_uses !== void 0) {
+ let data9 = data.requested_max_uses;
+ const _errs21 = errors;
+ if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9)) && data9 !== null) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/type", keyword: "type", params: { type: schema37.properties.requested_max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs21) {
+ if (typeof data9 == "number" && isFinite(data9)) {
+ if (data9 > 9007199254740991 || isNaN(data9)) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data9 < 1 || isNaN(data9)) {
+ validate24.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs21 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.granted_max_uses !== void 0) {
+ let data10 = data.granted_max_uses;
+ const _errs23 = errors;
+ if (!(typeof data10 == "number" && (!(data10 % 1) && !isNaN(data10)) && isFinite(data10)) && data10 !== null) {
+ validate24.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/type", keyword: "type", params: { type: schema37.properties.granted_max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs23) {
+ if (typeof data10 == "number" && isFinite(data10)) {
+ if (data10 > 9007199254740991 || isNaN(data10)) {
+ validate24.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data10 < 1 || isNaN(data10)) {
+ validate24.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs23 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.used_count !== void 0) {
+ let data11 = data.used_count;
+ const _errs25 = errors;
+ if (!(typeof data11 == "number" && (!(data11 % 1) && !isNaN(data11)) && isFinite(data11))) {
+ validate24.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs25) {
+ if (typeof data11 == "number" && isFinite(data11)) {
+ if (data11 > 9007199254740991 || isNaN(data11)) {
+ validate24.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data11 < 0 || isNaN(data11)) {
+ validate24.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs25 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.request_reason !== void 0) {
+ let data12 = data.request_reason;
+ const _errs27 = errors;
+ if (errors === _errs27) {
+ if (typeof data12 === "string") {
+ if (func1(data12) > 2e3) {
+ validate24.errors = [{ instancePath: instancePath + "/request_reason", schemaPath: "#/properties/request_reason/maxLength", keyword: "maxLength", params: { limit: 2e3 }, message: "must NOT have more than 2000 characters" }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/request_reason", schemaPath: "#/properties/request_reason/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs27 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_at !== void 0) {
+ let data13 = data.decided_at;
+ const _errs29 = errors;
+ if (errors === _errs29) {
+ if (errors === _errs29) {
+ if (typeof data13 === "string") {
+ if (!formats0.validate(data13)) {
+ validate24.errors = [{ instancePath: instancePath + "/decided_at", schemaPath: "#/properties/decided_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/decided_at", schemaPath: "#/properties/decided_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs29 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_by !== void 0) {
+ let data14 = data.decided_by;
+ const _errs31 = errors;
+ if (errors === _errs31) {
+ if (typeof data14 === "string") {
+ if (func1(data14) > 200) {
+ validate24.errors = [{ instancePath: instancePath + "/decided_by", schemaPath: "#/properties/decided_by/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/decided_by", schemaPath: "#/properties/decided_by/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs31 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_on_behalf_of !== void 0) {
+ let data15 = data.decided_on_behalf_of;
+ const _errs33 = errors;
+ if (errors === _errs33) {
+ if (typeof data15 === "string") {
+ if (func1(data15) > 200) {
+ validate24.errors = [{ instancePath: instancePath + "/decided_on_behalf_of", schemaPath: "#/properties/decided_on_behalf_of/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/decided_on_behalf_of", schemaPath: "#/properties/decided_on_behalf_of/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs33 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.presentation !== void 0) {
+ const _errs35 = errors;
+ if (!validate25(data.presentation, { instancePath: instancePath + "/presentation", parentData: data, parentDataProperty: "presentation", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate25.errors : vErrors.concat(validate25.errors);
+ errors = vErrors.length;
+ }
+ var valid0 = _errs35 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.presentation_unavailable !== void 0) {
+ const _errs36 = errors;
+ if (typeof data.presentation_unavailable !== "boolean") {
+ validate24.errors = [{ instancePath: instancePath + "/presentation_unavailable", schemaPath: "#/properties/presentation_unavailable/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" }];
+ return false;
+ }
+ var valid0 = _errs36 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.allowed_actions !== void 0) {
+ let data18 = data.allowed_actions;
+ const _errs38 = errors;
+ if (errors === _errs38) {
+ if (Array.isArray(data18)) {
+ var valid2 = true;
+ const len0 = data18.length;
+ for (let i0 = 0; i0 < len0; i0++) {
+ let data19 = data18[i0];
+ const _errs40 = errors;
+ if (typeof data19 !== "string") {
+ validate24.errors = [{ instancePath: instancePath + "/allowed_actions/" + i0, schemaPath: "#/$defs/Action/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data19 === "approve" || data19 === "deny" || data19 === "revoke")) {
+ validate24.errors = [{ instancePath: instancePath + "/allowed_actions/" + i0, schemaPath: "#/$defs/Action/enum", keyword: "enum", params: { allowedValues: schema44.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid2 = _errs40 === errors;
+ if (!valid2) {
+ break;
+ }
+ }
+ if (valid2) {
+ let i1 = data18.length;
+ let j0;
+ if (i1 > 1) {
+ outer0: for (; i1--; ) {
+ for (j0 = i1; j0--; ) {
+ if (func0(data18[i1], data18[j0])) {
+ validate24.errors = [{ instancePath: instancePath + "/allowed_actions", schemaPath: "#/properties/allowed_actions/uniqueItems", keyword: "uniqueItems", params: { i: i1, j: j0 }, message: "must NOT have duplicate items (items ## " + j0 + " and " + i1 + " are identical)" }];
+ return false;
+ break outer0;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/allowed_actions", schemaPath: "#/properties/allowed_actions/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs38 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.approval_bounds !== void 0) {
+ let data20 = data.approval_bounds;
+ const _errs43 = errors;
+ const _errs44 = errors;
+ if (errors === _errs44) {
+ if (data20 && typeof data20 == "object" && !Array.isArray(data20)) {
+ let missing1;
+ if (data20.max_duration_seconds === void 0 && (missing1 = "max_duration_seconds") || data20.max_uses === void 0 && (missing1 = "max_uses")) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/required", keyword: "required", params: { missingProperty: missing1 }, message: "must have required property '" + missing1 + "'" }];
+ return false;
+ } else {
+ const _errs46 = errors;
+ for (const key1 in data20) {
+ if (!(key1 === "max_duration_seconds" || key1 === "max_uses")) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key1 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs46 === errors) {
+ if (data20.max_duration_seconds !== void 0) {
+ let data21 = data20.max_duration_seconds;
+ const _errs47 = errors;
+ if (!(typeof data21 == "number" && (!(data21 % 1) && !isNaN(data21)) && isFinite(data21))) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs47) {
+ if (typeof data21 == "number" && isFinite(data21)) {
+ if (data21 > 9007199254740991 || isNaN(data21)) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data21 < 1 || isNaN(data21)) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid6 = _errs47 === errors;
+ } else {
+ var valid6 = true;
+ }
+ if (valid6) {
+ if (data20.max_uses !== void 0) {
+ let data22 = data20.max_uses;
+ const _errs49 = errors;
+ if (!(typeof data22 == "number" && (!(data22 % 1) && !isNaN(data22)) && isFinite(data22)) && data22 !== null) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/type", keyword: "type", params: { type: schema45.properties.max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs49) {
+ if (typeof data22 == "number" && isFinite(data22)) {
+ if (data22 > 9007199254740991 || isNaN(data22)) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data22 < 1 || isNaN(data22)) {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid6 = _errs49 === errors;
+ } else {
+ var valid6 = true;
+ }
+ }
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ var valid0 = _errs43 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate24.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
}
- flatten(mapper = (issue) => issue.message) {
- const fieldErrors = {};
- const formErrors = [];
- for (const sub of this.issues) {
- if (sub.path.length > 0) {
- const firstEl = sub.path[0];
- fieldErrors[firstEl] = fieldErrors[firstEl] || [];
- fieldErrors[firstEl].push(mapper(sub));
+ validate24.errors = vErrors;
+ return errors === 0;
+}
+validate24.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate23(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate23.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (!validate24(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate24.errors : vErrors.concat(validate24.errors);
+ errors = vErrors.length;
+ }
+ validate23.errors = vErrors;
+ return errors === 0;
+}
+validate23.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var validateRequestPage = validate30;
+function validate32(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate32.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.id === void 0 && (missing0 = "id") || data.revision === void 0 && (missing0 = "revision") || data.requester === void 0 && (missing0 = "requester") || data.operation === void 0 && (missing0 = "operation") || data.status === void 0 && (missing0 = "status") || data.requested_at === void 0 && (missing0 = "requested_at") || data.requested_duration_seconds === void 0 && (missing0 = "requested_duration_seconds") || data.requested_max_uses === void 0 && (missing0 = "requested_max_uses") || data.granted_max_uses === void 0 && (missing0 = "granted_max_uses") || data.used_count === void 0 && (missing0 = "used_count") || data.presentation === void 0 && (missing0 = "presentation") || data.allowed_actions === void 0 && (missing0 = "allowed_actions")) {
+ validate32.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
} else {
- formErrors.push(mapper(sub));
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!func3.call(schema37.properties, key0)) {
+ validate32.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.id !== void 0) {
+ let data0 = data.id;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 128) {
+ validate32.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate32.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/id", schemaPath: "#/properties/id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.revision !== void 0) {
+ let data1 = data.revision;
+ const _errs4 = errors;
+ if (!(typeof data1 == "number" && (!(data1 % 1) && !isNaN(data1)) && isFinite(data1))) {
+ validate32.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs4) {
+ if (typeof data1 == "number" && isFinite(data1)) {
+ if (data1 > 9007199254740991 || isNaN(data1)) {
+ validate32.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data1 < 1 || isNaN(data1)) {
+ validate32.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requester !== void 0) {
+ let data2 = data.requester;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 80) {
+ validate32.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/maxLength", keyword: "maxLength", params: { limit: 80 }, message: "must NOT have more than 80 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 1) {
+ validate32.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/requester", schemaPath: "#/properties/requester/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.operation !== void 0) {
+ let data3 = data.operation;
+ const _errs8 = errors;
+ if (errors === _errs8) {
+ if (typeof data3 === "string") {
+ if (func1(data3) > 500) {
+ validate32.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data3) < 1) {
+ validate32.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/operation", schemaPath: "#/properties/operation/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.status !== void 0) {
+ let data4 = data.status;
+ const _errs10 = errors;
+ if (typeof data4 !== "string") {
+ validate32.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data4 === "pending" || data4 === "active" || data4 === "denied" || data4 === "canceled" || data4 === "expired" || data4 === "consumed" || data4 === "revoked")) {
+ validate32.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/enum", keyword: "enum", params: { allowedValues: schema38.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs10 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_at !== void 0) {
+ let data5 = data.requested_at;
+ const _errs13 = errors;
+ if (errors === _errs13) {
+ if (errors === _errs13) {
+ if (typeof data5 === "string") {
+ if (!formats0.validate(data5)) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_at", schemaPath: "#/properties/requested_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/requested_at", schemaPath: "#/properties/requested_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs13 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.pending_expires_at !== void 0) {
+ let data6 = data.pending_expires_at;
+ const _errs15 = errors;
+ if (errors === _errs15) {
+ if (errors === _errs15) {
+ if (typeof data6 === "string") {
+ if (!formats0.validate(data6)) {
+ validate32.errors = [{ instancePath: instancePath + "/pending_expires_at", schemaPath: "#/properties/pending_expires_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/pending_expires_at", schemaPath: "#/properties/pending_expires_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs15 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.active_expires_at !== void 0) {
+ let data7 = data.active_expires_at;
+ const _errs17 = errors;
+ if (errors === _errs17) {
+ if (errors === _errs17) {
+ if (typeof data7 === "string") {
+ if (!formats0.validate(data7)) {
+ validate32.errors = [{ instancePath: instancePath + "/active_expires_at", schemaPath: "#/properties/active_expires_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/active_expires_at", schemaPath: "#/properties/active_expires_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs17 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_duration_seconds !== void 0) {
+ let data8 = data.requested_duration_seconds;
+ const _errs19 = errors;
+ if (!(typeof data8 == "number" && (!(data8 % 1) && !isNaN(data8)) && isFinite(data8))) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs19) {
+ if (typeof data8 == "number" && isFinite(data8)) {
+ if (data8 > 9007199254740991 || isNaN(data8)) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data8 < 1 || isNaN(data8)) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_duration_seconds", schemaPath: "#/properties/requested_duration_seconds/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs19 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requested_max_uses !== void 0) {
+ let data9 = data.requested_max_uses;
+ const _errs21 = errors;
+ if (!(typeof data9 == "number" && (!(data9 % 1) && !isNaN(data9)) && isFinite(data9)) && data9 !== null) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/type", keyword: "type", params: { type: schema37.properties.requested_max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs21) {
+ if (typeof data9 == "number" && isFinite(data9)) {
+ if (data9 > 9007199254740991 || isNaN(data9)) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data9 < 1 || isNaN(data9)) {
+ validate32.errors = [{ instancePath: instancePath + "/requested_max_uses", schemaPath: "#/properties/requested_max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs21 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.granted_max_uses !== void 0) {
+ let data10 = data.granted_max_uses;
+ const _errs23 = errors;
+ if (!(typeof data10 == "number" && (!(data10 % 1) && !isNaN(data10)) && isFinite(data10)) && data10 !== null) {
+ validate32.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/type", keyword: "type", params: { type: schema37.properties.granted_max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs23) {
+ if (typeof data10 == "number" && isFinite(data10)) {
+ if (data10 > 9007199254740991 || isNaN(data10)) {
+ validate32.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data10 < 1 || isNaN(data10)) {
+ validate32.errors = [{ instancePath: instancePath + "/granted_max_uses", schemaPath: "#/properties/granted_max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs23 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.used_count !== void 0) {
+ let data11 = data.used_count;
+ const _errs25 = errors;
+ if (!(typeof data11 == "number" && (!(data11 % 1) && !isNaN(data11)) && isFinite(data11))) {
+ validate32.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs25) {
+ if (typeof data11 == "number" && isFinite(data11)) {
+ if (data11 > 9007199254740991 || isNaN(data11)) {
+ validate32.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data11 < 0 || isNaN(data11)) {
+ validate32.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs25 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.request_reason !== void 0) {
+ let data12 = data.request_reason;
+ const _errs27 = errors;
+ if (errors === _errs27) {
+ if (typeof data12 === "string") {
+ if (func1(data12) > 2e3) {
+ validate32.errors = [{ instancePath: instancePath + "/request_reason", schemaPath: "#/properties/request_reason/maxLength", keyword: "maxLength", params: { limit: 2e3 }, message: "must NOT have more than 2000 characters" }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/request_reason", schemaPath: "#/properties/request_reason/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs27 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_at !== void 0) {
+ let data13 = data.decided_at;
+ const _errs29 = errors;
+ if (errors === _errs29) {
+ if (errors === _errs29) {
+ if (typeof data13 === "string") {
+ if (!formats0.validate(data13)) {
+ validate32.errors = [{ instancePath: instancePath + "/decided_at", schemaPath: "#/properties/decided_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/decided_at", schemaPath: "#/properties/decided_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs29 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_by !== void 0) {
+ let data14 = data.decided_by;
+ const _errs31 = errors;
+ if (errors === _errs31) {
+ if (typeof data14 === "string") {
+ if (func1(data14) > 200) {
+ validate32.errors = [{ instancePath: instancePath + "/decided_by", schemaPath: "#/properties/decided_by/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/decided_by", schemaPath: "#/properties/decided_by/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs31 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.decided_on_behalf_of !== void 0) {
+ let data15 = data.decided_on_behalf_of;
+ const _errs33 = errors;
+ if (errors === _errs33) {
+ if (typeof data15 === "string") {
+ if (func1(data15) > 200) {
+ validate32.errors = [{ instancePath: instancePath + "/decided_on_behalf_of", schemaPath: "#/properties/decided_on_behalf_of/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/decided_on_behalf_of", schemaPath: "#/properties/decided_on_behalf_of/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs33 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.presentation !== void 0) {
+ const _errs35 = errors;
+ if (!validate25(data.presentation, { instancePath: instancePath + "/presentation", parentData: data, parentDataProperty: "presentation", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate25.errors : vErrors.concat(validate25.errors);
+ errors = vErrors.length;
+ }
+ var valid0 = _errs35 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.presentation_unavailable !== void 0) {
+ const _errs36 = errors;
+ if (typeof data.presentation_unavailable !== "boolean") {
+ validate32.errors = [{ instancePath: instancePath + "/presentation_unavailable", schemaPath: "#/properties/presentation_unavailable/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" }];
+ return false;
+ }
+ var valid0 = _errs36 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.allowed_actions !== void 0) {
+ let data18 = data.allowed_actions;
+ const _errs38 = errors;
+ if (errors === _errs38) {
+ if (Array.isArray(data18)) {
+ var valid2 = true;
+ const len0 = data18.length;
+ for (let i0 = 0; i0 < len0; i0++) {
+ let data19 = data18[i0];
+ const _errs40 = errors;
+ if (typeof data19 !== "string") {
+ validate32.errors = [{ instancePath: instancePath + "/allowed_actions/" + i0, schemaPath: "#/$defs/Action/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data19 === "approve" || data19 === "deny" || data19 === "revoke")) {
+ validate32.errors = [{ instancePath: instancePath + "/allowed_actions/" + i0, schemaPath: "#/$defs/Action/enum", keyword: "enum", params: { allowedValues: schema44.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid2 = _errs40 === errors;
+ if (!valid2) {
+ break;
+ }
+ }
+ if (valid2) {
+ let i1 = data18.length;
+ let j0;
+ if (i1 > 1) {
+ outer0: for (; i1--; ) {
+ for (j0 = i1; j0--; ) {
+ if (func0(data18[i1], data18[j0])) {
+ validate32.errors = [{ instancePath: instancePath + "/allowed_actions", schemaPath: "#/properties/allowed_actions/uniqueItems", keyword: "uniqueItems", params: { i: i1, j: j0 }, message: "must NOT have duplicate items (items ## " + j0 + " and " + i1 + " are identical)" }];
+ return false;
+ break outer0;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/allowed_actions", schemaPath: "#/properties/allowed_actions/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs38 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.approval_bounds !== void 0) {
+ let data20 = data.approval_bounds;
+ const _errs43 = errors;
+ const _errs44 = errors;
+ if (errors === _errs44) {
+ if (data20 && typeof data20 == "object" && !Array.isArray(data20)) {
+ let missing1;
+ if (data20.max_duration_seconds === void 0 && (missing1 = "max_duration_seconds") || data20.max_uses === void 0 && (missing1 = "max_uses")) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/required", keyword: "required", params: { missingProperty: missing1 }, message: "must have required property '" + missing1 + "'" }];
+ return false;
+ } else {
+ const _errs46 = errors;
+ for (const key1 in data20) {
+ if (!(key1 === "max_duration_seconds" || key1 === "max_uses")) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key1 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs46 === errors) {
+ if (data20.max_duration_seconds !== void 0) {
+ let data21 = data20.max_duration_seconds;
+ const _errs47 = errors;
+ if (!(typeof data21 == "number" && (!(data21 % 1) && !isNaN(data21)) && isFinite(data21))) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs47) {
+ if (typeof data21 == "number" && isFinite(data21)) {
+ if (data21 > 9007199254740991 || isNaN(data21)) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data21 < 1 || isNaN(data21)) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_duration_seconds", schemaPath: "#/$defs/ApprovalBounds/properties/max_duration_seconds/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid6 = _errs47 === errors;
+ } else {
+ var valid6 = true;
+ }
+ if (valid6) {
+ if (data20.max_uses !== void 0) {
+ let data22 = data20.max_uses;
+ const _errs49 = errors;
+ if (!(typeof data22 == "number" && (!(data22 % 1) && !isNaN(data22)) && isFinite(data22)) && data22 !== null) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/type", keyword: "type", params: { type: schema45.properties.max_uses.type }, message: "must be integer,null" }];
+ return false;
+ }
+ if (errors === _errs49) {
+ if (typeof data22 == "number" && isFinite(data22)) {
+ if (data22 > 9007199254740991 || isNaN(data22)) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data22 < 1 || isNaN(data22)) {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds/max_uses", schemaPath: "#/$defs/ApprovalBounds/properties/max_uses/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid6 = _errs49 === errors;
+ } else {
+ var valid6 = true;
+ }
+ }
+ }
+ }
+ } else {
+ validate32.errors = [{ instancePath: instancePath + "/approval_bounds", schemaPath: "#/$defs/ApprovalBounds/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ var valid0 = _errs43 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
+ } else {
+ validate32.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return { formErrors, fieldErrors };
}
- get formErrors() {
- return this.flatten();
+ validate32.errors = vErrors;
+ return errors === 0;
+}
+validate32.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate31(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate31.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
-};
-ZodError.create = (issues) => {
- const error = new ZodError(issues);
- return error;
-};
-
-// node_modules/zod/v3/locales/en.js
-var errorMap = (issue, _ctx) => {
- let message;
- switch (issue.code) {
- case ZodIssueCode.invalid_type:
- if (issue.received === ZodParsedType.undefined) {
- message = "Required";
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.requests === void 0 && (missing0 = "requests")) {
+ validate31.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
} else {
- message = `Expected ${issue.expected}, received ${issue.received}`;
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "requests" || key0 === "next_cursor" || key0 === "event_cursor")) {
+ validate31.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.requests !== void 0) {
+ let data0 = data.requests;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (Array.isArray(data0)) {
+ if (data0.length > 100) {
+ validate31.errors = [{ instancePath: instancePath + "/requests", schemaPath: "#/properties/requests/maxItems", keyword: "maxItems", params: { limit: 100 }, message: "must NOT have more than 100 items" }];
+ return false;
+ } else {
+ var valid1 = true;
+ const len0 = data0.length;
+ for (let i0 = 0; i0 < len0; i0++) {
+ const _errs4 = errors;
+ if (!validate32(data0[i0], { instancePath: instancePath + "/requests/" + i0, parentData: data0, parentDataProperty: i0, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate32.errors : vErrors.concat(validate32.errors);
+ errors = vErrors.length;
+ }
+ var valid1 = _errs4 === errors;
+ if (!valid1) {
+ break;
+ }
+ }
+ }
+ } else {
+ validate31.errors = [{ instancePath: instancePath + "/requests", schemaPath: "#/properties/requests/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.next_cursor !== void 0) {
+ let data2 = data.next_cursor;
+ const _errs5 = errors;
+ if (errors === _errs5) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 1024) {
+ validate31.errors = [{ instancePath: instancePath + "/next_cursor", schemaPath: "#/properties/next_cursor/maxLength", keyword: "maxLength", params: { limit: 1024 }, message: "must NOT have more than 1024 characters" }];
+ return false;
+ }
+ } else {
+ validate31.errors = [{ instancePath: instancePath + "/next_cursor", schemaPath: "#/properties/next_cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs5 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.event_cursor !== void 0) {
+ let data3 = data.event_cursor;
+ const _errs7 = errors;
+ if (errors === _errs7) {
+ if (typeof data3 === "string") {
+ if (func1(data3) > 1024) {
+ validate31.errors = [{ instancePath: instancePath + "/event_cursor", schemaPath: "#/properties/event_cursor/maxLength", keyword: "maxLength", params: { limit: 1024 }, message: "must NOT have more than 1024 characters" }];
+ return false;
+ }
+ } else {
+ validate31.errors = [{ instancePath: instancePath + "/event_cursor", schemaPath: "#/properties/event_cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs7 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
}
- break;
- case ZodIssueCode.invalid_literal:
- message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
- break;
- case ZodIssueCode.unrecognized_keys:
- message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
- break;
- case ZodIssueCode.invalid_union:
- message = `Invalid input`;
- break;
- case ZodIssueCode.invalid_union_discriminator:
- message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
- break;
- case ZodIssueCode.invalid_enum_value:
- message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
- break;
- case ZodIssueCode.invalid_arguments:
- message = `Invalid function arguments`;
- break;
- case ZodIssueCode.invalid_return_type:
- message = `Invalid function return type`;
- break;
- case ZodIssueCode.invalid_date:
- message = `Invalid date`;
- break;
- case ZodIssueCode.invalid_string:
- if (typeof issue.validation === "object") {
- if ("includes" in issue.validation) {
- message = `Invalid input: must include "${issue.validation.includes}"`;
- if (typeof issue.validation.position === "number") {
- message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
+ } else {
+ validate31.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ validate31.errors = vErrors;
+ return errors === 0;
+}
+validate31.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate30(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate30.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (!validate31(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate31.errors : vErrors.concat(validate31.errors);
+ errors = vErrors.length;
+ }
+ validate30.errors = vErrors;
+ return errors === 0;
+}
+validate30.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var schema53 = { "type": "object", "additionalProperties": false, "required": ["cursor", "kind", "request_id", "revision", "status", "occurred_at", "used_count"], "properties": { "cursor": { "type": "string", "minLength": 1, "maxLength": 1024 }, "kind": { "type": "string", "enum": ["request.created", "request.approved", "request.denied", "request.canceled", "request.expired", "grant.revoked", "grant.reserved", "grant.consumed", "grant.released", "execution.succeeded", "execution.failed", "execution.ambiguous"] }, "request_id": { "type": "string", "minLength": 1, "maxLength": 128 }, "revision": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }, "status": { "$ref": "#/$defs/Status" }, "occurred_at": { "type": "string", "format": "date-time" }, "used_count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } } };
+function validate37(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate37.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.cursor === void 0 && (missing0 = "cursor") || data.kind === void 0 && (missing0 = "kind") || data.request_id === void 0 && (missing0 = "request_id") || data.revision === void 0 && (missing0 = "revision") || data.status === void 0 && (missing0 = "status") || data.occurred_at === void 0 && (missing0 = "occurred_at") || data.used_count === void 0 && (missing0 = "used_count")) {
+ validate37.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "cursor" || key0 === "kind" || key0 === "request_id" || key0 === "revision" || key0 === "status" || key0 === "occurred_at" || key0 === "used_count")) {
+ validate37.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
}
- } else if ("startsWith" in issue.validation) {
- message = `Invalid input: must start with "${issue.validation.startsWith}"`;
- } else if ("endsWith" in issue.validation) {
- message = `Invalid input: must end with "${issue.validation.endsWith}"`;
- } else {
- util.assertNever(issue.validation);
}
- } else if (issue.validation !== "regex") {
- message = `Invalid ${issue.validation}`;
+ if (_errs1 === errors) {
+ if (data.cursor !== void 0) {
+ let data0 = data.cursor;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 1024) {
+ validate37.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/maxLength", keyword: "maxLength", params: { limit: 1024 }, message: "must NOT have more than 1024 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate37.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate37.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.kind !== void 0) {
+ let data1 = data.kind;
+ const _errs4 = errors;
+ if (typeof data1 !== "string") {
+ validate37.errors = [{ instancePath: instancePath + "/kind", schemaPath: "#/properties/kind/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data1 === "request.created" || data1 === "request.approved" || data1 === "request.denied" || data1 === "request.canceled" || data1 === "request.expired" || data1 === "grant.revoked" || data1 === "grant.reserved" || data1 === "grant.consumed" || data1 === "grant.released" || data1 === "execution.succeeded" || data1 === "execution.failed" || data1 === "execution.ambiguous")) {
+ validate37.errors = [{ instancePath: instancePath + "/kind", schemaPath: "#/properties/kind/enum", keyword: "enum", params: { allowedValues: schema53.properties.kind.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.request_id !== void 0) {
+ let data2 = data.request_id;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 128) {
+ validate37.errors = [{ instancePath: instancePath + "/request_id", schemaPath: "#/properties/request_id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 1) {
+ validate37.errors = [{ instancePath: instancePath + "/request_id", schemaPath: "#/properties/request_id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate37.errors = [{ instancePath: instancePath + "/request_id", schemaPath: "#/properties/request_id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.revision !== void 0) {
+ let data3 = data.revision;
+ const _errs8 = errors;
+ if (!(typeof data3 == "number" && (!(data3 % 1) && !isNaN(data3)) && isFinite(data3))) {
+ validate37.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs8) {
+ if (typeof data3 == "number" && isFinite(data3)) {
+ if (data3 > 9007199254740991 || isNaN(data3)) {
+ validate37.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data3 < 1 || isNaN(data3)) {
+ validate37.errors = [{ instancePath: instancePath + "/revision", schemaPath: "#/properties/revision/minimum", keyword: "minimum", params: { comparison: ">=", limit: 1 }, message: "must be >= 1" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.status !== void 0) {
+ let data4 = data.status;
+ const _errs10 = errors;
+ if (typeof data4 !== "string") {
+ validate37.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data4 === "pending" || data4 === "active" || data4 === "denied" || data4 === "canceled" || data4 === "expired" || data4 === "consumed" || data4 === "revoked")) {
+ validate37.errors = [{ instancePath: instancePath + "/status", schemaPath: "#/$defs/Status/enum", keyword: "enum", params: { allowedValues: schema38.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs10 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.occurred_at !== void 0) {
+ let data5 = data.occurred_at;
+ const _errs13 = errors;
+ if (errors === _errs13) {
+ if (errors === _errs13) {
+ if (typeof data5 === "string") {
+ if (!formats0.validate(data5)) {
+ validate37.errors = [{ instancePath: instancePath + "/occurred_at", schemaPath: "#/properties/occurred_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate37.errors = [{ instancePath: instancePath + "/occurred_at", schemaPath: "#/properties/occurred_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs13 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.used_count !== void 0) {
+ let data6 = data.used_count;
+ const _errs15 = errors;
+ if (!(typeof data6 == "number" && (!(data6 % 1) && !isNaN(data6)) && isFinite(data6))) {
+ validate37.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs15) {
+ if (typeof data6 == "number" && isFinite(data6)) {
+ if (data6 > 9007199254740991 || isNaN(data6)) {
+ validate37.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data6 < 0 || isNaN(data6)) {
+ validate37.errors = [{ instancePath: instancePath + "/used_count", schemaPath: "#/properties/used_count/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs15 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate37.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ validate37.errors = vErrors;
+ return errors === 0;
+}
+validate37.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate36(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate36.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (!validate37(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate37.errors : vErrors.concat(validate37.errors);
+ errors = vErrors.length;
+ }
+ validate36.errors = vErrors;
+ return errors === 0;
+}
+validate36.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var validateErrorEnvelope = validate39;
+var schema57 = { "type": "object", "additionalProperties": false, "required": ["code", "message", "correlation_id"], "properties": { "code": { "type": "string", "enum": ["invalid_request", "unauthorized", "forbidden", "not_found", "method_not_allowed", "revision_conflict", "idempotency_conflict", "constraint_exceeded", "invalid_transition", "invalid_decision_token", "cursor_expired", "temporarily_unavailable", "internal_error"] }, "message": { "type": "string", "minLength": 1, "maxLength": 500 }, "correlation_id": { "type": "string", "minLength": 1, "maxLength": 128 }, "current": { "$ref": "#/$defs/BrokerRequest" } } };
+function validate41(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate41.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.code === void 0 && (missing0 = "code") || data.message === void 0 && (missing0 = "message") || data.correlation_id === void 0 && (missing0 = "correlation_id")) {
+ validate41.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
} else {
- message = "Invalid";
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "code" || key0 === "message" || key0 === "correlation_id" || key0 === "current")) {
+ validate41.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.code !== void 0) {
+ let data0 = data.code;
+ const _errs2 = errors;
+ if (typeof data0 !== "string") {
+ validate41.errors = [{ instancePath: instancePath + "/code", schemaPath: "#/properties/code/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if (!(data0 === "invalid_request" || data0 === "unauthorized" || data0 === "forbidden" || data0 === "not_found" || data0 === "method_not_allowed" || data0 === "revision_conflict" || data0 === "idempotency_conflict" || data0 === "constraint_exceeded" || data0 === "invalid_transition" || data0 === "invalid_decision_token" || data0 === "cursor_expired" || data0 === "temporarily_unavailable" || data0 === "internal_error")) {
+ validate41.errors = [{ instancePath: instancePath + "/code", schemaPath: "#/properties/code/enum", keyword: "enum", params: { allowedValues: schema57.properties.code.enum }, message: "must be equal to one of the allowed values" }];
+ return false;
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.message !== void 0) {
+ let data1 = data.message;
+ const _errs4 = errors;
+ if (errors === _errs4) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 500) {
+ validate41.errors = [{ instancePath: instancePath + "/message", schemaPath: "#/properties/message/maxLength", keyword: "maxLength", params: { limit: 500 }, message: "must NOT have more than 500 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate41.errors = [{ instancePath: instancePath + "/message", schemaPath: "#/properties/message/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate41.errors = [{ instancePath: instancePath + "/message", schemaPath: "#/properties/message/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.correlation_id !== void 0) {
+ let data2 = data.correlation_id;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 128) {
+ validate41.errors = [{ instancePath: instancePath + "/correlation_id", schemaPath: "#/properties/correlation_id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 1) {
+ validate41.errors = [{ instancePath: instancePath + "/correlation_id", schemaPath: "#/properties/correlation_id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate41.errors = [{ instancePath: instancePath + "/correlation_id", schemaPath: "#/properties/correlation_id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.current !== void 0) {
+ const _errs8 = errors;
+ if (!validate32(data.current, { instancePath: instancePath + "/current", parentData: data, parentDataProperty: "current", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate32.errors : vErrors.concat(validate32.errors);
+ errors = vErrors.length;
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
}
- break;
- case ZodIssueCode.too_small:
- if (issue.type === "array")
- message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
- else if (issue.type === "string")
- message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
- else if (issue.type === "number")
- message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
- else if (issue.type === "bigint")
- message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
- else if (issue.type === "date")
- message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
- else
- message = "Invalid input";
- break;
- case ZodIssueCode.too_big:
- if (issue.type === "array")
- message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
- else if (issue.type === "string")
- message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
- else if (issue.type === "number")
- message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
- else if (issue.type === "bigint")
- message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
- else if (issue.type === "date")
- message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
- else
- message = "Invalid input";
- break;
- case ZodIssueCode.custom:
- message = `Invalid input`;
- break;
- case ZodIssueCode.invalid_intersection_types:
- message = `Intersection results could not be merged`;
- break;
- case ZodIssueCode.not_multiple_of:
- message = `Number must be a multiple of ${issue.multipleOf}`;
- break;
- case ZodIssueCode.not_finite:
- message = "Number must be finite";
- break;
- default:
- message = _ctx.defaultError;
- util.assertNever(issue);
+ } else {
+ validate41.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
}
- return { message };
-};
-var en_default = errorMap;
-
-// node_modules/zod/v3/errors.js
-var overrideErrorMap = en_default;
-function setErrorMap(map) {
- overrideErrorMap = map;
-}
-function getErrorMap() {
- return overrideErrorMap;
+ validate41.errors = vErrors;
+ return errors === 0;
}
-
-// node_modules/zod/v3/helpers/parseUtil.js
-var makeIssue = (params) => {
- const { data, path: path5, errorMaps, issueData } = params;
- const fullPath = [...path5, ...issueData.path || []];
- const fullIssue = {
- ...issueData,
- path: fullPath
- };
- if (issueData.message !== void 0) {
- return {
- ...issueData,
- path: fullPath,
- message: issueData.message
- };
+validate41.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate40(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate40.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
- let errorMessage = "";
- const maps = errorMaps.filter((m) => !!m).slice().reverse();
- for (const map of maps) {
- errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
}
- return {
- ...issueData,
- path: fullPath,
- message: errorMessage
- };
-};
-var EMPTY_PATH = [];
-function addIssueToContext(ctx, issueData) {
- const overrideMap = getErrorMap();
- const issue = makeIssue({
- issueData,
- data: ctx.data,
- path: ctx.path,
- errorMaps: [
- ctx.common.contextualErrorMap,
- // contextual error map is first priority
- ctx.schemaErrorMap,
- // then schema-bound map if available
- overrideMap,
- // then global override map
- overrideMap === en_default ? void 0 : en_default
- // then global default map
- ].filter((x) => !!x)
- });
- ctx.common.issues.push(issue);
-}
-var ParseStatus = class _ParseStatus {
- constructor() {
- this.value = "valid";
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.error === void 0 && (missing0 = "error")) {
+ validate40.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "error")) {
+ validate40.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.error !== void 0) {
+ if (!validate41(data.error, { instancePath: instancePath + "/error", parentData: data, parentDataProperty: "error", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate41.errors : vErrors.concat(validate41.errors);
+ errors = vErrors.length;
+ }
+ }
+ }
+ }
+ } else {
+ validate40.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
}
- dirty() {
- if (this.value === "valid")
- this.value = "dirty";
+ validate40.errors = vErrors;
+ return errors === 0;
+}
+validate40.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate39(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate39.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (!validate40(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate40.errors : vErrors.concat(validate40.errors);
+ errors = vErrors.length;
+ }
+ validate39.errors = vErrors;
+ return errors === 0;
+}
+validate39.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+var pattern4 = new RegExp("^[A-Za-z0-9_-]+$", "u");
+function validate47(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate47.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.source_id === void 0 && (missing0 = "source_id") || data.source_label === void 0 && (missing0 = "source_label") || data.handle === void 0 && (missing0 = "handle") || data.request === void 0 && (missing0 = "request")) {
+ validate47.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "source_id" || key0 === "source_label" || key0 === "handle" || key0 === "request")) {
+ validate47.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.source_id !== void 0) {
+ let data0 = data.source_id;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 128) {
+ validate47.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate47.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate47.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.source_label !== void 0) {
+ let data1 = data.source_label;
+ const _errs4 = errors;
+ if (errors === _errs4) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 200) {
+ validate47.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate47.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate47.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.handle !== void 0) {
+ let data2 = data.handle;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 256) {
+ validate47.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/maxLength", keyword: "maxLength", params: { limit: 256 }, message: "must NOT have more than 256 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 22) {
+ validate47.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/minLength", keyword: "minLength", params: { limit: 22 }, message: "must NOT have fewer than 22 characters" }];
+ return false;
+ } else {
+ if (!pattern4.test(data2)) {
+ validate47.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' }];
+ return false;
+ }
+ }
+ }
+ } else {
+ validate47.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.request !== void 0) {
+ const _errs8 = errors;
+ if (!validate32(data.request, { instancePath: instancePath + "/request", parentData: data, parentDataProperty: "request", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate32.errors : vErrors.concat(validate32.errors);
+ errors = vErrors.length;
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate47.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
}
- abort() {
- if (this.value !== "aborted")
- this.value = "aborted";
+ validate47.errors = vErrors;
+ return errors === 0;
+}
+validate47.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate46(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate46.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
- static mergeArray(status, results) {
- const arrayValue = [];
- for (const s of results) {
- if (s.status === "aborted")
- return INVALID;
- if (s.status === "dirty")
- status.dirty();
- arrayValue.push(s.value);
- }
- return { status: status.value, value: arrayValue };
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
}
- static async mergeObjectAsync(status, pairs) {
- const syncPairs = [];
- for (const pair of pairs) {
- const key = await pair.key;
- const value = await pair.value;
- syncPairs.push({
- key,
- value
- });
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.api_version === void 0 && (missing0 = "api_version") || data.cursor === void 0 && (missing0 = "cursor") || data.synchronized_at === void 0 && (missing0 = "synchronized_at") || data.sources === void 0 && (missing0 = "sources") || data.requests === void 0 && (missing0 = "requests")) {
+ validate46.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "api_version" || key0 === "cursor" || key0 === "synchronized_at" || key0 === "sources" || key0 === "requests" || key0 === "delivery_failures")) {
+ validate46.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.api_version !== void 0) {
+ let data0 = data.api_version;
+ const _errs2 = errors;
+ if (typeof data0 !== "string") {
+ validate46.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "#/properties/api_version/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if ("brokerkit.io/operator-ui/v1" !== data0) {
+ validate46.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "#/properties/api_version/const", keyword: "const", params: { allowedValue: "brokerkit.io/operator-ui/v1" }, message: "must be equal to constant" }];
+ return false;
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.cursor !== void 0) {
+ let data1 = data.cursor;
+ const _errs4 = errors;
+ if (errors === _errs4) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 128) {
+ validate46.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate46.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "#/properties/cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.synchronized_at !== void 0) {
+ let data2 = data.synchronized_at;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (!formats0.validate(data2)) {
+ validate46.errors = [{ instancePath: instancePath + "/synchronized_at", schemaPath: "#/properties/synchronized_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/synchronized_at", schemaPath: "#/properties/synchronized_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.sources !== void 0) {
+ let data3 = data.sources;
+ const _errs8 = errors;
+ if (errors === _errs8) {
+ if (Array.isArray(data3)) {
+ if (data3.length > 100) {
+ validate46.errors = [{ instancePath: instancePath + "/sources", schemaPath: "#/properties/sources/maxItems", keyword: "maxItems", params: { limit: 100 }, message: "must NOT have more than 100 items" }];
+ return false;
+ } else {
+ var valid1 = true;
+ const len0 = data3.length;
+ for (let i0 = 0; i0 < len0; i0++) {
+ let data4 = data3[i0];
+ const _errs10 = errors;
+ const _errs11 = errors;
+ if (errors === _errs11) {
+ if (data4 && typeof data4 == "object" && !Array.isArray(data4)) {
+ let missing1;
+ if (data4.id === void 0 && (missing1 = "id") || data4.label === void 0 && (missing1 = "label") || data4.healthy === void 0 && (missing1 = "healthy")) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0, schemaPath: "#/$defs/UISourceHealth/required", keyword: "required", params: { missingProperty: missing1 }, message: "must have required property '" + missing1 + "'" }];
+ return false;
+ } else {
+ const _errs13 = errors;
+ for (const key1 in data4) {
+ if (!(key1 === "id" || key1 === "label" || key1 === "healthy" || key1 === "last_sync_at" || key1 === "error")) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0, schemaPath: "#/$defs/UISourceHealth/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key1 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs13 === errors) {
+ if (data4.id !== void 0) {
+ let data5 = data4.id;
+ const _errs14 = errors;
+ if (errors === _errs14) {
+ if (typeof data5 === "string") {
+ if (func1(data5) > 128) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/id", schemaPath: "#/$defs/UISourceHealth/properties/id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data5) < 1) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/id", schemaPath: "#/$defs/UISourceHealth/properties/id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/id", schemaPath: "#/$defs/UISourceHealth/properties/id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid3 = _errs14 === errors;
+ } else {
+ var valid3 = true;
+ }
+ if (valid3) {
+ if (data4.label !== void 0) {
+ let data6 = data4.label;
+ const _errs16 = errors;
+ if (errors === _errs16) {
+ if (typeof data6 === "string") {
+ if (func1(data6) > 200) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/label", schemaPath: "#/$defs/UISourceHealth/properties/label/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ } else {
+ if (func1(data6) < 1) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/label", schemaPath: "#/$defs/UISourceHealth/properties/label/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/label", schemaPath: "#/$defs/UISourceHealth/properties/label/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid3 = _errs16 === errors;
+ } else {
+ var valid3 = true;
+ }
+ if (valid3) {
+ if (data4.healthy !== void 0) {
+ const _errs18 = errors;
+ if (typeof data4.healthy !== "boolean") {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/healthy", schemaPath: "#/$defs/UISourceHealth/properties/healthy/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" }];
+ return false;
+ }
+ var valid3 = _errs18 === errors;
+ } else {
+ var valid3 = true;
+ }
+ if (valid3) {
+ if (data4.last_sync_at !== void 0) {
+ let data8 = data4.last_sync_at;
+ const _errs20 = errors;
+ if (errors === _errs20) {
+ if (errors === _errs20) {
+ if (typeof data8 === "string") {
+ if (!formats0.validate(data8)) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/last_sync_at", schemaPath: "#/$defs/UISourceHealth/properties/last_sync_at/format", keyword: "format", params: { format: "date-time" }, message: 'must match format "date-time"' }];
+ return false;
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/last_sync_at", schemaPath: "#/$defs/UISourceHealth/properties/last_sync_at/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ }
+ var valid3 = _errs20 === errors;
+ } else {
+ var valid3 = true;
+ }
+ if (valid3) {
+ if (data4.error !== void 0) {
+ let data9 = data4.error;
+ const _errs22 = errors;
+ if (errors === _errs22) {
+ if (typeof data9 === "string") {
+ if (func1(data9) > 200) {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/error", schemaPath: "#/$defs/UISourceHealth/properties/error/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0 + "/error", schemaPath: "#/$defs/UISourceHealth/properties/error/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid3 = _errs22 === errors;
+ } else {
+ var valid3 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources/" + i0, schemaPath: "#/$defs/UISourceHealth/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
+ }
+ }
+ var valid1 = _errs10 === errors;
+ if (!valid1) {
+ break;
+ }
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/sources", schemaPath: "#/properties/sources/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.requests !== void 0) {
+ let data10 = data.requests;
+ const _errs24 = errors;
+ if (errors === _errs24) {
+ if (Array.isArray(data10)) {
+ if (data10.length > 1e3) {
+ validate46.errors = [{ instancePath: instancePath + "/requests", schemaPath: "#/properties/requests/maxItems", keyword: "maxItems", params: { limit: 1e3 }, message: "must NOT have more than 1000 items" }];
+ return false;
+ } else {
+ var valid4 = true;
+ const len1 = data10.length;
+ for (let i1 = 0; i1 < len1; i1++) {
+ const _errs26 = errors;
+ if (!validate47(data10[i1], { instancePath: instancePath + "/requests/" + i1, parentData: data10, parentDataProperty: i1, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate47.errors : vErrors.concat(validate47.errors);
+ errors = vErrors.length;
+ }
+ var valid4 = _errs26 === errors;
+ if (!valid4) {
+ break;
+ }
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath: instancePath + "/requests", schemaPath: "#/properties/requests/type", keyword: "type", params: { type: "array" }, message: "must be array" }];
+ return false;
+ }
+ }
+ var valid0 = _errs24 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.delivery_failures !== void 0) {
+ let data12 = data.delivery_failures;
+ const _errs27 = errors;
+ if (!(typeof data12 == "number" && (!(data12 % 1) && !isNaN(data12)) && isFinite(data12))) {
+ validate46.errors = [{ instancePath: instancePath + "/delivery_failures", schemaPath: "#/properties/delivery_failures/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs27) {
+ if (typeof data12 == "number" && isFinite(data12)) {
+ if (data12 > 9007199254740991 || isNaN(data12)) {
+ validate46.errors = [{ instancePath: instancePath + "/delivery_failures", schemaPath: "#/properties/delivery_failures/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data12 < 0 || isNaN(data12)) {
+ validate46.errors = [{ instancePath: instancePath + "/delivery_failures", schemaPath: "#/properties/delivery_failures/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid0 = _errs27 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate46.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return _ParseStatus.mergeObjectSync(status, syncPairs);
}
- static mergeObjectSync(status, pairs) {
- const finalObject = {};
- for (const pair of pairs) {
- const { key, value } = pair;
- if (key.status === "aborted")
- return INVALID;
- if (value.status === "aborted")
- return INVALID;
- if (key.status === "dirty")
- status.dirty();
- if (value.status === "dirty")
- status.dirty();
- if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
- finalObject[key.value] = value.value;
+ validate46.errors = vErrors;
+ return errors === 0;
+}
+validate46.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate45(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate45.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ if (!validate46(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate46.errors : vErrors.concat(validate46.errors);
+ errors = vErrors.length;
+ }
+ validate45.errors = vErrors;
+ return errors === 0;
+}
+validate45.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate51(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate51.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
+ }
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ const _errs0 = errors;
+ if (errors === _errs0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.api_version === void 0 && (missing0 = "api_version") || data.cursor === void 0 && (missing0 = "cursor") || data.changed === void 0 && (missing0 = "changed")) {
+ validate51.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs2 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "api_version" || key0 === "cursor" || key0 === "changed")) {
+ validate51.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs2 === errors) {
+ if (data.api_version !== void 0) {
+ let data0 = data.api_version;
+ const _errs3 = errors;
+ if (typeof data0 !== "string") {
+ validate51.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/api_version/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if ("brokerkit.io/operator-ui/v1" !== data0) {
+ validate51.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/api_version/const", keyword: "const", params: { allowedValue: "brokerkit.io/operator-ui/v1" }, message: "must be equal to constant" }];
+ return false;
+ }
+ var valid1 = _errs3 === errors;
+ } else {
+ var valid1 = true;
+ }
+ if (valid1) {
+ if (data.cursor !== void 0) {
+ let data1 = data.cursor;
+ const _errs5 = errors;
+ if (errors === _errs5) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 128) {
+ validate51.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/cursor/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate51.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/cursor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate51.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid1 = _errs5 === errors;
+ } else {
+ var valid1 = true;
+ }
+ if (valid1) {
+ if (data.changed !== void 0) {
+ const _errs7 = errors;
+ if (typeof data.changed !== "boolean") {
+ validate51.errors = [{ instancePath: instancePath + "/changed", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/properties/changed/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" }];
+ return false;
+ }
+ var valid1 = _errs7 === errors;
+ } else {
+ var valid1 = true;
+ }
+ }
+ }
+ }
}
+ } else {
+ validate51.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISnapshotEvent/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return { status: status.value, value: finalObject };
}
-};
-var INVALID = Object.freeze({
- status: "aborted"
-});
-var DIRTY = (value) => ({ status: "dirty", value });
-var OK = (value) => ({ status: "valid", value });
-var isAborted = (x) => x.status === "aborted";
-var isDirty = (x) => x.status === "dirty";
-var isValid = (x) => x.status === "valid";
-var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
-
-// node_modules/zod/v3/helpers/errorUtil.js
-var errorUtil;
-(function(errorUtil2) {
- errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
- errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
-})(errorUtil || (errorUtil = {}));
-
-// node_modules/zod/v3/types.js
-var ParseInputLazyPath = class {
- constructor(parent, value, path5, key) {
- this._cachedPath = [];
- this.parent = parent;
- this.data = value;
- this._path = path5;
- this._key = key;
+ validate51.errors = vErrors;
+ return errors === 0;
+}
+validate51.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate52(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate52.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
- get path() {
- if (!this._cachedPath.length) {
- if (Array.isArray(this._key)) {
- this._cachedPath.push(...this._path, ...this._key);
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
+ }
+ const _errs0 = errors;
+ if (errors === _errs0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.api_version === void 0 && (missing0 = "api_version") || data.cursor === void 0 && (missing0 = "cursor") || data.pending === void 0 && (missing0 = "pending") || data.healthy === void 0 && (missing0 = "healthy")) {
+ validate52.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
} else {
- this._cachedPath.push(...this._path, this._key);
+ const _errs2 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "api_version" || key0 === "cursor" || key0 === "pending" || key0 === "healthy")) {
+ validate52.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs2 === errors) {
+ if (data.api_version !== void 0) {
+ let data0 = data.api_version;
+ const _errs3 = errors;
+ if (typeof data0 !== "string") {
+ validate52.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/api_version/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ if ("brokerkit.io/operator-ui/v1" !== data0) {
+ validate52.errors = [{ instancePath: instancePath + "/api_version", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/api_version/const", keyword: "const", params: { allowedValue: "brokerkit.io/operator-ui/v1" }, message: "must be equal to constant" }];
+ return false;
+ }
+ var valid1 = _errs3 === errors;
+ } else {
+ var valid1 = true;
+ }
+ if (valid1) {
+ if (data.cursor !== void 0) {
+ let data1 = data.cursor;
+ const _errs5 = errors;
+ if (errors === _errs5) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 128) {
+ validate52.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/cursor/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate52.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/cursor/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate52.errors = [{ instancePath: instancePath + "/cursor", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/cursor/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid1 = _errs5 === errors;
+ } else {
+ var valid1 = true;
+ }
+ if (valid1) {
+ if (data.pending !== void 0) {
+ let data2 = data.pending;
+ const _errs7 = errors;
+ if (!(typeof data2 == "number" && (!(data2 % 1) && !isNaN(data2)) && isFinite(data2))) {
+ validate52.errors = [{ instancePath: instancePath + "/pending", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/pending/type", keyword: "type", params: { type: "integer" }, message: "must be integer" }];
+ return false;
+ }
+ if (errors === _errs7) {
+ if (typeof data2 == "number" && isFinite(data2)) {
+ if (data2 > 9007199254740991 || isNaN(data2)) {
+ validate52.errors = [{ instancePath: instancePath + "/pending", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/pending/maximum", keyword: "maximum", params: { comparison: "<=", limit: 9007199254740991 }, message: "must be <= 9007199254740991" }];
+ return false;
+ } else {
+ if (data2 < 0 || isNaN(data2)) {
+ validate52.errors = [{ instancePath: instancePath + "/pending", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/pending/minimum", keyword: "minimum", params: { comparison: ">=", limit: 0 }, message: "must be >= 0" }];
+ return false;
+ }
+ }
+ }
+ }
+ var valid1 = _errs7 === errors;
+ } else {
+ var valid1 = true;
+ }
+ if (valid1) {
+ if (data.healthy !== void 0) {
+ const _errs9 = errors;
+ if (typeof data.healthy !== "boolean") {
+ validate52.errors = [{ instancePath: instancePath + "/healthy", schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/properties/healthy/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" }];
+ return false;
+ }
+ var valid1 = _errs9 === errors;
+ } else {
+ var valid1 = true;
+ }
+ }
+ }
+ }
+ }
}
+ } else {
+ validate52.errors = [{ instancePath, schemaPath: "https://brokerkit.dev/schema/operator/v1/runtime/components#/$defs/UISummary/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- return this._cachedPath;
}
-};
-var handleResult = (ctx, result) => {
- if (isValid(result)) {
- return { success: true, data: result.value };
- } else {
- if (!ctx.common.issues.length) {
- throw new Error("Validation failed but no issues detected.");
- }
- return {
- success: false,
- get error() {
- if (this._error)
- return this._error;
- const error = new ZodError(ctx.common.issues);
- this._error = error;
- return this._error;
- }
- };
+ validate52.errors = vErrors;
+ return errors === 0;
+}
+validate52.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate54(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate54.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
-};
-function processCreateParams(params) {
- if (!params)
- return {};
- const { errorMap: errorMap2, invalid_type_error, required_error, description } = params;
- if (errorMap2 && (invalid_type_error || required_error)) {
- throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
}
- if (errorMap2)
- return { errorMap: errorMap2, description };
- const customMap = (iss, ctx) => {
- const { message } = params;
- if (iss.code === "invalid_enum_value") {
- return { message: message ?? ctx.defaultError };
- }
- if (typeof ctx.data === "undefined") {
- return { message: message ?? required_error ?? ctx.defaultError };
+ if (errors === 0) {
+ if (data && typeof data == "object" && !Array.isArray(data)) {
+ let missing0;
+ if (data.source_id === void 0 && (missing0 = "source_id") || data.source_label === void 0 && (missing0 = "source_label") || data.handle === void 0 && (missing0 = "handle") || data.request === void 0 && (missing0 = "request")) {
+ validate54.errors = [{ instancePath, schemaPath: "#/required", keyword: "required", params: { missingProperty: missing0 }, message: "must have required property '" + missing0 + "'" }];
+ return false;
+ } else {
+ const _errs1 = errors;
+ for (const key0 in data) {
+ if (!(key0 === "source_id" || key0 === "source_label" || key0 === "handle" || key0 === "request")) {
+ validate54.errors = [{ instancePath, schemaPath: "#/additionalProperties", keyword: "additionalProperties", params: { additionalProperty: key0 }, message: "must NOT have additional properties" }];
+ return false;
+ break;
+ }
+ }
+ if (_errs1 === errors) {
+ if (data.source_id !== void 0) {
+ let data0 = data.source_id;
+ const _errs2 = errors;
+ if (errors === _errs2) {
+ if (typeof data0 === "string") {
+ if (func1(data0) > 128) {
+ validate54.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/maxLength", keyword: "maxLength", params: { limit: 128 }, message: "must NOT have more than 128 characters" }];
+ return false;
+ } else {
+ if (func1(data0) < 1) {
+ validate54.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate54.errors = [{ instancePath: instancePath + "/source_id", schemaPath: "#/properties/source_id/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs2 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.source_label !== void 0) {
+ let data1 = data.source_label;
+ const _errs4 = errors;
+ if (errors === _errs4) {
+ if (typeof data1 === "string") {
+ if (func1(data1) > 200) {
+ validate54.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/maxLength", keyword: "maxLength", params: { limit: 200 }, message: "must NOT have more than 200 characters" }];
+ return false;
+ } else {
+ if (func1(data1) < 1) {
+ validate54.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" }];
+ return false;
+ }
+ }
+ } else {
+ validate54.errors = [{ instancePath: instancePath + "/source_label", schemaPath: "#/properties/source_label/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs4 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.handle !== void 0) {
+ let data2 = data.handle;
+ const _errs6 = errors;
+ if (errors === _errs6) {
+ if (typeof data2 === "string") {
+ if (func1(data2) > 256) {
+ validate54.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/maxLength", keyword: "maxLength", params: { limit: 256 }, message: "must NOT have more than 256 characters" }];
+ return false;
+ } else {
+ if (func1(data2) < 22) {
+ validate54.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/minLength", keyword: "minLength", params: { limit: 22 }, message: "must NOT have fewer than 22 characters" }];
+ return false;
+ } else {
+ if (!pattern4.test(data2)) {
+ validate54.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/pattern", keyword: "pattern", params: { pattern: "^[A-Za-z0-9_-]+$" }, message: 'must match pattern "^[A-Za-z0-9_-]+$"' }];
+ return false;
+ }
+ }
+ }
+ } else {
+ validate54.errors = [{ instancePath: instancePath + "/handle", schemaPath: "#/properties/handle/type", keyword: "type", params: { type: "string" }, message: "must be string" }];
+ return false;
+ }
+ }
+ var valid0 = _errs6 === errors;
+ } else {
+ var valid0 = true;
+ }
+ if (valid0) {
+ if (data.request !== void 0) {
+ const _errs8 = errors;
+ if (!validate32(data.request, { instancePath: instancePath + "/request", parentData: data, parentDataProperty: "request", rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate32.errors : vErrors.concat(validate32.errors);
+ errors = vErrors.length;
+ }
+ var valid0 = _errs8 === errors;
+ } else {
+ var valid0 = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ validate54.errors = [{ instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" }];
+ return false;
}
- if (iss.code !== "invalid_type")
- return { message: ctx.defaultError };
- return { message: message ?? invalid_type_error ?? ctx.defaultError };
- };
- return { errorMap: customMap, description };
+ }
+ validate54.errors = vErrors;
+ return errors === 0;
}
-var ZodType = class {
- get description() {
- return this._def.description;
+validate54.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+function validate53(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) {
+ ;
+ let vErrors = null;
+ let errors = 0;
+ const evaluated0 = validate53.evaluated;
+ if (evaluated0.dynamicProps) {
+ evaluated0.props = void 0;
}
- _getType(input) {
- return getParsedType(input.data);
+ if (evaluated0.dynamicItems) {
+ evaluated0.items = void 0;
}
- _getOrReturnCtx(input, ctx) {
- return ctx || {
- common: input.parent.common,
- data: input.data,
- parsedType: getParsedType(input.data),
- schemaErrorMap: this._def.errorMap,
- path: input.path,
- parent: input.parent
- };
+ if (!validate54(data, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors })) {
+ vErrors = vErrors === null ? validate54.errors : vErrors.concat(validate54.errors);
+ errors = vErrors.length;
}
- _processInputParams(input) {
- return {
- status: new ParseStatus(),
- ctx: {
- common: input.parent.common,
- data: input.data,
- parsedType: getParsedType(input.data),
- schemaErrorMap: this._def.errorMap,
- path: input.path,
- parent: input.parent
- }
- };
+ validate53.errors = vErrors;
+ return errors === 0;
+}
+validate53.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
+
+// node_modules/openclaw-brokerkit/dist/src/operator-v1.js
+function parseDescriptor(value) {
+ return validated(validateDescriptor, value);
+}
+function parseRequest(value) {
+ return validated(validateBrokerRequest, value);
+}
+function parseRequestPage(value) {
+ return validated(validateRequestPage, value);
+}
+function parseErrorEnvelope(value) {
+ return validateErrorEnvelope(value) ? value : void 0;
+}
+function validated(validate, value) {
+ if (!validate(value))
+ throw new Error("Operator V1 response is invalid");
+ return value;
+}
+
+// src/mlclaw-space-runtime/operator-brokers.ts
+var MAX_CONFIG_BYTES = 64 * 1024;
+var MAX_TOKEN_BYTES = 4096;
+var MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
+var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
+var BROKER_ID = /^[a-z](?:[a-z0-9-]{0,38}[a-z0-9])?$/;
+var BrokerOperatorError = class extends Error {
+ constructor(broker, status, code, message) {
+ super(message);
+ this.broker = broker;
+ this.status = status;
+ this.code = code;
}
- _parseSync(input) {
- const result = this._parse(input);
- if (isAsync(result)) {
- throw new Error("Synchronous parse encountered promise.");
+};
+function requestDeadline(timeoutMs, signal) {
+ const timeout = new AbortController();
+ const timer = setTimeout(() => timeout.abort(), timeoutMs);
+ timer.unref?.();
+ return {
+ signal: signal ? AbortSignal.any([signal, timeout.signal]) : timeout.signal,
+ timedOut: () => timeout.signal.aborted,
+ clear: () => clearTimeout(timer)
+ };
+}
+var BrokerOperatorClient = class {
+ constructor(options) {
+ this.options = options;
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
+ this.fetchImpl = options.fetch ?? fetch;
+ this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
+ if (!Number.isSafeInteger(this.requestTimeoutMs) || this.requestTimeoutMs < 1) {
+ throw new Error("operator broker request timeout must be a positive integer");
}
- return result;
- }
- _parseAsync(input) {
- const result = this._parse(input);
- return Promise.resolve(result);
}
- parse(data, params) {
- const result = this.safeParse(data, params);
- if (result.success)
- return result.data;
- throw result.error;
+ fetchImpl;
+ baseUrl;
+ requestTimeoutMs;
+ summary() {
+ return { id: this.options.id, label: this.options.label };
}
- safeParse(data, params) {
- const ctx = {
- common: {
- issues: [],
- async: params?.async ?? false,
- contextualErrorMap: params?.errorMap
- },
- path: params?.path || [],
- schemaErrorMap: this._def.errorMap,
- parent: null,
- data,
- parsedType: getParsedType(data)
- };
- const result = this._parseSync({ data, path: ctx.path, parent: ctx });
- return handleResult(ctx, result);
+ discover(signal) {
+ return this.request(
+ "/.well-known/brokerkit-operator",
+ signal ? { signal } : void 0,
+ parseDescriptor,
+ "discovery"
+ );
}
- "~validate"(data) {
- const ctx = {
- common: {
- issues: [],
- async: !!this["~standard"].async
- },
- path: [],
- schemaErrorMap: this._def.errorMap,
- parent: null,
- data,
- parsedType: getParsedType(data)
- };
- if (!this["~standard"].async) {
- try {
- const result = this._parseSync({ data, path: [], parent: ctx });
- return isValid(result) ? {
- value: result.value
- } : {
- issues: ctx.common.issues
- };
- } catch (err) {
- if (err?.message?.toLowerCase()?.includes("encountered")) {
- this["~standard"].async = true;
- }
- ctx.common = {
- issues: [],
- async: true
- };
- }
+ list(params = {}, signal) {
+ const query = new URLSearchParams();
+ if (params.status) {
+ query.set("status", params.status);
}
- return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? {
- value: result.value
- } : {
- issues: ctx.common.issues
- });
+ if (params.cursor) {
+ query.set("cursor", params.cursor);
+ }
+ if (params.limit) {
+ query.set("limit", String(params.limit));
+ }
+ const suffix = query.size > 0 ? `?${query}` : "";
+ return this.request(
+ `/api/operator/v1/requests${suffix}`,
+ signal ? { signal } : void 0,
+ parseRequestPage,
+ "request list"
+ );
}
- async parseAsync(data, params) {
- const result = await this.safeParseAsync(data, params);
- if (result.success)
- return result.data;
- throw result.error;
+ get(id) {
+ return this.request(
+ `/api/operator/v1/requests/${approvalId(id)}`,
+ void 0,
+ parseRequest,
+ "request"
+ );
}
- async safeParseAsync(data, params) {
- const ctx = {
- common: {
- issues: [],
- contextualErrorMap: params?.errorMap,
- async: true
+ decide(id, action, decision) {
+ return this.request(
+ `/api/operator/v1/requests/${approvalId(id)}/${action}`,
+ {
+ method: "POST",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify({
+ expected_revision: decision.expectedRevision,
+ idempotency_key: decision.idempotencyKey,
+ on_behalf_of: decision.onBehalfOf,
+ ...decision.durationSeconds !== void 0 || decision.maxUses !== void 0 ? {
+ constraints: {
+ ...decision.durationSeconds !== void 0 ? { duration_seconds: decision.durationSeconds } : {},
+ ...decision.maxUses !== void 0 ? { max_uses: decision.maxUses } : {}
+ }
+ } : {}
+ })
},
- path: params?.path || [],
- schemaErrorMap: this._def.errorMap,
- parent: null,
- data,
- parsedType: getParsedType(data)
- };
- const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
- const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
- return handleResult(ctx, result);
+ parseRequest,
+ "request"
+ );
}
- refine(check, message) {
- const getIssueProperties = (val) => {
- if (typeof message === "string" || typeof message === "undefined") {
- return { message };
- } else if (typeof message === "function") {
- return message(val);
- } else {
- return message;
- }
+ async events(lastEventId, signal) {
+ const headers = {
+ accept: "text/event-stream",
+ authorization: `Bearer ${this.options.token}`
};
- return this._refinement((val, ctx) => {
- const result = check(val);
- const setError = () => ctx.addIssue({
- code: ZodIssueCode.custom,
- ...getIssueProperties(val)
+ const cursor = lastEventId ? `?cursor=${encodeURIComponent(lastEventId)}` : "";
+ const response = await this.fetchImpl(`${this.baseUrl}/api/operator/v1/events${cursor}`, {
+ headers,
+ redirect: "error",
+ ...signal ? { signal } : {}
+ });
+ if (!response.ok) {
+ throw await this.operatorError(response);
+ }
+ if (!response.headers.get("content-type")?.toLowerCase().startsWith("text/event-stream")) {
+ await response.body?.cancel();
+ throw new BrokerOperatorError(
+ this.summary(),
+ 502,
+ "invalid_event_stream",
+ "Broker returned an invalid event stream"
+ );
+ }
+ return response;
+ }
+ async request(pathname, init, parser, label) {
+ const headers = new Headers(init?.headers);
+ headers.set("accept", "application/json");
+ headers.set("authorization", `Bearer ${this.options.token}`);
+ const deadline = requestDeadline(this.requestTimeoutMs, init?.signal ?? void 0);
+ try {
+ const response = await this.fetchImpl(`${this.baseUrl}${pathname}`, {
+ ...init ?? {},
+ headers,
+ redirect: "error",
+ signal: deadline.signal
});
- if (typeof Promise !== "undefined" && result instanceof Promise) {
- return result.then((data) => {
- if (!data) {
- setError();
- return false;
- } else {
- return true;
- }
- });
+ if (!response.ok) {
+ throw await this.operatorError(response);
}
- if (!result) {
- setError();
- return false;
- } else {
- return true;
+ return validatedBrokerPayload(await boundedJson(response), parser, label);
+ } catch (err) {
+ if (deadline.timedOut()) {
+ throw new BrokerOperatorError(
+ this.summary(),
+ 504,
+ "broker_timeout",
+ `${this.options.label} operator request timed out`
+ );
}
- });
+ throw err;
+ } finally {
+ deadline.clear();
+ }
}
- refinement(check, refinementData) {
- return this._refinement((val, ctx) => {
- if (!check(val)) {
- ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
- return false;
- } else {
- return true;
- }
- });
+ async operatorError(response) {
+ const fallback = `${this.options.label} operator request failed`;
+ try {
+ const value = validatedBrokerPayload(await boundedJson(response), parseErrorEnvelope, "error");
+ const message = value?.error.message.trim() || fallback;
+ const code = value?.error.code.trim();
+ return new BrokerOperatorError(this.summary(), response.status, code, message);
+ } catch {
+ return new BrokerOperatorError(this.summary(), response.status, void 0, fallback);
+ }
}
- _refinement(refinement) {
- return new ZodEffects({
- schema: this,
- typeName: ZodFirstPartyTypeKind.ZodEffects,
- effect: { type: "refinement", refinement }
- });
+};
+var OperatorBrokerRegistry = class {
+ clients;
+ constructor(configs, fetchImpl) {
+ this.clients = new Map(
+ configs.map((config2) => [
+ config2.id,
+ new BrokerOperatorClient({ ...config2, ...fetchImpl ? { fetch: fetchImpl } : {} })
+ ])
+ );
}
- superRefine(refinement) {
- return this._refinement(refinement);
+ list() {
+ return [...this.clients.values()].map((client) => client.summary());
}
- constructor(def) {
- this.spa = this.safeParseAsync;
- this._def = def;
- this.parse = this.parse.bind(this);
- this.safeParse = this.safeParse.bind(this);
- this.parseAsync = this.parseAsync.bind(this);
- this.safeParseAsync = this.safeParseAsync.bind(this);
- this.spa = this.spa.bind(this);
- this.refine = this.refine.bind(this);
- this.refinement = this.refinement.bind(this);
- this.superRefine = this.superRefine.bind(this);
- this.optional = this.optional.bind(this);
- this.nullable = this.nullable.bind(this);
- this.nullish = this.nullish.bind(this);
- this.array = this.array.bind(this);
- this.promise = this.promise.bind(this);
- this.or = this.or.bind(this);
- this.and = this.and.bind(this);
- this.transform = this.transform.bind(this);
- this.brand = this.brand.bind(this);
- this.default = this.default.bind(this);
- this.catch = this.catch.bind(this);
- this.describe = this.describe.bind(this);
- this.pipe = this.pipe.bind(this);
- this.readonly = this.readonly.bind(this);
- this.isNullable = this.isNullable.bind(this);
- this.isOptional = this.isOptional.bind(this);
- this["~standard"] = {
- version: 1,
- vendor: "zod",
- validate: (data) => this["~validate"](data)
- };
- }
- optional() {
- return ZodOptional.create(this, this._def);
- }
- nullable() {
- return ZodNullable.create(this, this._def);
- }
- nullish() {
- return this.nullable().optional();
- }
- array() {
- return ZodArray.create(this);
+ get(id) {
+ return this.clients.get(id);
}
- promise() {
- return ZodPromise.create(this, this._def);
+ entries() {
+ return [...this.clients.values()].map((client) => [client.summary(), client]);
}
- or(option) {
- return ZodUnion.create([this, option], this._def);
+};
+function loadOperatorBrokers(file) {
+ if (!file) {
+ return [];
}
- and(incoming) {
- return ZodIntersection.create(this, incoming, this._def);
+ if (!isAbsolute(file)) {
+ throw new Error("MLCLAW_OPERATOR_BROKERS_FILE must be absolute");
}
- transform(transform) {
- return new ZodEffects({
- ...processCreateParams(this._def),
- schema: this,
- typeName: ZodFirstPartyTypeKind.ZodEffects,
- effect: { type: "transform", transform }
- });
+ const raw2 = readBoundedFile(file, MAX_CONFIG_BYTES, "operator broker configuration");
+ let parsed;
+ try {
+ parsed = JSON.parse(raw2);
+ } catch {
+ throw new Error("operator broker configuration must be valid JSON");
}
- default(def) {
- const defaultValueFunc = typeof def === "function" ? def : () => def;
- return new ZodDefault({
- ...processCreateParams(this._def),
- innerType: this,
- defaultValue: defaultValueFunc,
- typeName: ZodFirstPartyTypeKind.ZodDefault
- });
+ const root = strictRecord(parsed, ["version", "brokers"], "operator broker configuration");
+ if (root.version !== 1) {
+ throw new Error("operator broker configuration version must be 1");
}
- brand() {
- return new ZodBranded({
- typeName: ZodFirstPartyTypeKind.ZodBranded,
- type: this,
- ...processCreateParams(this._def)
- });
+ if (!Array.isArray(root.brokers) || root.brokers.length > 16) {
+ throw new Error("operator broker configuration must contain at most 16 brokers");
}
- catch(def) {
- const catchValueFunc = typeof def === "function" ? def : () => def;
- return new ZodCatch({
- ...processCreateParams(this._def),
- innerType: this,
- catchValue: catchValueFunc,
- typeName: ZodFirstPartyTypeKind.ZodCatch
- });
+ const ids = /* @__PURE__ */ new Set();
+ const urls = /* @__PURE__ */ new Set();
+ return root.brokers.map((value, index) => {
+ const entry = strictRecord(value, ["id", "label", "url", "token_file"], `broker ${index}`);
+ const id = requiredString(entry.id, `broker ${index} id`);
+ if (!BROKER_ID.test(id) || ids.has(id)) {
+ throw new Error(`broker ${index} id is invalid or duplicated`);
+ }
+ ids.add(id);
+ const label = requiredString(entry.label, `broker ${index} label`);
+ if ([...label].length > 80 || new RegExp("\\p{Cc}", "u").test(label)) {
+ throw new Error(`broker ${index} label is invalid`);
+ }
+ const baseUrl = operatorOrigin(requiredString(entry.url, `broker ${index} url`));
+ if (urls.has(baseUrl)) {
+ throw new Error(`broker ${index} URL is duplicated`);
+ }
+ urls.add(baseUrl);
+ const tokenFile = requiredString(entry.token_file, `broker ${index} token_file`);
+ if (!isAbsolute(tokenFile)) {
+ throw new Error(`broker ${index} token_file must be absolute`);
+ }
+ const token = readBoundedFile(tokenFile, MAX_TOKEN_BYTES, `broker ${id} token`).trim();
+ if (!/^[\x21-\x7e]{24,4096}$/u.test(token)) {
+ throw new Error(`broker ${id} token is invalid`);
+ }
+ return { id, label, baseUrl, token };
+ });
+}
+function operatorOrigin(value) {
+ let url;
+ try {
+ url = new URL(value);
+ } catch {
+ throw new Error("broker URL must be an absolute HTTP URL");
}
- describe(description) {
- const This = this.constructor;
- return new This({
- ...this._def,
- description
- });
+ const supportedProtocol = (/* @__PURE__ */ new Set(["http:", "https:"])).has(url.protocol);
+ const hasAuthorityOrSuffix = [url.username, url.password, url.search, url.hash].some(Boolean);
+ const hasPath = !["", "/"].includes(url.pathname);
+ if (!supportedProtocol || hasAuthorityOrSuffix || hasPath) {
+ throw new Error("broker URL must be one HTTP origin without credentials, path, query, or fragment");
}
- pipe(target) {
- return ZodPipeline.create(this, target);
+ return url.origin;
+}
+function strictRecord(value, keys, label) {
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
+ throw new Error(`${label} must be an object`);
}
- readonly() {
- return ZodReadonly.create(this);
+ const record = value;
+ if (Object.keys(record).some((key) => !keys.includes(key)) || keys.some((key) => !(key in record))) {
+ throw new Error(`${label} has missing or unknown fields`);
}
- isOptional() {
- return this.safeParse(void 0).success;
+ return record;
+}
+function requiredString(value, label) {
+ if (typeof value !== "string" || !value || value !== value.trim()) {
+ throw new Error(`${label} must be a non-empty trimmed string`);
}
- isNullable() {
- return this.safeParse(null).success;
+ return value;
+}
+function readBoundedFile(file, maximum, label) {
+ let value;
+ try {
+ value = readFileSync(file, "utf8");
+ } catch {
+ throw new Error(`${label} could not be read`);
}
-};
-var cuidRegex = /^c[^\s-]{8,}$/i;
-var cuid2Regex = /^[0-9a-z]+$/;
-var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
-var uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
-var nanoidRegex = /^[a-z0-9_-]{21}$/i;
-var jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
-var durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
-var emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
-var _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
-var emojiRegex;
-var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
-var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
-var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
-var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
-var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
-var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
-var dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
-var dateRegex = new RegExp(`^${dateRegexSource}$`);
-function timeRegexSource(args) {
- let secondsRegexSource = `[0-5]\\d`;
- if (args.precision) {
- secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
- } else if (args.precision == null) {
- secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
+ if (Buffer.byteLength(value) > maximum) {
+ throw new Error(`${label} is too large`);
}
- const secondsQuantifier = args.precision ? "+" : "?";
- return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
-}
-function timeRegex(args) {
- return new RegExp(`^${timeRegexSource(args)}$`);
+ return value;
}
-function datetimeRegex(args) {
- let regex = `${dateRegexSource}T${timeRegexSource(args)}`;
- const opts = [];
- opts.push(args.local ? `Z?` : `Z`);
- if (args.offset)
- opts.push(`([+-]\\d{2}:?\\d{2})`);
- regex = `${regex}(${opts.join("|")})`;
- return new RegExp(`^${regex}$`);
+function approvalId(id) {
+ return encodeURIComponent(id);
}
-function isValidIP(ip, version) {
- if ((version === "v4" || !version) && ipv4Regex.test(ip)) {
- return true;
+async function boundedJson(response) {
+ if (!response.body) {
+ throw new Error("broker response body is empty");
}
- if ((version === "v6" || !version) && ipv6Regex.test(ip)) {
- return true;
+ const reader = response.body.getReader();
+ const chunks = [];
+ let size = 0;
+ while (true) {
+ const { done, value } = await reader.read();
+ if (done) {
+ break;
+ }
+ size += value.byteLength;
+ if (size > MAX_RESPONSE_BYTES) {
+ await reader.cancel();
+ throw new Error("broker response is too large");
+ }
+ chunks.push(value);
}
- return false;
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
}
-function isValidJWT(jwt, alg) {
- if (!jwtRegex.test(jwt))
- return false;
+function validatedBrokerPayload(value, parser, label) {
try {
- const [header] = jwt.split(".");
- if (!header)
- return false;
- const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
- const decoded = JSON.parse(atob(base64));
- if (typeof decoded !== "object" || decoded === null)
- return false;
- if ("typ" in decoded && decoded?.typ !== "JWT")
- return false;
- if (!decoded.alg)
- return false;
- if (alg && decoded.alg !== alg)
- return false;
- return true;
+ return parser(value);
} catch {
- return false;
- }
-}
-function isValidCidr(ip, version) {
- if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
- return true;
- }
- if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
- return true;
+ throw new Error(`broker ${label} response is invalid`);
}
- return false;
}
-var ZodString = class _ZodString extends ZodType {
- _parse(input) {
- if (this._def.coerce) {
- input.data = String(input.data);
- }
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.string) {
- const ctx2 = this._getOrReturnCtx(input);
- addIssueToContext(ctx2, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.string,
- received: ctx2.parsedType
- });
- return INVALID;
+
+// src/mlclaw-space-runtime/local-access.ts
+import { createHmac, timingSafeEqual } from "node:crypto";
+var LOCAL_ACCESS_CONTEXT = "mlclaw-local-access-v1";
+function deriveLocalAccessToken(sessionSecret) {
+ return createHmac("sha256", sessionSecret).update(LOCAL_ACCESS_CONTEXT).digest("base64url");
+}
+function localAccessTokenMatches(candidate, expected) {
+ const left = Buffer.from(candidate);
+ const right = Buffer.from(expected);
+ return left.length === right.length && timingSafeEqual(left, right);
+}
+
+// src/mlclaw-space-runtime/config.ts
+function loadConfig(env = process.env) {
+ const port = integer(env.PORT ?? env.MLCLAW_SPACE_PORT, 7860);
+ const openclawPort = integer(env.MLCLAW_OPENCLAW_PORT ?? env.OPENCLAW_GATEWAY_PORT, 7861);
+ const mcpPort = integer(env.MLCLAW_MCP_PORT, 7862);
+ const spaceId = trim(env.SPACE_ID);
+ const canonicalSpaceId = trim(env.MLCLAW_CANONICAL_SPACE_ID) ?? "osolmaz/mlclaw";
+ const canonicalCreatorUserId = trim(env.MLCLAW_CANONICAL_CREATOR_USER_ID);
+ const spaceCreatorUserId = trim(env.SPACE_CREATOR_USER_ID);
+ const mode = resolveMode({
+ env,
+ spaceId,
+ canonicalSpaceId,
+ canonicalCreatorUserId,
+ spaceCreatorUserId
+ });
+ const owner = ownerFromSpaceId(spaceId);
+ const stateBucket = trim(env.OPENCLAW_HF_STATE_BUCKET);
+ const gatewayLocation = trim(env.MLCLAW_GATEWAY_LOCATION);
+ const localAccessUser = gatewayLocation === "local" ? trim(env.MLCLAW_LOCAL_ACCESS_USER) ?? ownerFromRepoId(stateBucket) : void 0;
+ const configuredAllowedUsers = splitUsers(env.MLCLAW_ALLOWED_USERS ?? env.ALLOWED_USERS);
+ const configuredAdmins = splitUsers(env.MLCLAW_ADMINS);
+ const resolvedAdmins = uniqueUsers([
+ ...configuredAdmins.length > 0 ? configuredAdmins : owner ? [owner] : configuredAllowedUsers.slice(0, 1),
+ ...localAccessUser ? [localAccessUser] : []
+ ]);
+ const allowedUsers = uniqueUsers([...configuredAllowedUsers, ...resolvedAdmins, ...owner ? [owner] : []]);
+ const publicUrl = publicUrlFromEnv(env, port);
+ const accessOrigins = accessOriginsFromEnv(env, publicUrl);
+ const sessionSecret = trim(env.MLCLAW_SESSION_SECRET ?? env.SESSION_SECRET) ?? randomBytes(48).toString("base64url");
+ const configuredCredentialKey = trim(env.MLCLAW_CREDENTIAL_KEY);
+ if (mode === "app" && !configuredCredentialKey) {
+ throw new Error("MLCLAW_CREDENTIAL_KEY is required in app mode; run mlclaw doctor --fix");
+ }
+ const credentialKey = configuredCredentialKey ?? randomBytes(32).toString("base64url");
+ const openclawCommand = trim(env.MLCLAW_OPENCLAW_COMMAND) ?? "openclaw";
+ const openclawArgs = splitArgs(env.MLCLAW_OPENCLAW_ARGS) ?? ["gateway"];
+ const runtimeSettingsFile = trim(env.MLCLAW_RUNTIME_SETTINGS_FILE) ?? "/home/node/.local/share/mlclaw/live/.mlclaw/settings.json";
+ const stateMountDir = trim(env.MLCLAW_STATE_MOUNT_DIR);
+ const statePrefix = trim(env.OPENCLAW_HF_STATE_PREFIX);
+ const mcpCredentialFile = trim(env.MLCLAW_MCP_CREDENTIAL_FILE) ?? (stateMountDir ? `${stateMountDir.replace(/\/+$/, "")}/${normalizeBucketPrefix(statePrefix)}/.mlclaw/mcp-oauth.enc` : `${pathDirname(runtimeSettingsFile)}/mcp-oauth.enc`);
+ const openaiCredentialStoreFile = trim(env.MLCLAW_OPENAI_CREDENTIAL_STORE_FILE) ?? (stateMountDir ? `${stateMountDir.replace(/\/+$/, "")}/${normalizeBucketPrefix(statePrefix)}/.mlclaw/openai-api-key.enc` : `${pathDirname(pathDirname(runtimeSettingsFile))}/.mlclaw-protected/control/openai-api-key.enc`);
+ const runtimeSettings2 = readRuntimeSettings(runtimeSettingsFile);
+ const model = runtimeSettings2.model ?? trim(env.OPENCLAW_MODEL) ?? DEFAULT_MODEL;
+ const agentName = trim(env.OPENCLAW_AGENT_NAME);
+ return {
+ port,
+ openclawPort,
+ mcpPort,
+ openclawHost: trim(env.MLCLAW_OPENCLAW_HOST) ?? "127.0.0.1",
+ openclawUid: integer(env.MLCLAW_OPENCLAW_UID, 1e3),
+ openclawGid: integer(env.MLCLAW_OPENCLAW_GID, 1e3),
+ publicUrl,
+ accessOrigins,
+ providerUrl: trim(env.OPENID_PROVIDER_URL) ?? "https://huggingface.co",
+ oauthClientId: trim(env.OAUTH_CLIENT_ID),
+ oauthClientSecret: trim(env.OAUTH_CLIENT_SECRET),
+ sessionSecret,
+ sessionSecretGenerated: !trim(env.MLCLAW_SESSION_SECRET ?? env.SESSION_SECRET),
+ credentialKey,
+ credentialKeyGenerated: !configuredCredentialKey,
+ cookieSecure: env.MLCLAW_COOKIE_SECURE === "0" ? false : !publicUrl.startsWith("http://"),
+ sessionCookieName: gatewayLocation === "local" ? localSessionCookieName(trim(env.MLCLAW_RUNTIME_ID) ?? publicUrl) : SESSION_COOKIE_PREFIX,
+ spaceId,
+ canonicalSpaceId,
+ canonicalCreatorUserId,
+ spaceCreatorUserId,
+ allowedUsers,
+ adminUsers: resolvedAdmins,
+ allowAnySignedIn: env.MLCLAW_ALLOW_ANY_SIGNED_IN === "1" || env.MLCLAW_ALLOW_ANY_SIGNED_IN === "true",
+ localAccessUser,
+ localAccessToken: gatewayLocation === "local" && localAccessUser ? deriveLocalAccessToken(sessionSecret) : void 0,
+ mode,
+ hfToken: readOptionalSecret(trim(env.MLCLAW_TRUSTED_HF_TOKEN_FILE)) ?? trim(env.HF_TOKEN ?? env.HUGGINGFACE_HUB_TOKEN),
+ routerToken: trim(env.MLCLAW_ROUTER_TOKEN ?? env.HF_ROUTER_TOKEN),
+ brokerAgentUrl: trim(env.MLCLAW_HF_BROKER_URL),
+ brokerAgentSecret: readOptionalSecret(trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE)),
+ brokerAgentSecretFile: trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE),
+ operatorBrokers: loadOperatorBrokers(trim(env.MLCLAW_OPERATOR_BROKERS_FILE)),
+ brokerKitPopoverDecisions: env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "0" && env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "false",
+ hubUrl: trim(env.HF_ENDPOINT) ?? "https://huggingface.co",
+ openaiCredentialFile: trim(env.MLCLAW_OPENAI_CREDENTIAL_FILE) ?? "/tmp/mlclaw-secrets/openai.env",
+ openaiCredentialStoreFile,
+ mcpCredentialFile,
+ hfMcpUrl: trim(env.MLCLAW_HF_MCP_URL) ?? "https://huggingface.co/mcp?bouquet=hf",
+ researchMcpUrl: trim(env.MLCLAW_RESEARCH_MCP_URL) ?? "https://evalstate-research-agent-two.hf.space/mcp",
+ researchTimeoutMs: integer(env.MLCLAW_RESEARCH_TIMEOUT_MS, 30 * 60 * 1e3),
+ researchPollMs: integer(env.MLCLAW_RESEARCH_POLL_MS, 1500),
+ runtimeSettingsFile,
+ openclawConfigPath: trim(env.OPENCLAW_CONFIG_PATH) ?? "/home/node/.local/share/mlclaw/live/.openclaw/openclaw.json",
+ openclawCommand,
+ openclawArgs,
+ brokerKitPluginPath: trim(env.MLCLAW_BROKERKIT_PLUGIN_PATH) ?? "/opt/openclaw-plugins/node_modules/openclaw-brokerkit",
+ agentName,
+ model,
+ modelChoices: runtimeSettings2.modelChoices ?? parseModelChoicesEnv(env.MLCLAW_MODEL_CHOICES, model),
+ routerModelsUrl: trim(env.MLCLAW_ROUTER_MODELS_URL) ?? "https://router.huggingface.co/v1/models",
+ stateBucket,
+ stateMountDir,
+ statePrefix,
+ gatewayLocation,
+ runtimeImage: trim(env.MLCLAW_RUNTIME_IMAGE),
+ runtimeId: trim(env.MLCLAW_RUNTIME_ID),
+ templateRev: trim(env.MLCLAW_TEMPLATE_REV),
+ assetsDir: trim(env.MLCLAW_ASSETS_DIR) ?? "/app/assets",
+ branding: resolveBranding(env, agentName)
+ };
+}
+var SESSION_COOKIE_PREFIX = "mlclaw_session";
+function localSessionCookieName(identity) {
+ return `${SESSION_COOKIE_PREFIX}_${createHash("sha256").update(identity).digest("hex").slice(0, 12)}`;
+}
+function accessOriginsFromEnv(env, publicUrl) {
+ const configured = (env.MLCLAW_ACCESS_ORIGINS ?? "").split(",").map((value) => value.trim()).filter(Boolean);
+ if (configured.length > 8) {
+ throw new Error("MLCLAW_ACCESS_ORIGINS supports at most 8 origins");
+ }
+ const origins = [.../* @__PURE__ */ new Set([publicUrl, ...configured.map(parseAccessOrigin)])];
+ if (origins.length > 8) {
+ throw new Error("MLCLAW_ACCESS_ORIGINS supports at most 8 origins including MLCLAW_PUBLIC_URL");
+ }
+ return origins;
+}
+function parseAccessOrigin(value) {
+ const url = new URL(value);
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.hostname.includes("*") || url.pathname !== "/" || url.search || url.hash) {
+ throw new Error(
+ "MLCLAW_ACCESS_ORIGINS entries must be HTTP origins without credentials, wildcard hosts, paths, queries, or fragments"
+ );
+ }
+ return url.origin;
+}
+function readOptionalSecret(file) {
+ if (!file) {
+ return void 0;
+ }
+ try {
+ return trim(readFileSync2(file, "utf8"));
+ } catch {
+ return void 0;
+ }
+}
+function integrationCredentialSlot(config2) {
+ return config2.adminUsers[0];
+}
+function pathDirname(file) {
+ const slash = file.lastIndexOf("/");
+ return slash > 0 ? file.slice(0, slash) : ".";
+}
+function resolveMode(params) {
+ if (params.env.MLCLAW_FORCE_TEMPLATE === "1") {
+ return "template";
+ }
+ if (params.env.MLCLAW_FORCE_APP === "1") {
+ return "app";
+ }
+ const isCanonicalSpace = Boolean(params.spaceId && params.spaceId === params.canonicalSpaceId);
+ if (!isCanonicalSpace) {
+ return "app";
+ }
+ if (!params.canonicalCreatorUserId || !params.spaceCreatorUserId) {
+ return "template";
+ }
+ return params.canonicalCreatorUserId === params.spaceCreatorUserId ? "template" : "app";
+}
+function publicUrlFromEnv(env, port) {
+ const explicit = trim(env.MLCLAW_PUBLIC_URL);
+ if (explicit) {
+ const url = new URL(explicit);
+ if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
+ throw new Error("MLCLAW_PUBLIC_URL must be one HTTP origin without credentials, path, query, or fragment");
}
- const status = new ParseStatus();
- let ctx = void 0;
- for (const check of this._def.checks) {
- if (check.kind === "min") {
- if (input.data.length < check.value) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: check.value,
- type: "string",
- inclusive: true,
- exact: false,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "max") {
- if (input.data.length > check.value) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: check.value,
- type: "string",
- inclusive: true,
- exact: false,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "length") {
- const tooBig = input.data.length > check.value;
- const tooSmall = input.data.length < check.value;
- if (tooBig || tooSmall) {
- ctx = this._getOrReturnCtx(input, ctx);
- if (tooBig) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: check.value,
- type: "string",
- inclusive: true,
- exact: true,
- message: check.message
- });
- } else if (tooSmall) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: check.value,
- type: "string",
- inclusive: true,
- exact: true,
- message: check.message
- });
- }
- status.dirty();
- }
- } else if (check.kind === "email") {
- if (!emailRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "email",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "emoji") {
- if (!emojiRegex) {
- emojiRegex = new RegExp(_emojiRegex, "u");
- }
- if (!emojiRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "emoji",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "uuid") {
- if (!uuidRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "uuid",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "nanoid") {
- if (!nanoidRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "nanoid",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "cuid") {
- if (!cuidRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "cuid",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "cuid2") {
- if (!cuid2Regex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "cuid2",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "ulid") {
- if (!ulidRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "ulid",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "url") {
+ return url.origin;
+ }
+ const host = trim(env.SPACE_HOST);
+ if (host) {
+ return host.startsWith("http") ? host.replace(/\/+$/, "") : `https://${host.replace(/\/+$/, "")}`;
+ }
+ return `http://127.0.0.1:${port}`;
+}
+function ownerFromSpaceId(spaceId) {
+ return ownerFromRepoId(spaceId);
+}
+function ownerFromRepoId(repoId) {
+ const owner = repoId?.split("/")[0]?.trim();
+ return owner || void 0;
+}
+function integer(value, fallback) {
+ if (!value) {
+ return fallback;
+ }
+ const parsed = Number.parseInt(value, 10);
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
+}
+function splitUsers(value) {
+ return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
+}
+function uniqueUsers(users) {
+ return [...new Set(users)];
+}
+function splitArgs(value) {
+ const trimmed = trim(value);
+ return trimmed ? trimmed.split(/\s+/).filter(Boolean) : void 0;
+}
+function trim(value) {
+ const trimmed = value?.trim();
+ return trimmed || void 0;
+}
+function readRuntimeSettings(file) {
+ try {
+ const parsed = JSON.parse(readFileSync2(file, "utf8"));
+ const model = typeof parsed.model === "string" ? parsed.model.trim() : void 0;
+ if (!model) {
+ return {};
+ }
+ const modelChoices = normalizeModelChoices(parsed.modelChoices, model);
+ return {
+ model,
+ ...modelChoices ? { modelChoices } : {}
+ };
+ } catch {
+ return {};
+ }
+}
+
+// src/mlclaw-space-runtime/server.ts
+import { spawn } from "node:child_process";
+import http3 from "node:http";
+import { Readable as Readable2 } from "node:stream";
+
+// src/mlclaw-space-runtime/app.ts
+import fs3 from "node:fs/promises";
+import path3 from "node:path";
+
+// node_modules/hono/dist/compose.js
+var compose = (middleware, onError, onNotFound) => {
+ return (context, next) => {
+ let index = -1;
+ return dispatch(0);
+ async function dispatch(i) {
+ if (i <= index) {
+ throw new Error("next() called multiple times");
+ }
+ index = i;
+ let res;
+ let isError = false;
+ let handler;
+ if (middleware[i]) {
+ handler = middleware[i][0][0];
+ context.req.routeIndex = i;
+ } else {
+ handler = i === middleware.length && next || void 0;
+ }
+ if (handler) {
try {
- new URL(input.data);
- } catch {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "url",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "regex") {
- check.regex.lastIndex = 0;
- const testResult = check.regex.test(input.data);
- if (!testResult) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "regex",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "trim") {
- input.data = input.data.trim();
- } else if (check.kind === "includes") {
- if (!input.data.includes(check.value, check.position)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: { includes: check.value, position: check.position },
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "toLowerCase") {
- input.data = input.data.toLowerCase();
- } else if (check.kind === "toUpperCase") {
- input.data = input.data.toUpperCase();
- } else if (check.kind === "startsWith") {
- if (!input.data.startsWith(check.value)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: { startsWith: check.value },
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "endsWith") {
- if (!input.data.endsWith(check.value)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: { endsWith: check.value },
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "datetime") {
- const regex = datetimeRegex(check);
- if (!regex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: "datetime",
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "date") {
- const regex = dateRegex;
- if (!regex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: "date",
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "time") {
- const regex = timeRegex(check);
- if (!regex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_string,
- validation: "time",
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "duration") {
- if (!durationRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "duration",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "ip") {
- if (!isValidIP(input.data, check.version)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "ip",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "jwt") {
- if (!isValidJWT(input.data, check.alg)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "jwt",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "cidr") {
- if (!isValidCidr(input.data, check.version)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "cidr",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "base64") {
- if (!base64Regex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "base64",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "base64url") {
- if (!base64urlRegex.test(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- validation: "base64url",
- code: ZodIssueCode.invalid_string,
- message: check.message
- });
- status.dirty();
+ res = await handler(context, () => dispatch(i + 1));
+ } catch (err) {
+ if (err instanceof Error && onError) {
+ context.error = err;
+ res = await onError(err, context);
+ isError = true;
+ } else {
+ throw err;
+ }
}
} else {
- util.assertNever(check);
+ if (context.finalized === false && onNotFound) {
+ res = await onNotFound(context);
+ }
+ }
+ if (res && (context.finalized === false || isError)) {
+ context.res = res;
}
+ return context;
+ }
+ };
+};
+
+// node_modules/hono/dist/request/constants.js
+var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
+
+// node_modules/hono/dist/utils/buffer.js
+var bufferToFormData = (arrayBuffer, contentType2) => {
+ const response = new Response(arrayBuffer, {
+ headers: {
+ // Normalize the media type (case-insensitive) while keeping parameters like the boundary
+ "Content-Type": contentType2.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
}
- return { status: status.value, value: input.data };
- }
- _regex(regex, validation, message) {
- return this.refinement((data) => regex.test(data), {
- validation,
- code: ZodIssueCode.invalid_string,
- ...errorUtil.errToObj(message)
- });
- }
- _addCheck(check) {
- return new _ZodString({
- ...this._def,
- checks: [...this._def.checks, check]
- });
- }
- email(message) {
- return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });
- }
- url(message) {
- return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });
- }
- emoji(message) {
- return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });
- }
- uuid(message) {
- return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });
- }
- nanoid(message) {
- return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) });
- }
- cuid(message) {
- return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });
- }
- cuid2(message) {
- return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });
- }
- ulid(message) {
- return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });
- }
- base64(message) {
- return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
- }
- base64url(message) {
- return this._addCheck({
- kind: "base64url",
- ...errorUtil.errToObj(message)
- });
- }
- jwt(options) {
- return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });
+ });
+ return response.formData();
+};
+
+// node_modules/hono/dist/utils/body.js
+var isRawRequest = (request) => "headers" in request;
+var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
+ const { all = false, dot = false } = options;
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
+ const contentType2 = headers.get("Content-Type");
+ const mediaType = contentType2?.split(";")[0].trim().toLowerCase();
+ if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
+ return parseFormData(request, { all, dot });
}
- ip(options) {
- return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
+ return {};
+};
+async function parseFormData(request, options) {
+ const headers = isRawRequest(request) ? request.headers : request.raw.headers;
+ const arrayBuffer = await request.arrayBuffer();
+ const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
+ if (!isRawRequest(request)) {
+ request.bodyCache.formData = formDataPromise;
}
- cidr(options) {
- return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
+ const formData = await formDataPromise;
+ if (formData) {
+ return convertFormDataToBodyData(formData, options);
}
- datetime(options) {
- if (typeof options === "string") {
- return this._addCheck({
- kind: "datetime",
- precision: null,
- offset: false,
- local: false,
- message: options
- });
+ return {};
+}
+function convertFormDataToBodyData(formData, options) {
+ const form = /* @__PURE__ */ Object.create(null);
+ formData.forEach((value, key) => {
+ const shouldParseAllValues = options.all || key.endsWith("[]");
+ if (!shouldParseAllValues) {
+ form[key] = value;
+ } else {
+ handleParsingAllValues(form, key, value);
}
- return this._addCheck({
- kind: "datetime",
- precision: typeof options?.precision === "undefined" ? null : options?.precision,
- offset: options?.offset ?? false,
- local: options?.local ?? false,
- ...errorUtil.errToObj(options?.message)
+ });
+ if (options.dot) {
+ Object.entries(form).forEach(([key, value]) => {
+ const shouldParseDotValues = key.includes(".");
+ if (shouldParseDotValues) {
+ handleParsingNestedValues(form, key, value);
+ delete form[key];
+ }
});
}
- date(message) {
- return this._addCheck({ kind: "date", message });
- }
- time(options) {
- if (typeof options === "string") {
- return this._addCheck({
- kind: "time",
- precision: null,
- message: options
- });
+ return form;
+}
+var handleParsingAllValues = (form, key, value) => {
+ if (form[key] !== void 0) {
+ if (Array.isArray(form[key])) {
+ ;
+ form[key].push(value);
+ } else {
+ form[key] = [form[key], value];
+ }
+ } else {
+ if (!key.endsWith("[]")) {
+ form[key] = value;
+ } else {
+ form[key] = [value];
}
- return this._addCheck({
- kind: "time",
- precision: typeof options?.precision === "undefined" ? null : options?.precision,
- ...errorUtil.errToObj(options?.message)
- });
- }
- duration(message) {
- return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) });
- }
- regex(regex, message) {
- return this._addCheck({
- kind: "regex",
- regex,
- ...errorUtil.errToObj(message)
- });
- }
- includes(value, options) {
- return this._addCheck({
- kind: "includes",
- value,
- position: options?.position,
- ...errorUtil.errToObj(options?.message)
- });
- }
- startsWith(value, message) {
- return this._addCheck({
- kind: "startsWith",
- value,
- ...errorUtil.errToObj(message)
- });
- }
- endsWith(value, message) {
- return this._addCheck({
- kind: "endsWith",
- value,
- ...errorUtil.errToObj(message)
- });
- }
- min(minLength, message) {
- return this._addCheck({
- kind: "min",
- value: minLength,
- ...errorUtil.errToObj(message)
- });
- }
- max(maxLength, message) {
- return this._addCheck({
- kind: "max",
- value: maxLength,
- ...errorUtil.errToObj(message)
- });
- }
- length(len, message) {
- return this._addCheck({
- kind: "length",
- value: len,
- ...errorUtil.errToObj(message)
- });
- }
- /**
- * Equivalent to `.min(1)`
- */
- nonempty(message) {
- return this.min(1, errorUtil.errToObj(message));
}
- trim() {
- return new _ZodString({
- ...this._def,
- checks: [...this._def.checks, { kind: "trim" }]
- });
+};
+var handleParsingNestedValues = (form, key, value) => {
+ if (/(?:^|\.)__proto__\./.test(key)) {
+ return;
}
- toLowerCase() {
- return new _ZodString({
- ...this._def,
- checks: [...this._def.checks, { kind: "toLowerCase" }]
- });
+ let nestedForm = form;
+ const keys = key.split(".");
+ keys.forEach((key2, index) => {
+ if (index === keys.length - 1) {
+ nestedForm[key2] = value;
+ } else {
+ if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {
+ nestedForm[key2] = /* @__PURE__ */ Object.create(null);
+ }
+ nestedForm = nestedForm[key2];
+ }
+ });
+};
+
+// node_modules/hono/dist/utils/url.js
+var splitPath = (path5) => {
+ const paths = path5.split("/");
+ if (paths[0] === "") {
+ paths.shift();
}
- toUpperCase() {
- return new _ZodString({
- ...this._def,
- checks: [...this._def.checks, { kind: "toUpperCase" }]
- });
+ return paths;
+};
+var splitRoutingPath = (routePath) => {
+ const { groups, path: path5 } = extractGroupsFromPath(routePath);
+ const paths = splitPath(path5);
+ return replaceGroupMarks(paths, groups);
+};
+var extractGroupsFromPath = (path5) => {
+ const groups = [];
+ path5 = path5.replace(/\{[^}]+\}/g, (match2, index) => {
+ const mark = `@${index}`;
+ groups.push([mark, match2]);
+ return mark;
+ });
+ return { groups, path: path5 };
+};
+var replaceGroupMarks = (paths, groups) => {
+ for (let i = groups.length - 1; i >= 0; i--) {
+ const [mark] = groups[i];
+ for (let j = paths.length - 1; j >= 0; j--) {
+ if (paths[j].includes(mark)) {
+ paths[j] = paths[j].replace(mark, groups[i][1]);
+ break;
+ }
+ }
}
- get isDatetime() {
- return !!this._def.checks.find((ch) => ch.kind === "datetime");
+ return paths;
+};
+var patternCache = {};
+var getPattern = (label, next) => {
+ if (label === "*") {
+ return "*";
}
- get isDate() {
- return !!this._def.checks.find((ch) => ch.kind === "date");
+ const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
+ if (match2) {
+ const cacheKey = `${label}#${next}`;
+ if (!patternCache[cacheKey]) {
+ if (match2[2]) {
+ patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
+ } else {
+ patternCache[cacheKey] = [label, match2[1], true];
+ }
+ }
+ return patternCache[cacheKey];
}
- get isTime() {
- return !!this._def.checks.find((ch) => ch.kind === "time");
+ return null;
+};
+var tryDecode = (str, decoder) => {
+ try {
+ return decoder(str);
+ } catch {
+ return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
+ try {
+ return decoder(match2);
+ } catch {
+ return match2;
+ }
+ });
}
- get isDuration() {
- return !!this._def.checks.find((ch) => ch.kind === "duration");
+};
+var tryDecodeURI = (str) => tryDecode(str, decodeURI);
+var getPath = (request) => {
+ const url = request.url;
+ const start = url.indexOf("/", url.indexOf(":") + 4);
+ let i = start;
+ for (; i < url.length; i++) {
+ const charCode = url.charCodeAt(i);
+ if (charCode === 37) {
+ const queryIndex = url.indexOf("?", i);
+ const hashIndex = url.indexOf("#", i);
+ const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
+ const path5 = url.slice(start, end);
+ return tryDecodeURI(path5.includes("%25") ? path5.replace(/%25/g, "%2525") : path5);
+ } else if (charCode === 63 || charCode === 35) {
+ break;
+ }
}
- get isEmail() {
- return !!this._def.checks.find((ch) => ch.kind === "email");
+ return url.slice(start, i);
+};
+var getPathNoStrict = (request) => {
+ const result = getPath(request);
+ return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
+};
+var mergePath = (base, sub, ...rest) => {
+ if (rest.length) {
+ sub = mergePath(sub, ...rest);
}
- get isURL() {
- return !!this._def.checks.find((ch) => ch.kind === "url");
+ return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
+};
+var checkOptionalParameter = (path5) => {
+ if (path5.charCodeAt(path5.length - 1) !== 63 || !path5.includes(":")) {
+ return null;
}
- get isEmoji() {
- return !!this._def.checks.find((ch) => ch.kind === "emoji");
+ const segments = path5.split("/");
+ const results = [];
+ let basePath = "";
+ segments.forEach((segment) => {
+ if (segment !== "" && !/\:/.test(segment)) {
+ basePath += "/" + segment;
+ } else if (/\:/.test(segment)) {
+ if (/\?/.test(segment)) {
+ if (results.length === 0 && basePath === "") {
+ results.push("/");
+ } else {
+ results.push(basePath);
+ }
+ const optionalSegment = segment.replace("?", "");
+ basePath += "/" + optionalSegment;
+ results.push(basePath);
+ } else {
+ basePath += "/" + segment;
+ }
+ }
+ });
+ return results.filter((v, i, a) => a.indexOf(v) === i);
+};
+var _decodeURI = (value) => {
+ if (!/[%+]/.test(value)) {
+ return value;
}
- get isUUID() {
- return !!this._def.checks.find((ch) => ch.kind === "uuid");
+ if (value.indexOf("+") !== -1) {
+ value = value.replace(/\+/g, " ");
}
- get isNANOID() {
- return !!this._def.checks.find((ch) => ch.kind === "nanoid");
+ return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
+};
+var _getQueryParam = (url, key, multiple) => {
+ let encoded;
+ if (!multiple && key && !/[%+]/.test(key)) {
+ let keyIndex2 = url.indexOf("?", 8);
+ if (keyIndex2 === -1) {
+ return void 0;
+ }
+ if (!url.startsWith(key, keyIndex2 + 1)) {
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
+ }
+ while (keyIndex2 !== -1) {
+ const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
+ if (trailingKeyCode === 61) {
+ const valueIndex = keyIndex2 + key.length + 2;
+ const endIndex = url.indexOf("&", valueIndex);
+ return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
+ } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
+ return "";
+ }
+ keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
+ }
+ encoded = /[%+]/.test(url);
+ if (!encoded) {
+ return void 0;
+ }
}
- get isCUID() {
- return !!this._def.checks.find((ch) => ch.kind === "cuid");
+ const results = {};
+ encoded ??= /[%+]/.test(url);
+ let keyIndex = url.indexOf("?", 8);
+ while (keyIndex !== -1) {
+ const nextKeyIndex = url.indexOf("&", keyIndex + 1);
+ let valueIndex = url.indexOf("=", keyIndex);
+ if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
+ valueIndex = -1;
+ }
+ let name = url.slice(
+ keyIndex + 1,
+ valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex
+ );
+ if (encoded) {
+ name = _decodeURI(name);
+ }
+ keyIndex = nextKeyIndex;
+ if (name === "") {
+ continue;
+ }
+ let value;
+ if (valueIndex === -1) {
+ value = "";
+ } else {
+ value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
+ if (encoded) {
+ value = _decodeURI(value);
+ }
+ }
+ if (multiple) {
+ if (!(results[name] && Array.isArray(results[name]))) {
+ results[name] = [];
+ }
+ ;
+ results[name].push(value);
+ } else {
+ results[name] ??= value;
+ }
}
- get isCUID2() {
- return !!this._def.checks.find((ch) => ch.kind === "cuid2");
+ return key ? results[key] : results;
+};
+var getQueryParam = _getQueryParam;
+var getQueryParams = (url, key) => {
+ return _getQueryParam(url, key, true);
+};
+var decodeURIComponent_ = decodeURIComponent;
+
+// node_modules/hono/dist/request.js
+var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
+var HonoRequest = class {
+ /**
+ * `.raw` can get the raw Request object.
+ *
+ * @see {@link https://hono.dev/docs/api/request#raw}
+ *
+ * @example
+ * ```ts
+ * // For Cloudflare Workers
+ * app.post('/', async (c) => {
+ * const metadata = c.req.raw.cf?.hostMetadata?
+ * ...
+ * })
+ * ```
+ */
+ raw;
+ #validatedData;
+ // Short name of validatedData
+ #matchResult;
+ routeIndex = 0;
+ /**
+ * `.path` can get the pathname of the request.
+ *
+ * @see {@link https://hono.dev/docs/api/request#path}
+ *
+ * @example
+ * ```ts
+ * app.get('/about/me', (c) => {
+ * const pathname = c.req.path // `/about/me`
+ * })
+ * ```
+ */
+ path;
+ bodyCache = {};
+ constructor(request, path5 = "/", matchResult = [[]]) {
+ this.raw = request;
+ this.path = path5;
+ this.#matchResult = matchResult;
+ this.#validatedData = {};
}
- get isULID() {
- return !!this._def.checks.find((ch) => ch.kind === "ulid");
+ param(key) {
+ return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
}
- get isIP() {
- return !!this._def.checks.find((ch) => ch.kind === "ip");
+ #getDecodedParam(key) {
+ const paramKey = this.#matchResult[0][this.routeIndex][1][key];
+ const param = this.#getParamValue(paramKey);
+ return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
}
- get isCIDR() {
- return !!this._def.checks.find((ch) => ch.kind === "cidr");
+ #getAllDecodedParams() {
+ const decoded = {};
+ const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
+ for (const key of keys) {
+ const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
+ if (value !== void 0) {
+ decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
+ }
+ }
+ return decoded;
}
- get isBase64() {
- return !!this._def.checks.find((ch) => ch.kind === "base64");
+ #getParamValue(paramKey) {
+ return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
}
- get isBase64url() {
- return !!this._def.checks.find((ch) => ch.kind === "base64url");
+ query(key) {
+ return getQueryParam(this.url, key);
}
- get minLength() {
- let min = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "min") {
- if (min === null || ch.value > min)
- min = ch.value;
- }
- }
- return min;
+ queries(key) {
+ return getQueryParams(this.url, key);
}
- get maxLength() {
- let max = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "max") {
- if (max === null || ch.value < max)
- max = ch.value;
- }
+ header(name) {
+ if (name) {
+ return this.raw.headers.get(name) ?? void 0;
}
- return max;
+ const headerData = {};
+ this.raw.headers.forEach((value, key) => {
+ headerData[key] = value;
+ });
+ return headerData;
}
-};
-ZodString.create = (params) => {
- return new ZodString({
- checks: [],
- typeName: ZodFirstPartyTypeKind.ZodString,
- coerce: params?.coerce ?? false,
- ...processCreateParams(params)
- });
-};
-function floatSafeRemainder(val, step) {
- const valDecCount = (val.toString().split(".")[1] || "").length;
- const stepDecCount = (step.toString().split(".")[1] || "").length;
- const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
- const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
- const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
- return valInt % stepInt / 10 ** decCount;
-}
-var ZodNumber = class _ZodNumber extends ZodType {
- constructor() {
- super(...arguments);
- this.min = this.gte;
- this.max = this.lte;
- this.step = this.multipleOf;
+ async parseBody(options) {
+ return parseBody(this, options);
}
- _parse(input) {
- if (this._def.coerce) {
- input.data = Number(input.data);
- }
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.number) {
- const ctx2 = this._getOrReturnCtx(input);
- addIssueToContext(ctx2, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.number,
- received: ctx2.parsedType
- });
- return INVALID;
+ #cachedBody = (key) => {
+ const { bodyCache, raw: raw2 } = this;
+ const cachedBody = bodyCache[key];
+ if (cachedBody) {
+ return cachedBody;
}
- let ctx = void 0;
- const status = new ParseStatus();
- for (const check of this._def.checks) {
- if (check.kind === "int") {
- if (!util.isInteger(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: "integer",
- received: "float",
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "min") {
- const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
- if (tooSmall) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: check.value,
- type: "number",
- inclusive: check.inclusive,
- exact: false,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "max") {
- const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
- if (tooBig) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: check.value,
- type: "number",
- inclusive: check.inclusive,
- exact: false,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "multipleOf") {
- if (floatSafeRemainder(input.data, check.value) !== 0) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.not_multiple_of,
- multipleOf: check.value,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "finite") {
- if (!Number.isFinite(input.data)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.not_finite,
- message: check.message
- });
- status.dirty();
+ const anyCachedKey = Object.keys(bodyCache)[0];
+ if (anyCachedKey) {
+ return bodyCache[anyCachedKey].then((body) => {
+ if (anyCachedKey === "json") {
+ body = JSON.stringify(body);
}
- } else {
- util.assertNever(check);
- }
+ return new Response(body)[key]();
+ });
}
- return { status: status.value, value: input.data };
+ return bodyCache[key] = raw2[key]();
+ };
+ /**
+ * `.json()` can parse Request body of type `application/json`
+ *
+ * @see {@link https://hono.dev/docs/api/request#json}
+ *
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.json()
+ * })
+ * ```
+ */
+ json() {
+ return this.#cachedBody("text").then((text) => JSON.parse(text));
}
- gte(value, message) {
- return this.setLimit("min", value, true, errorUtil.toString(message));
+ /**
+ * `.text()` can parse Request body of type `text/plain`
+ *
+ * @see {@link https://hono.dev/docs/api/request#text}
+ *
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.text()
+ * })
+ * ```
+ */
+ text() {
+ return this.#cachedBody("text");
}
- gt(value, message) {
- return this.setLimit("min", value, false, errorUtil.toString(message));
+ /**
+ * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
+ *
+ * @see {@link https://hono.dev/docs/api/request#arraybuffer}
+ *
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.arrayBuffer()
+ * })
+ * ```
+ */
+ arrayBuffer() {
+ return this.#cachedBody("arrayBuffer");
}
- lte(value, message) {
- return this.setLimit("max", value, true, errorUtil.toString(message));
+ /**
+ * `.bytes()` parses the request body as a `Uint8Array`.
+ *
+ * @see {@link https://hono.dev/docs/api/request#bytes}
+ *
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.bytes()
+ * })
+ * ```
+ */
+ bytes() {
+ return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
}
- lt(value, message) {
- return this.setLimit("max", value, false, errorUtil.toString(message));
+ /**
+ * Parses the request body as a `Blob`.
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.blob();
+ * });
+ * ```
+ * @see https://hono.dev/docs/api/request#blob
+ */
+ blob() {
+ return this.#cachedBody("blob");
}
- setLimit(kind, value, inclusive, message) {
- return new _ZodNumber({
- ...this._def,
- checks: [
- ...this._def.checks,
- {
- kind,
- value,
- inclusive,
- message: errorUtil.toString(message)
- }
- ]
- });
+ /**
+ * Parses the request body as `FormData`.
+ * @example
+ * ```ts
+ * app.post('/entry', async (c) => {
+ * const body = await c.req.formData();
+ * });
+ * ```
+ * @see https://hono.dev/docs/api/request#formdata
+ */
+ formData() {
+ return this.#cachedBody("formData");
+ }
+ /**
+ * Adds validated data to the request.
+ *
+ * @param target - The target of the validation.
+ * @param data - The validated data to add.
+ */
+ addValidatedData(target, data) {
+ this.#validatedData[target] = data;
}
- _addCheck(check) {
- return new _ZodNumber({
- ...this._def,
- checks: [...this._def.checks, check]
- });
+ valid(target) {
+ return this.#validatedData[target];
}
- int(message) {
- return this._addCheck({
- kind: "int",
- message: errorUtil.toString(message)
- });
+ /**
+ * `.url()` can get the request url strings.
+ *
+ * @see {@link https://hono.dev/docs/api/request#url}
+ *
+ * @example
+ * ```ts
+ * app.get('/about/me', (c) => {
+ * const url = c.req.url // `http://localhost:8787/about/me`
+ * ...
+ * })
+ * ```
+ */
+ get url() {
+ return this.raw.url;
}
- positive(message) {
- return this._addCheck({
- kind: "min",
- value: 0,
- inclusive: false,
- message: errorUtil.toString(message)
- });
+ /**
+ * `.method()` can get the method name of the request.
+ *
+ * @see {@link https://hono.dev/docs/api/request#method}
+ *
+ * @example
+ * ```ts
+ * app.get('/about/me', (c) => {
+ * const method = c.req.method // `GET`
+ * })
+ * ```
+ */
+ get method() {
+ return this.raw.method;
}
- negative(message) {
- return this._addCheck({
- kind: "max",
- value: 0,
- inclusive: false,
- message: errorUtil.toString(message)
- });
+ get [GET_MATCH_RESULT]() {
+ return this.#matchResult;
}
- nonpositive(message) {
- return this._addCheck({
- kind: "max",
- value: 0,
- inclusive: true,
- message: errorUtil.toString(message)
- });
+ /**
+ * `.matchedRoutes()` can return a matched route in the handler
+ *
+ * @deprecated
+ *
+ * Use matchedRoutes helper defined in "hono/route" instead.
+ *
+ * @see {@link https://hono.dev/docs/api/request#matchedroutes}
+ *
+ * @example
+ * ```ts
+ * app.use('*', async function logger(c, next) {
+ * await next()
+ * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
+ * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
+ * console.log(
+ * method,
+ * ' ',
+ * path,
+ * ' '.repeat(Math.max(10 - path.length, 0)),
+ * name,
+ * i === c.req.routeIndex ? '<- respond from here' : ''
+ * )
+ * })
+ * })
+ * ```
+ */
+ get matchedRoutes() {
+ return this.#matchResult[0].map(([[, route]]) => route);
}
- nonnegative(message) {
- return this._addCheck({
- kind: "min",
- value: 0,
- inclusive: true,
- message: errorUtil.toString(message)
- });
+ /**
+ * `routePath()` can retrieve the path registered within the handler
+ *
+ * @deprecated
+ *
+ * Use routePath helper defined in "hono/route" instead.
+ *
+ * @see {@link https://hono.dev/docs/api/request#routepath}
+ *
+ * @example
+ * ```ts
+ * app.get('/posts/:id', (c) => {
+ * return c.json({ path: c.req.routePath })
+ * })
+ * ```
+ */
+ get routePath() {
+ return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
}
- multipleOf(value, message) {
- return this._addCheck({
- kind: "multipleOf",
- value,
- message: errorUtil.toString(message)
- });
+};
+
+// node_modules/hono/dist/utils/html.js
+var HtmlEscapedCallbackPhase = {
+ Stringify: 1,
+ BeforeStream: 2,
+ Stream: 3
+};
+var raw = (value, callbacks) => {
+ const escapedString = new String(value);
+ escapedString.isEscaped = true;
+ escapedString.callbacks = callbacks;
+ return escapedString;
+};
+var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
+ if (typeof str === "object" && !(str instanceof String)) {
+ if (!(str instanceof Promise)) {
+ str = str.toString();
+ }
+ if (str instanceof Promise) {
+ str = await str;
+ }
}
- finite(message) {
- return this._addCheck({
- kind: "finite",
- message: errorUtil.toString(message)
- });
+ const callbacks = str.callbacks;
+ if (!callbacks?.length) {
+ return Promise.resolve(str);
}
- safe(message) {
- return this._addCheck({
- kind: "min",
- inclusive: true,
- value: Number.MIN_SAFE_INTEGER,
- message: errorUtil.toString(message)
- })._addCheck({
- kind: "max",
- inclusive: true,
- value: Number.MAX_SAFE_INTEGER,
- message: errorUtil.toString(message)
- });
+ if (buffer) {
+ buffer[0] += str;
+ } else {
+ buffer = [str];
+ }
+ const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(
+ (res) => Promise.all(
+ res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))
+ ).then(() => buffer[0])
+ );
+ if (preserveCallbacks) {
+ return raw(await resStr, callbacks);
+ } else {
+ return resStr;
+ }
+};
+
+// node_modules/hono/dist/context.js
+var TEXT_PLAIN = "text/plain; charset=UTF-8";
+var setDefaultContentType = (contentType2, headers) => {
+ return {
+ "Content-Type": contentType2,
+ ...headers
+ };
+};
+var createResponseInstance = (body, init) => new Response(body, init);
+var Context = class {
+ #rawRequest;
+ #req;
+ /**
+ * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
+ *
+ * @see {@link https://hono.dev/docs/api/context#env}
+ *
+ * @example
+ * ```ts
+ * // Environment object for Cloudflare Workers
+ * app.get('*', async c => {
+ * const counter = c.env.COUNTER
+ * })
+ * ```
+ */
+ env = {};
+ #var;
+ finalized = false;
+ /**
+ * `.error` can get the error object from the middleware if the Handler throws an error.
+ *
+ * @see {@link https://hono.dev/docs/api/context#error}
+ *
+ * @example
+ * ```ts
+ * app.use('*', async (c, next) => {
+ * await next()
+ * if (c.error) {
+ * // do something...
+ * }
+ * })
+ * ```
+ */
+ error;
+ #status;
+ #executionCtx;
+ #res;
+ #layout;
+ #renderer;
+ #notFoundHandler;
+ #preparedHeaders;
+ #matchResult;
+ #path;
+ /**
+ * Creates an instance of the Context class.
+ *
+ * @param req - The Request object.
+ * @param options - Optional configuration options for the context.
+ */
+ constructor(req, options) {
+ this.#rawRequest = req;
+ if (options) {
+ this.#executionCtx = options.executionCtx;
+ this.env = options.env;
+ this.#notFoundHandler = options.notFoundHandler;
+ this.#path = options.path;
+ this.#matchResult = options.matchResult;
+ }
}
- get minValue() {
- let min = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "min") {
- if (min === null || ch.value > min)
- min = ch.value;
- }
+ /**
+ * `.req` is the instance of {@link HonoRequest}.
+ */
+ get req() {
+ this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
+ return this.#req;
+ }
+ /**
+ * @see {@link https://hono.dev/docs/api/context#event}
+ * The FetchEvent associated with the current request.
+ *
+ * @throws Will throw an error if the context does not have a FetchEvent.
+ */
+ get event() {
+ if (this.#executionCtx && "respondWith" in this.#executionCtx) {
+ return this.#executionCtx;
+ } else {
+ throw Error("This context has no FetchEvent");
}
- return min;
}
- get maxValue() {
- let max = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "max") {
- if (max === null || ch.value < max)
- max = ch.value;
- }
+ /**
+ * @see {@link https://hono.dev/docs/api/context#executionctx}
+ * The ExecutionContext associated with the current request.
+ *
+ * @throws Will throw an error if the context does not have an ExecutionContext.
+ */
+ get executionCtx() {
+ if (this.#executionCtx) {
+ return this.#executionCtx;
+ } else {
+ throw Error("This context has no ExecutionContext");
}
- return max;
}
- get isInt() {
- return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value));
+ /**
+ * @see {@link https://hono.dev/docs/api/context#res}
+ * The Response object for the current request.
+ */
+ get res() {
+ return this.#res ||= createResponseInstance(null, {
+ headers: this.#preparedHeaders ??= new Headers()
+ });
}
- get isFinite() {
- let max = null;
- let min = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
- return true;
- } else if (ch.kind === "min") {
- if (min === null || ch.value > min)
- min = ch.value;
- } else if (ch.kind === "max") {
- if (max === null || ch.value < max)
- max = ch.value;
+ /**
+ * Sets the Response object for the current request.
+ *
+ * @param _res - The Response object to set.
+ */
+ set res(_res) {
+ if (this.#res && _res) {
+ _res = createResponseInstance(_res.body, _res);
+ for (const [k, v] of this.#res.headers.entries()) {
+ if (k === "content-type") {
+ continue;
+ }
+ if (k === "set-cookie") {
+ const cookies = this.#res.headers.getSetCookie();
+ _res.headers.delete("set-cookie");
+ for (const cookie of cookies) {
+ _res.headers.append("set-cookie", cookie);
+ }
+ } else {
+ _res.headers.set(k, v);
+ }
}
}
- return Number.isFinite(min) && Number.isFinite(max);
+ this.#res = _res;
+ this.finalized = true;
}
-};
-ZodNumber.create = (params) => {
- return new ZodNumber({
- checks: [],
- typeName: ZodFirstPartyTypeKind.ZodNumber,
- coerce: params?.coerce || false,
- ...processCreateParams(params)
- });
-};
-var ZodBigInt = class _ZodBigInt extends ZodType {
- constructor() {
- super(...arguments);
- this.min = this.gte;
- this.max = this.lte;
+ /**
+ * `.render()` can create a response within a layout.
+ *
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
+ *
+ * @example
+ * ```ts
+ * app.get('/', (c) => {
+ * return c.render('Hello!')
+ * })
+ * ```
+ */
+ render = (...args) => {
+ this.#renderer ??= (content) => this.html(content);
+ return this.#renderer(...args);
+ };
+ /**
+ * Sets the layout for the response.
+ *
+ * @param layout - The layout to set.
+ * @returns The layout function.
+ */
+ setLayout = (layout) => this.#layout = layout;
+ /**
+ * Gets the current layout for the response.
+ *
+ * @returns The current layout function.
+ */
+ getLayout = () => this.#layout;
+ /**
+ * `.setRenderer()` can set the layout in the custom middleware.
+ *
+ * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
+ *
+ * @example
+ * ```tsx
+ * app.use('*', async (c, next) => {
+ * c.setRenderer((content) => {
+ * return c.html(
+ *
+ *
+ * {content}
+ *
+ *
+ * )
+ * })
+ * await next()
+ * })
+ * ```
+ */
+ setRenderer = (renderer) => {
+ this.#renderer = renderer;
+ };
+ /**
+ * `.header()` can set headers.
+ *
+ * @see {@link https://hono.dev/docs/api/context#header}
+ *
+ * @example
+ * ```ts
+ * app.get('/welcome', (c) => {
+ * // Set headers
+ * c.header('X-Message', 'Hello!')
+ * c.header('Content-Type', 'text/plain')
+ *
+ * return c.body('Thank you for coming')
+ * })
+ * ```
+ */
+ header = (name, value, options) => {
+ if (this.finalized) {
+ this.#res = createResponseInstance(this.#res.body, this.#res);
+ }
+ const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
+ if (value === void 0) {
+ headers.delete(name);
+ } else if (options?.append) {
+ headers.append(name, value);
+ } else {
+ headers.set(name, value);
+ }
+ };
+ status = (status) => {
+ this.#status = status;
+ };
+ /**
+ * `.set()` can set the value specified by the key.
+ *
+ * @see {@link https://hono.dev/docs/api/context#set-get}
+ *
+ * @example
+ * ```ts
+ * app.use('*', async (c, next) => {
+ * c.set('message', 'Hono is hot!!')
+ * await next()
+ * })
+ * ```
+ */
+ set = (key, value) => {
+ this.#var ??= /* @__PURE__ */ new Map();
+ this.#var.set(key, value);
+ };
+ /**
+ * `.get()` can use the value specified by the key.
+ *
+ * @see {@link https://hono.dev/docs/api/context#set-get}
+ *
+ * @example
+ * ```ts
+ * app.get('/', (c) => {
+ * const message = c.get('message')
+ * return c.text(`The message is "${message}"`)
+ * })
+ * ```
+ */
+ get = (key) => {
+ return this.#var ? this.#var.get(key) : void 0;
+ };
+ /**
+ * `.var` can access the value of a variable.
+ *
+ * @see {@link https://hono.dev/docs/api/context#var}
+ *
+ * @example
+ * ```ts
+ * const result = c.var.client.oneMethod()
+ * ```
+ */
+ // c.var.propName is a read-only
+ get var() {
+ if (!this.#var) {
+ return {};
+ }
+ return Object.fromEntries(this.#var);
}
- _parse(input) {
- if (this._def.coerce) {
- try {
- input.data = BigInt(input.data);
- } catch {
- return this._getInvalidInput(input);
+ #newResponse(data, arg, headers) {
+ const responseHeaders2 = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
+ if (typeof arg === "object" && "headers" in arg) {
+ const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
+ for (const [key, value] of argHeaders) {
+ if (key.toLowerCase() === "set-cookie") {
+ responseHeaders2.append(key, value);
+ } else {
+ responseHeaders2.set(key, value);
+ }
}
}
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.bigint) {
- return this._getInvalidInput(input);
- }
- let ctx = void 0;
- const status = new ParseStatus();
- for (const check of this._def.checks) {
- if (check.kind === "min") {
- const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
- if (tooSmall) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- type: "bigint",
- minimum: check.value,
- inclusive: check.inclusive,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "max") {
- const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
- if (tooBig) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- type: "bigint",
- maximum: check.value,
- inclusive: check.inclusive,
- message: check.message
- });
- status.dirty();
- }
- } else if (check.kind === "multipleOf") {
- if (input.data % check.value !== BigInt(0)) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.not_multiple_of,
- multipleOf: check.value,
- message: check.message
- });
- status.dirty();
+ if (headers) {
+ for (const [k, v] of Object.entries(headers)) {
+ if (typeof v === "string") {
+ responseHeaders2.set(k, v);
+ } else {
+ responseHeaders2.delete(k);
+ for (const v2 of v) {
+ responseHeaders2.append(k, v2);
+ }
}
- } else {
- util.assertNever(check);
}
}
- return { status: status.value, value: input.data };
- }
- _getInvalidInput(input) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.bigint,
- received: ctx.parsedType
- });
- return INVALID;
- }
- gte(value, message) {
- return this.setLimit("min", value, true, errorUtil.toString(message));
- }
- gt(value, message) {
- return this.setLimit("min", value, false, errorUtil.toString(message));
- }
- lte(value, message) {
- return this.setLimit("max", value, true, errorUtil.toString(message));
+ const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
+ return createResponseInstance(data, { status, headers: responseHeaders2 });
}
- lt(value, message) {
- return this.setLimit("max", value, false, errorUtil.toString(message));
+ newResponse = (...args) => this.#newResponse(...args);
+ /**
+ * `.body()` can return the HTTP response.
+ * You can set headers with `.header()` and set HTTP status code with `.status`.
+ * This can also be set in `.text()`, `.json()` and so on.
+ *
+ * @see {@link https://hono.dev/docs/api/context#body}
+ *
+ * @example
+ * ```ts
+ * app.get('/welcome', (c) => {
+ * // Set headers
+ * c.header('X-Message', 'Hello!')
+ * c.header('Content-Type', 'text/plain')
+ * // Set HTTP status code
+ * c.status(201)
+ *
+ * // Return the response body
+ * return c.body('Thank you for coming')
+ * })
+ * ```
+ */
+ body = (data, arg, headers) => this.#newResponse(data, arg, headers);
+ /**
+ * `.text()` can render text as `Content-Type:text/plain`.
+ *
+ * @see {@link https://hono.dev/docs/api/context#text}
+ *
+ * @example
+ * ```ts
+ * app.get('/say', (c) => {
+ * return c.text('Hello!')
+ * })
+ * ```
+ */
+ text = (text, arg, headers) => {
+ return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
+ text,
+ arg,
+ setDefaultContentType(TEXT_PLAIN, headers)
+ );
+ };
+ /**
+ * `.json()` can render JSON as `Content-Type:application/json`.
+ *
+ * @see {@link https://hono.dev/docs/api/context#json}
+ *
+ * @example
+ * ```ts
+ * app.get('/api', (c) => {
+ * return c.json({ message: 'Hello!' })
+ * })
+ * ```
+ */
+ json = (object2, arg, headers) => {
+ return this.#newResponse(
+ JSON.stringify(object2),
+ arg,
+ setDefaultContentType("application/json", headers)
+ );
+ };
+ html = (html, arg, headers) => {
+ const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
+ return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
+ };
+ /**
+ * `.redirect()` can Redirect, default status code is 302.
+ *
+ * @see {@link https://hono.dev/docs/api/context#redirect}
+ *
+ * @example
+ * ```ts
+ * app.get('/redirect', (c) => {
+ * return c.redirect('/')
+ * })
+ * app.get('/redirect-permanently', (c) => {
+ * return c.redirect('/', 301)
+ * })
+ * ```
+ */
+ redirect = (location, status) => {
+ const locationString = String(location);
+ this.header(
+ "Location",
+ // Multibyes should be encoded
+ // eslint-disable-next-line no-control-regex
+ !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
+ );
+ return this.newResponse(null, status ?? 302);
+ };
+ /**
+ * `.notFound()` can return the Not Found Response.
+ *
+ * @see {@link https://hono.dev/docs/api/context#notfound}
+ *
+ * @example
+ * ```ts
+ * app.get('/notfound', (c) => {
+ * return c.notFound()
+ * })
+ * ```
+ */
+ notFound = () => {
+ this.#notFoundHandler ??= () => createResponseInstance();
+ return this.#notFoundHandler(this);
+ };
+};
+
+// node_modules/hono/dist/router.js
+var METHOD_NAME_ALL = "ALL";
+var METHOD_NAME_ALL_LOWERCASE = "all";
+var METHODS = ["get", "post", "put", "delete", "options", "patch"];
+var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
+var UnsupportedPathError = class extends Error {
+};
+
+// node_modules/hono/dist/utils/constants.js
+var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
+
+// node_modules/hono/dist/hono-base.js
+var notFoundHandler = (c) => {
+ return c.text("404 Not Found", 404);
+};
+var errorHandler = (err, c) => {
+ if ("getResponse" in err) {
+ const res = err.getResponse();
+ return c.newResponse(res.body, res);
}
- setLimit(kind, value, inclusive, message) {
- return new _ZodBigInt({
- ...this._def,
- checks: [
- ...this._def.checks,
- {
- kind,
- value,
- inclusive,
- message: errorUtil.toString(message)
+ console.error(err);
+ return c.text("Internal Server Error", 500);
+};
+var Hono = class _Hono {
+ get;
+ post;
+ put;
+ delete;
+ options;
+ patch;
+ all;
+ on;
+ use;
+ /*
+ This class is like an abstract class and does not have a router.
+ To use it, inherit the class and implement router in the constructor.
+ */
+ router;
+ getPath;
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
+ _basePath = "/";
+ #path = "/";
+ routes = [];
+ constructor(options = {}) {
+ const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
+ allMethods.forEach((method) => {
+ this[method] = (args1, ...args) => {
+ if (typeof args1 === "string") {
+ this.#path = args1;
+ } else {
+ this.#addRoute(method, this.#path, args1);
+ }
+ args.forEach((handler) => {
+ this.#addRoute(method, this.#path, handler);
+ });
+ return this;
+ };
+ });
+ this.on = (method, path5, ...handlers) => {
+ for (const p of [path5].flat()) {
+ this.#path = p;
+ for (const m of [method].flat()) {
+ handlers.map((handler) => {
+ this.#addRoute(m.toUpperCase(), this.#path, handler);
+ });
}
- ]
- });
+ }
+ return this;
+ };
+ this.use = (arg1, ...handlers) => {
+ if (typeof arg1 === "string") {
+ this.#path = arg1;
+ } else {
+ this.#path = "*";
+ handlers.unshift(arg1);
+ }
+ handlers.forEach((handler) => {
+ this.#addRoute(METHOD_NAME_ALL, this.#path, handler);
+ });
+ return this;
+ };
+ const { strict, ...optionsWithoutStrict } = options;
+ Object.assign(this, optionsWithoutStrict);
+ this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
}
- _addCheck(check) {
- return new _ZodBigInt({
- ...this._def,
- checks: [...this._def.checks, check]
+ #clone() {
+ const clone = new _Hono({
+ router: this.router,
+ getPath: this.getPath
});
+ clone.errorHandler = this.errorHandler;
+ clone.#notFoundHandler = this.#notFoundHandler;
+ clone.routes = this.routes;
+ return clone;
}
- positive(message) {
- return this._addCheck({
- kind: "min",
- value: BigInt(0),
- inclusive: false,
- message: errorUtil.toString(message)
+ #notFoundHandler = notFoundHandler;
+ // Cannot use `#` because it requires visibility at JavaScript runtime.
+ errorHandler = errorHandler;
+ /**
+ * `.route()` allows grouping other Hono instance in routes.
+ *
+ * @see {@link https://hono.dev/docs/api/routing#grouping}
+ *
+ * @param {string} path - base Path
+ * @param {Hono} app - other Hono instance
+ * @returns {Hono} routed Hono instance
+ *
+ * @example
+ * ```ts
+ * const app = new Hono()
+ * const app2 = new Hono()
+ *
+ * app2.get("/user", (c) => c.text("user"))
+ * app.route("/api", app2) // GET /api/user
+ * ```
+ */
+ route(path5, app) {
+ const subApp = this.basePath(path5);
+ app.routes.map((r) => {
+ let handler;
+ if (app.errorHandler === errorHandler) {
+ handler = r.handler;
+ } else {
+ handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
+ handler[COMPOSED_HANDLER] = r.handler;
+ }
+ subApp.#addRoute(r.method, r.path, handler, r.basePath);
});
+ return this;
}
- negative(message) {
- return this._addCheck({
- kind: "max",
- value: BigInt(0),
- inclusive: false,
- message: errorUtil.toString(message)
- });
+ /**
+ * `.basePath()` allows base paths to be specified.
+ *
+ * @see {@link https://hono.dev/docs/api/routing#base-path}
+ *
+ * @param {string} path - base Path
+ * @returns {Hono} changed Hono instance
+ *
+ * @example
+ * ```ts
+ * const api = new Hono().basePath('/api')
+ * ```
+ */
+ basePath(path5) {
+ const subApp = this.#clone();
+ subApp._basePath = mergePath(this._basePath, path5);
+ return subApp;
}
- nonpositive(message) {
- return this._addCheck({
- kind: "max",
- value: BigInt(0),
- inclusive: true,
- message: errorUtil.toString(message)
- });
+ /**
+ * `.onError()` handles an error and returns a customized Response.
+ *
+ * @see {@link https://hono.dev/docs/api/hono#error-handling}
+ *
+ * @param {ErrorHandler} handler - request Handler for error
+ * @returns {Hono} changed Hono instance
+ *
+ * @example
+ * ```ts
+ * app.onError((err, c) => {
+ * console.error(`${err}`)
+ * return c.text('Custom Error Message', 500)
+ * })
+ * ```
+ */
+ onError = (handler) => {
+ this.errorHandler = handler;
+ return this;
+ };
+ /**
+ * `.notFound()` allows you to customize a Not Found Response.
+ *
+ * @see {@link https://hono.dev/docs/api/hono#not-found}
+ *
+ * @param {NotFoundHandler} handler - request handler for not-found
+ * @returns {Hono} changed Hono instance
+ *
+ * @example
+ * ```ts
+ * app.notFound((c) => {
+ * return c.text('Custom 404 Message', 404)
+ * })
+ * ```
+ */
+ notFound = (handler) => {
+ this.#notFoundHandler = handler;
+ return this;
+ };
+ /**
+ * `.mount()` allows you to mount applications built with other frameworks into your Hono application.
+ *
+ * @see {@link https://hono.dev/docs/api/hono#mount}
+ *
+ * @param {string} path - base Path
+ * @param {Function} applicationHandler - other Request Handler
+ * @param {MountOptions} [options] - options of `.mount()`
+ * @returns {Hono} mounted Hono instance
+ *
+ * @example
+ * ```ts
+ * import { Router as IttyRouter } from 'itty-router'
+ * import { Hono } from 'hono'
+ * // Create itty-router application
+ * const ittyRouter = IttyRouter()
+ * // GET /itty-router/hello
+ * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
+ *
+ * const app = new Hono()
+ * app.mount('/itty-router', ittyRouter.handle)
+ * ```
+ *
+ * @example
+ * ```ts
+ * const app = new Hono()
+ * // Send the request to another application without modification.
+ * app.mount('/app', anotherApp, {
+ * replaceRequest: (req) => req,
+ * })
+ * ```
+ */
+ mount(path5, applicationHandler, options) {
+ let replaceRequest;
+ let optionHandler;
+ if (options) {
+ if (typeof options === "function") {
+ optionHandler = options;
+ } else {
+ optionHandler = options.optionHandler;
+ if (options.replaceRequest === false) {
+ replaceRequest = (request) => request;
+ } else {
+ replaceRequest = options.replaceRequest;
+ }
+ }
+ }
+ const getOptions = optionHandler ? (c) => {
+ const options2 = optionHandler(c);
+ return Array.isArray(options2) ? options2 : [options2];
+ } : (c) => {
+ let executionContext = void 0;
+ try {
+ executionContext = c.executionCtx;
+ } catch {
+ }
+ return [c.env, executionContext];
+ };
+ replaceRequest ||= (() => {
+ const mergedPath = mergePath(this._basePath, path5);
+ const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
+ return (request) => {
+ const url = new URL(request.url);
+ url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
+ return new Request(url, request);
+ };
+ })();
+ const handler = async (c, next) => {
+ const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
+ if (res) {
+ return res;
+ }
+ await next();
+ };
+ this.#addRoute(METHOD_NAME_ALL, mergePath(path5, "*"), handler);
+ return this;
}
- nonnegative(message) {
- return this._addCheck({
- kind: "min",
- value: BigInt(0),
- inclusive: true,
- message: errorUtil.toString(message)
- });
+ #addRoute(method, path5, handler, baseRoutePath) {
+ method = method.toUpperCase();
+ path5 = mergePath(this._basePath, path5);
+ const r = {
+ basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
+ path: path5,
+ method,
+ handler
+ };
+ this.router.add(method, path5, [handler, r]);
+ this.routes.push(r);
}
- multipleOf(value, message) {
- return this._addCheck({
- kind: "multipleOf",
- value,
- message: errorUtil.toString(message)
+ #handleError(err, c) {
+ if (err instanceof Error) {
+ return this.errorHandler(err, c);
+ }
+ throw err;
+ }
+ #dispatch(request, executionCtx, env, method) {
+ if (method === "HEAD") {
+ return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
+ }
+ const path5 = this.getPath(request, { env });
+ const matchResult = this.router.match(method, path5);
+ const c = new Context(request, {
+ path: path5,
+ matchResult,
+ env,
+ executionCtx,
+ notFoundHandler: this.#notFoundHandler
});
- }
- get minValue() {
- let min = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "min") {
- if (min === null || ch.value > min)
- min = ch.value;
+ if (matchResult[0].length === 1) {
+ let res;
+ try {
+ res = matchResult[0][0][0][0](c, async () => {
+ c.res = await this.#notFoundHandler(c);
+ });
+ } catch (err) {
+ return this.#handleError(err, c);
}
+ return res instanceof Promise ? res.then(
+ (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
+ ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
}
- return min;
- }
- get maxValue() {
- let max = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "max") {
- if (max === null || ch.value < max)
- max = ch.value;
+ const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
+ return (async () => {
+ try {
+ const context = await composed(c);
+ if (!context.finalized) {
+ throw new Error(
+ "Context is not finalized. Did you forget to return a Response object or `await next()`?"
+ );
+ }
+ return context.res;
+ } catch (err) {
+ return this.#handleError(err, c);
}
- }
- return max;
+ })();
}
-};
-ZodBigInt.create = (params) => {
- return new ZodBigInt({
- checks: [],
- typeName: ZodFirstPartyTypeKind.ZodBigInt,
- coerce: params?.coerce ?? false,
- ...processCreateParams(params)
- });
-};
-var ZodBoolean = class extends ZodType {
- _parse(input) {
- if (this._def.coerce) {
- input.data = Boolean(input.data);
- }
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.boolean) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.boolean,
- received: ctx.parsedType
- });
- return INVALID;
+ /**
+ * `.fetch()` will be entry point of your app.
+ *
+ * @see {@link https://hono.dev/docs/api/hono#fetch}
+ *
+ * @param {Request} request - request Object of request
+ * @param {Env} Env - env Object
+ * @param {ExecutionContext} - context of execution
+ * @returns {Response | Promise} response of request
+ *
+ */
+ fetch = (request, ...rest) => {
+ return this.#dispatch(request, rest[1], rest[0], request.method);
+ };
+ /**
+ * `.request()` is a useful method for testing.
+ * You can pass a URL or pathname to send a GET request.
+ * app will return a Response object.
+ * ```ts
+ * test('GET /hello is ok', async () => {
+ * const res = await app.request('/hello')
+ * expect(res.status).toBe(200)
+ * })
+ * ```
+ * @see https://hono.dev/docs/api/hono#request
+ */
+ request = (input, requestInit, Env, executionCtx) => {
+ if (input instanceof Request) {
+ return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
}
- return OK(input.data);
- }
-};
-ZodBoolean.create = (params) => {
- return new ZodBoolean({
- typeName: ZodFirstPartyTypeKind.ZodBoolean,
- coerce: params?.coerce || false,
- ...processCreateParams(params)
- });
+ input = input.toString();
+ return this.fetch(
+ new Request(
+ /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`,
+ requestInit
+ ),
+ Env,
+ executionCtx
+ );
+ };
+ /**
+ * `.fire()` automatically adds a global fetch event listener.
+ * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
+ * @deprecated
+ * Use `fire` from `hono/service-worker` instead.
+ * ```ts
+ * import { Hono } from 'hono'
+ * import { fire } from 'hono/service-worker'
+ *
+ * const app = new Hono()
+ * // ...
+ * fire(app)
+ * ```
+ * @see https://hono.dev/docs/api/hono#fire
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
+ * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
+ */
+ fire = () => {
+ addEventListener("fetch", (event) => {
+ event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
+ });
+ };
};
-var ZodDate = class _ZodDate extends ZodType {
- _parse(input) {
- if (this._def.coerce) {
- input.data = new Date(input.data);
+
+// node_modules/hono/dist/router/reg-exp-router/matcher.js
+var emptyParam = [];
+function match(method, path5) {
+ const matchers = this.buildAllMatchers();
+ const match2 = ((method2, path22) => {
+ const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
+ const staticMatch = matcher[2][path22];
+ if (staticMatch) {
+ return staticMatch;
}
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.date) {
- const ctx2 = this._getOrReturnCtx(input);
- addIssueToContext(ctx2, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.date,
- received: ctx2.parsedType
- });
- return INVALID;
+ const match3 = path22.match(matcher[0]);
+ if (!match3) {
+ return [[], emptyParam];
}
- if (Number.isNaN(input.data.getTime())) {
- const ctx2 = this._getOrReturnCtx(input);
- addIssueToContext(ctx2, {
- code: ZodIssueCode.invalid_date
- });
- return INVALID;
+ const index = match3.indexOf("", 1);
+ return [matcher[1][index], match3];
+ });
+ this.match = match2;
+ return match2(method, path5);
+}
+
+// node_modules/hono/dist/router/reg-exp-router/node.js
+var LABEL_REG_EXP_STR = "[^/]+";
+var ONLY_WILDCARD_REG_EXP_STR = ".*";
+var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
+var PATH_ERROR = /* @__PURE__ */ Symbol();
+var regExpMetaChars = new Set(".\\+*[^]$()");
+function compareKey(a, b) {
+ if (a.length === 1) {
+ return b.length === 1 ? a < b ? -1 : 1 : -1;
+ }
+ if (b.length === 1) {
+ return 1;
+ }
+ if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
+ return 1;
+ } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
+ return -1;
+ }
+ if (a === LABEL_REG_EXP_STR) {
+ return 1;
+ } else if (b === LABEL_REG_EXP_STR) {
+ return -1;
+ }
+ return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
+}
+var Node = class _Node {
+ #index;
+ #varIndex;
+ #children = /* @__PURE__ */ Object.create(null);
+ insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
+ if (tokens.length === 0) {
+ if (this.#index !== void 0) {
+ throw PATH_ERROR;
+ }
+ if (pathErrorCheckOnly) {
+ return;
+ }
+ this.#index = index;
+ return;
}
- const status = new ParseStatus();
- let ctx = void 0;
- for (const check of this._def.checks) {
- if (check.kind === "min") {
- if (input.data.getTime() < check.value) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- message: check.message,
- inclusive: true,
- exact: false,
- minimum: check.value,
- type: "date"
- });
- status.dirty();
+ const [token, ...restTokens] = tokens;
+ const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
+ let node;
+ if (pattern) {
+ const name = pattern[1];
+ let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
+ if (name && pattern[2]) {
+ if (regexpStr === ".*") {
+ throw PATH_ERROR;
+ }
+ regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
+ if (/\((?!\?:)/.test(regexpStr)) {
+ throw PATH_ERROR;
+ }
+ }
+ node = this.#children[regexpStr];
+ if (!node) {
+ if (Object.keys(this.#children).some(
+ (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
+ )) {
+ throw PATH_ERROR;
+ }
+ if (pathErrorCheckOnly) {
+ return;
}
- } else if (check.kind === "max") {
- if (input.data.getTime() > check.value) {
- ctx = this._getOrReturnCtx(input, ctx);
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- message: check.message,
- inclusive: true,
- exact: false,
- maximum: check.value,
- type: "date"
- });
- status.dirty();
+ node = this.#children[regexpStr] = new _Node();
+ if (name !== "") {
+ node.#varIndex = context.varIndex++;
}
- } else {
- util.assertNever(check);
+ }
+ if (!pathErrorCheckOnly && name !== "") {
+ paramMap.push([name, node.#varIndex]);
+ }
+ } else {
+ node = this.#children[token];
+ if (!node) {
+ if (Object.keys(this.#children).some(
+ (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
+ )) {
+ throw PATH_ERROR;
+ }
+ if (pathErrorCheckOnly) {
+ return;
+ }
+ node = this.#children[token] = new _Node();
}
}
- return {
- status: status.value,
- value: new Date(input.data.getTime())
- };
- }
- _addCheck(check) {
- return new _ZodDate({
- ...this._def,
- checks: [...this._def.checks, check]
- });
- }
- min(minDate, message) {
- return this._addCheck({
- kind: "min",
- value: minDate.getTime(),
- message: errorUtil.toString(message)
- });
+ node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
}
- max(maxDate, message) {
- return this._addCheck({
- kind: "max",
- value: maxDate.getTime(),
- message: errorUtil.toString(message)
+ buildRegExpStr() {
+ const childKeys = Object.keys(this.#children).sort(compareKey);
+ const strList = childKeys.map((k) => {
+ const c = this.#children[k];
+ return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
});
- }
- get minDate() {
- let min = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "min") {
- if (min === null || ch.value > min)
- min = ch.value;
- }
+ if (typeof this.#index === "number") {
+ strList.unshift(`#${this.#index}`);
}
- return min != null ? new Date(min) : null;
- }
- get maxDate() {
- let max = null;
- for (const ch of this._def.checks) {
- if (ch.kind === "max") {
- if (max === null || ch.value < max)
- max = ch.value;
- }
+ if (strList.length === 0) {
+ return "";
}
- return max != null ? new Date(max) : null;
- }
-};
-ZodDate.create = (params) => {
- return new ZodDate({
- checks: [],
- coerce: params?.coerce || false,
- typeName: ZodFirstPartyTypeKind.ZodDate,
- ...processCreateParams(params)
- });
-};
-var ZodSymbol = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.symbol) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.symbol,
- received: ctx.parsedType
- });
- return INVALID;
+ if (strList.length === 1) {
+ return strList[0];
}
- return OK(input.data);
+ return "(?:" + strList.join("|") + ")";
}
};
-ZodSymbol.create = (params) => {
- return new ZodSymbol({
- typeName: ZodFirstPartyTypeKind.ZodSymbol,
- ...processCreateParams(params)
- });
-};
-var ZodUndefined = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.undefined) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.undefined,
- received: ctx.parsedType
+
+// node_modules/hono/dist/router/reg-exp-router/trie.js
+var Trie = class {
+ #context = { varIndex: 0 };
+ #root = new Node();
+ insert(path5, index, pathErrorCheckOnly) {
+ const paramAssoc = [];
+ const groups = [];
+ for (let i = 0; ; ) {
+ let replaced = false;
+ path5 = path5.replace(/\{[^}]+\}/g, (m) => {
+ const mark = `@\\${i}`;
+ groups[i] = [mark, m];
+ i++;
+ replaced = true;
+ return mark;
});
- return INVALID;
+ if (!replaced) {
+ break;
+ }
}
- return OK(input.data);
+ const tokens = path5.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
+ for (let i = groups.length - 1; i >= 0; i--) {
+ const [mark] = groups[i];
+ for (let j = tokens.length - 1; j >= 0; j--) {
+ if (tokens[j].indexOf(mark) !== -1) {
+ tokens[j] = tokens[j].replace(mark, groups[i][1]);
+ break;
+ }
+ }
+ }
+ this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
+ return paramAssoc;
}
-};
-ZodUndefined.create = (params) => {
- return new ZodUndefined({
- typeName: ZodFirstPartyTypeKind.ZodUndefined,
- ...processCreateParams(params)
- });
-};
-var ZodNull = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.null) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.null,
- received: ctx.parsedType
- });
- return INVALID;
+ buildRegExp() {
+ let regexp = this.#root.buildRegExpStr();
+ if (regexp === "") {
+ return [/^$/, [], []];
}
- return OK(input.data);
+ let captureIndex = 0;
+ const indexReplacementMap = [];
+ const paramReplacementMap = [];
+ regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
+ if (handlerIndex !== void 0) {
+ indexReplacementMap[++captureIndex] = Number(handlerIndex);
+ return "$()";
+ }
+ if (paramIndex !== void 0) {
+ paramReplacementMap[Number(paramIndex)] = ++captureIndex;
+ return "";
+ }
+ return "";
+ });
+ return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
}
};
-ZodNull.create = (params) => {
- return new ZodNull({
- typeName: ZodFirstPartyTypeKind.ZodNull,
- ...processCreateParams(params)
- });
-};
-var ZodAny = class extends ZodType {
- constructor() {
- super(...arguments);
- this._any = true;
+
+// node_modules/hono/dist/router/reg-exp-router/router.js
+var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
+var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
+function buildWildcardRegExp(path5) {
+ return wildcardRegExpCache[path5] ??= new RegExp(
+ path5 === "*" ? "" : `^${path5.replace(
+ /\/\*$|([.\\+*[^\]$()])/g,
+ (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
+ )}$`
+ );
+}
+function clearWildcardRegExpCache() {
+ wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
+}
+function buildMatcherFromPreprocessedRoutes(routes) {
+ const trie = new Trie();
+ const handlerData = [];
+ if (routes.length === 0) {
+ return nullMatcher;
}
- _parse(input) {
- return OK(input.data);
+ const routesWithStaticPathFlag = routes.map(
+ (route) => [!/\*|\/:/.test(route[0]), ...route]
+ ).sort(
+ ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
+ );
+ const staticMap = /* @__PURE__ */ Object.create(null);
+ for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
+ const [pathErrorCheckOnly, path5, handlers] = routesWithStaticPathFlag[i];
+ if (pathErrorCheckOnly) {
+ staticMap[path5] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
+ } else {
+ j++;
+ }
+ let paramAssoc;
+ try {
+ paramAssoc = trie.insert(path5, j, pathErrorCheckOnly);
+ } catch (e) {
+ throw e === PATH_ERROR ? new UnsupportedPathError(path5) : e;
+ }
+ if (pathErrorCheckOnly) {
+ continue;
+ }
+ handlerData[j] = handlers.map(([h, paramCount]) => {
+ const paramIndexMap = /* @__PURE__ */ Object.create(null);
+ paramCount -= 1;
+ for (; paramCount >= 0; paramCount--) {
+ const [key, value] = paramAssoc[paramCount];
+ paramIndexMap[key] = value;
+ }
+ return [h, paramIndexMap];
+ });
}
-};
-ZodAny.create = (params) => {
- return new ZodAny({
- typeName: ZodFirstPartyTypeKind.ZodAny,
- ...processCreateParams(params)
- });
-};
-var ZodUnknown = class extends ZodType {
- constructor() {
- super(...arguments);
- this._unknown = true;
+ const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
+ for (let i = 0, len = handlerData.length; i < len; i++) {
+ for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
+ const map = handlerData[i][j]?.[1];
+ if (!map) {
+ continue;
+ }
+ const keys = Object.keys(map);
+ for (let k = 0, len3 = keys.length; k < len3; k++) {
+ map[keys[k]] = paramReplacementMap[map[keys[k]]];
+ }
+ }
}
- _parse(input) {
- return OK(input.data);
+ const handlerMap = [];
+ for (const i in indexReplacementMap) {
+ handlerMap[i] = handlerData[indexReplacementMap[i]];
}
-};
-ZodUnknown.create = (params) => {
- return new ZodUnknown({
- typeName: ZodFirstPartyTypeKind.ZodUnknown,
- ...processCreateParams(params)
- });
-};
-var ZodNever = class extends ZodType {
- _parse(input) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.never,
- received: ctx.parsedType
- });
- return INVALID;
+ return [regexp, handlerMap, staticMap];
+}
+function findMiddleware(middleware, path5) {
+ if (!middleware) {
+ return void 0;
}
-};
-ZodNever.create = (params) => {
- return new ZodNever({
- typeName: ZodFirstPartyTypeKind.ZodNever,
- ...processCreateParams(params)
- });
-};
-var ZodVoid = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.undefined) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.void,
- received: ctx.parsedType
- });
- return INVALID;
+ for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
+ if (buildWildcardRegExp(k).test(path5)) {
+ return [...middleware[k]];
}
- return OK(input.data);
}
-};
-ZodVoid.create = (params) => {
- return new ZodVoid({
- typeName: ZodFirstPartyTypeKind.ZodVoid,
- ...processCreateParams(params)
- });
-};
-var ZodArray = class _ZodArray extends ZodType {
- _parse(input) {
- const { ctx, status } = this._processInputParams(input);
- const def = this._def;
- if (ctx.parsedType !== ZodParsedType.array) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.array,
- received: ctx.parsedType
- });
- return INVALID;
+ return void 0;
+}
+var RegExpRouter = class {
+ name = "RegExpRouter";
+ #middleware;
+ #routes;
+ constructor() {
+ this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
+ this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
+ }
+ add(method, path5, handler) {
+ const middleware = this.#middleware;
+ const routes = this.#routes;
+ if (!middleware || !routes) {
+ throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
}
- if (def.exactLength !== null) {
- const tooBig = ctx.data.length > def.exactLength.value;
- const tooSmall = ctx.data.length < def.exactLength.value;
- if (tooBig || tooSmall) {
- addIssueToContext(ctx, {
- code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,
- minimum: tooSmall ? def.exactLength.value : void 0,
- maximum: tooBig ? def.exactLength.value : void 0,
- type: "array",
- inclusive: true,
- exact: true,
- message: def.exactLength.message
+ if (!middleware[method]) {
+ ;
+ [middleware, routes].forEach((handlerMap) => {
+ handlerMap[method] = /* @__PURE__ */ Object.create(null);
+ Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
+ handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
});
- status.dirty();
- }
+ });
}
- if (def.minLength !== null) {
- if (ctx.data.length < def.minLength.value) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: def.minLength.value,
- type: "array",
- inclusive: true,
- exact: false,
- message: def.minLength.message
- });
- status.dirty();
- }
+ if (path5 === "/*") {
+ path5 = "*";
}
- if (def.maxLength !== null) {
- if (ctx.data.length > def.maxLength.value) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: def.maxLength.value,
- type: "array",
- inclusive: true,
- exact: false,
- message: def.maxLength.message
+ const paramCount = (path5.match(/\/:/g) || []).length;
+ if (/\*$/.test(path5)) {
+ const re = buildWildcardRegExp(path5);
+ if (method === METHOD_NAME_ALL) {
+ Object.keys(middleware).forEach((m) => {
+ middleware[m][path5] ||= findMiddleware(middleware[m], path5) || findMiddleware(middleware[METHOD_NAME_ALL], path5) || [];
});
- status.dirty();
+ } else {
+ middleware[method][path5] ||= findMiddleware(middleware[method], path5) || findMiddleware(middleware[METHOD_NAME_ALL], path5) || [];
}
+ Object.keys(middleware).forEach((m) => {
+ if (method === METHOD_NAME_ALL || method === m) {
+ Object.keys(middleware[m]).forEach((p) => {
+ re.test(p) && middleware[m][p].push([handler, paramCount]);
+ });
+ }
+ });
+ Object.keys(routes).forEach((m) => {
+ if (method === METHOD_NAME_ALL || method === m) {
+ Object.keys(routes[m]).forEach(
+ (p) => re.test(p) && routes[m][p].push([handler, paramCount])
+ );
+ }
+ });
+ return;
}
- if (ctx.common.async) {
- return Promise.all([...ctx.data].map((item, i) => {
- return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
- })).then((result2) => {
- return ParseStatus.mergeArray(status, result2);
+ const paths = checkOptionalParameter(path5) || [path5];
+ for (let i = 0, len = paths.length; i < len; i++) {
+ const path22 = paths[i];
+ Object.keys(routes).forEach((m) => {
+ if (method === METHOD_NAME_ALL || method === m) {
+ routes[m][path22] ||= [
+ ...findMiddleware(middleware[m], path22) || findMiddleware(middleware[METHOD_NAME_ALL], path22) || []
+ ];
+ routes[m][path22].push([handler, paramCount - len + i + 1]);
+ }
});
}
- const result = [...ctx.data].map((item, i) => {
- return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
- });
- return ParseStatus.mergeArray(status, result);
}
- get element() {
- return this._def.type;
- }
- min(minLength, message) {
- return new _ZodArray({
- ...this._def,
- minLength: { value: minLength, message: errorUtil.toString(message) }
+ match = match;
+ buildAllMatchers() {
+ const matchers = /* @__PURE__ */ Object.create(null);
+ Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
+ matchers[method] ||= this.#buildMatcher(method);
});
+ this.#middleware = this.#routes = void 0;
+ clearWildcardRegExpCache();
+ return matchers;
}
- max(maxLength, message) {
- return new _ZodArray({
- ...this._def,
- maxLength: { value: maxLength, message: errorUtil.toString(message) }
+ #buildMatcher(method) {
+ const routes = [];
+ let hasOwnRoute = method === METHOD_NAME_ALL;
+ [this.#middleware, this.#routes].forEach((r) => {
+ const ownRoute = r[method] ? Object.keys(r[method]).map((path5) => [path5, r[method][path5]]) : [];
+ if (ownRoute.length !== 0) {
+ hasOwnRoute ||= true;
+ routes.push(...ownRoute);
+ } else if (method !== METHOD_NAME_ALL) {
+ routes.push(
+ ...Object.keys(r[METHOD_NAME_ALL]).map((path5) => [path5, r[METHOD_NAME_ALL][path5]])
+ );
+ }
});
+ if (!hasOwnRoute) {
+ return null;
+ } else {
+ return buildMatcherFromPreprocessedRoutes(routes);
+ }
}
- length(len, message) {
- return new _ZodArray({
- ...this._def,
- exactLength: { value: len, message: errorUtil.toString(message) }
- });
+};
+
+// node_modules/hono/dist/router/smart-router/router.js
+var SmartRouter = class {
+ name = "SmartRouter";
+ #routers = [];
+ #routes = [];
+ constructor(init) {
+ this.#routers = init.routers;
+ }
+ add(method, path5, handler) {
+ if (!this.#routes) {
+ throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
+ }
+ this.#routes.push([method, path5, handler]);
+ }
+ match(method, path5) {
+ if (!this.#routes) {
+ throw new Error("Fatal error");
+ }
+ const routers = this.#routers;
+ const routes = this.#routes;
+ const len = routers.length;
+ let i = 0;
+ let res;
+ for (; i < len; i++) {
+ const router = routers[i];
+ try {
+ for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
+ router.add(...routes[i2]);
+ }
+ res = router.match(method, path5);
+ } catch (e) {
+ if (e instanceof UnsupportedPathError) {
+ continue;
+ }
+ throw e;
+ }
+ this.match = router.match.bind(router);
+ this.#routers = [router];
+ this.#routes = void 0;
+ break;
+ }
+ if (i === len) {
+ throw new Error("Fatal error");
+ }
+ this.name = `SmartRouter + ${this.activeRouter.name}`;
+ return res;
}
- nonempty(message) {
- return this.min(1, message);
+ get activeRouter() {
+ if (this.#routes || this.#routers.length !== 1) {
+ throw new Error("No active router has been determined yet.");
+ }
+ return this.#routers[0];
}
};
-ZodArray.create = (schema, params) => {
- return new ZodArray({
- type: schema,
- minLength: null,
- maxLength: null,
- exactLength: null,
- typeName: ZodFirstPartyTypeKind.ZodArray,
- ...processCreateParams(params)
- });
+
+// node_modules/hono/dist/router/trie-router/node.js
+var emptyParams = /* @__PURE__ */ Object.create(null);
+var hasChildren = (children) => {
+ for (const _ in children) {
+ return true;
+ }
+ return false;
};
-function deepPartialify(schema) {
- if (schema instanceof ZodObject) {
- const newShape = {};
- for (const key in schema.shape) {
- const fieldSchema = schema.shape[key];
- newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
+var Node2 = class _Node2 {
+ #methods;
+ #children;
+ #patterns;
+ #order = 0;
+ #params = emptyParams;
+ constructor(method, handler, children) {
+ this.#children = children || /* @__PURE__ */ Object.create(null);
+ this.#methods = [];
+ if (method && handler) {
+ const m = /* @__PURE__ */ Object.create(null);
+ m[method] = { handler, possibleKeys: [], score: 0 };
+ this.#methods = [m];
}
- return new ZodObject({
- ...schema._def,
- shape: () => newShape
- });
- } else if (schema instanceof ZodArray) {
- return new ZodArray({
- ...schema._def,
- type: deepPartialify(schema.element)
- });
- } else if (schema instanceof ZodOptional) {
- return ZodOptional.create(deepPartialify(schema.unwrap()));
- } else if (schema instanceof ZodNullable) {
- return ZodNullable.create(deepPartialify(schema.unwrap()));
- } else if (schema instanceof ZodTuple) {
- return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
- } else {
- return schema;
- }
-}
-var ZodObject = class _ZodObject extends ZodType {
- constructor() {
- super(...arguments);
- this._cached = null;
- this.nonstrict = this.passthrough;
- this.augment = this.extend;
- }
- _getCached() {
- if (this._cached !== null)
- return this._cached;
- const shape = this._def.shape();
- const keys = util.objectKeys(shape);
- this._cached = { shape, keys };
- return this._cached;
+ this.#patterns = [];
}
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.object) {
- const ctx2 = this._getOrReturnCtx(input);
- addIssueToContext(ctx2, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.object,
- received: ctx2.parsedType
- });
- return INVALID;
- }
- const { status, ctx } = this._processInputParams(input);
- const { shape, keys: shapeKeys } = this._getCached();
- const extraKeys = [];
- if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
- for (const key in ctx.data) {
- if (!shapeKeys.includes(key)) {
- extraKeys.push(key);
+ insert(method, path5, handler) {
+ this.#order = ++this.#order;
+ let curNode = this;
+ const parts = splitRoutingPath(path5);
+ const possibleKeys = [];
+ for (let i = 0, len = parts.length; i < len; i++) {
+ const p = parts[i];
+ const nextP = parts[i + 1];
+ const pattern = getPattern(p, nextP);
+ const key = Array.isArray(pattern) ? pattern[0] : p;
+ if (key in curNode.#children) {
+ curNode = curNode.#children[key];
+ if (pattern) {
+ possibleKeys.push(pattern[1]);
}
+ continue;
}
+ curNode.#children[key] = new _Node2();
+ if (pattern) {
+ curNode.#patterns.push(pattern);
+ possibleKeys.push(pattern[1]);
+ }
+ curNode = curNode.#children[key];
}
- const pairs = [];
- for (const key of shapeKeys) {
- const keyValidator = shape[key];
- const value = ctx.data[key];
- pairs.push({
- key: { status: "valid", value: key },
- value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
- alwaysSet: key in ctx.data
- });
+ curNode.#methods.push({
+ [method]: {
+ handler,
+ possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
+ score: this.#order
+ }
+ });
+ return curNode;
+ }
+ #pushHandlerSets(handlerSets, node, method, nodeParams, params) {
+ for (let i = 0, len = node.#methods.length; i < len; i++) {
+ const m = node.#methods[i];
+ const handlerSet = m[method] || m[METHOD_NAME_ALL];
+ const processedSet = {};
+ if (handlerSet !== void 0) {
+ handlerSet.params = /* @__PURE__ */ Object.create(null);
+ handlerSets.push(handlerSet);
+ if (nodeParams !== emptyParams || params && params !== emptyParams) {
+ for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
+ const key = handlerSet.possibleKeys[i2];
+ const processed = processedSet[handlerSet.score];
+ handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
+ processedSet[handlerSet.score] = true;
+ }
+ }
+ }
}
- if (this._def.catchall instanceof ZodNever) {
- const unknownKeys = this._def.unknownKeys;
- if (unknownKeys === "passthrough") {
- for (const key of extraKeys) {
- pairs.push({
- key: { status: "valid", value: key },
- value: { status: "valid", value: ctx.data[key] }
- });
+ }
+ search(method, path5) {
+ const handlerSets = [];
+ this.#params = emptyParams;
+ const curNode = this;
+ let curNodes = [curNode];
+ const parts = splitPath(path5);
+ const curNodesQueue = [];
+ const len = parts.length;
+ let partOffsets = null;
+ for (let i = 0; i < len; i++) {
+ const part = parts[i];
+ const isLast = i === len - 1;
+ const tempNodes = [];
+ for (let j = 0, len2 = curNodes.length; j < len2; j++) {
+ const node = curNodes[j];
+ const nextNode = node.#children[part];
+ if (nextNode) {
+ nextNode.#params = node.#params;
+ if (isLast) {
+ if (nextNode.#children["*"]) {
+ this.#pushHandlerSets(handlerSets, nextNode.#children["*"], method, node.#params);
+ }
+ this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);
+ } else {
+ tempNodes.push(nextNode);
+ }
}
- } else if (unknownKeys === "strict") {
- if (extraKeys.length > 0) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.unrecognized_keys,
- keys: extraKeys
- });
- status.dirty();
+ for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {
+ const pattern = node.#patterns[k];
+ const params = node.#params === emptyParams ? {} : { ...node.#params };
+ if (pattern === "*") {
+ const astNode = node.#children["*"];
+ if (astNode) {
+ this.#pushHandlerSets(handlerSets, astNode, method, node.#params);
+ astNode.#params = params;
+ tempNodes.push(astNode);
+ }
+ continue;
+ }
+ const [key, name, matcher] = pattern;
+ if (!part && !(matcher instanceof RegExp)) {
+ continue;
+ }
+ const child = node.#children[key];
+ if (matcher instanceof RegExp) {
+ if (partOffsets === null) {
+ partOffsets = new Array(len);
+ let offset = path5[0] === "/" ? 1 : 0;
+ for (let p = 0; p < len; p++) {
+ partOffsets[p] = offset;
+ offset += parts[p].length + 1;
+ }
+ }
+ const restPathString = path5.substring(partOffsets[i]);
+ const m = matcher.exec(restPathString);
+ if (m) {
+ params[name] = m[0];
+ this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
+ if (hasChildren(child.#children)) {
+ child.#params = params;
+ const componentCount = m[0].match(/\//)?.length ?? 0;
+ const targetCurNodes = curNodesQueue[componentCount] ||= [];
+ targetCurNodes.push(child);
+ }
+ continue;
+ }
+ }
+ if (matcher === true || matcher.test(part)) {
+ params[name] = part;
+ if (isLast) {
+ this.#pushHandlerSets(handlerSets, child, method, params, node.#params);
+ if (child.#children["*"]) {
+ this.#pushHandlerSets(
+ handlerSets,
+ child.#children["*"],
+ method,
+ params,
+ node.#params
+ );
+ }
+ } else {
+ child.#params = params;
+ tempNodes.push(child);
+ }
+ }
}
- } else if (unknownKeys === "strip") {
- } else {
- throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
- }
- } else {
- const catchall = this._def.catchall;
- for (const key of extraKeys) {
- const value = ctx.data[key];
- pairs.push({
- key: { status: "valid", value: key },
- value: catchall._parse(
- new ParseInputLazyPath(ctx, value, ctx.path, key)
- //, ctx.child(key), value, getParsedType(value)
- ),
- alwaysSet: key in ctx.data
- });
}
+ const shifted = curNodesQueue.shift();
+ curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
}
- if (ctx.common.async) {
- return Promise.resolve().then(async () => {
- const syncPairs = [];
- for (const pair of pairs) {
- const key = await pair.key;
- const value = await pair.value;
- syncPairs.push({
- key,
- value,
- alwaysSet: pair.alwaysSet
- });
- }
- return syncPairs;
- }).then((syncPairs) => {
- return ParseStatus.mergeObjectSync(status, syncPairs);
+ if (handlerSets.length > 1) {
+ handlerSets.sort((a, b) => {
+ return a.score - b.score;
});
- } else {
- return ParseStatus.mergeObjectSync(status, pairs);
}
+ return [handlerSets.map(({ handler, params }) => [handler, params])];
}
- get shape() {
- return this._def.shape();
+};
+
+// node_modules/hono/dist/router/trie-router/router.js
+var TrieRouter = class {
+ name = "TrieRouter";
+ #node;
+ constructor() {
+ this.#node = new Node2();
}
- strict(message) {
- errorUtil.errToObj;
- return new _ZodObject({
- ...this._def,
- unknownKeys: "strict",
- ...message !== void 0 ? {
- errorMap: (issue, ctx) => {
- const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
- if (issue.code === "unrecognized_keys")
- return {
- message: errorUtil.errToObj(message).message ?? defaultError
- };
- return {
- message: defaultError
- };
- }
- } : {}
- });
+ add(method, path5, handler) {
+ const results = checkOptionalParameter(path5);
+ if (results) {
+ for (let i = 0, len = results.length; i < len; i++) {
+ this.#node.insert(method, results[i], handler);
+ }
+ return;
+ }
+ this.#node.insert(method, path5, handler);
}
- strip() {
- return new _ZodObject({
- ...this._def,
- unknownKeys: "strip"
- });
+ match(method, path5) {
+ return this.#node.search(method, path5);
}
- passthrough() {
- return new _ZodObject({
- ...this._def,
- unknownKeys: "passthrough"
+};
+
+// node_modules/hono/dist/hono.js
+var Hono2 = class extends Hono {
+ /**
+ * Creates an instance of the Hono class.
+ *
+ * @param options - Optional configuration options for the Hono instance.
+ */
+ constructor(options = {}) {
+ super(options);
+ this.router = options.router ?? new SmartRouter({
+ routers: [new RegExpRouter(), new TrieRouter()]
});
}
- // const AugmentFactory =
- // (def: Def) =>
- // (
- // augmentation: Augmentation
- // ): ZodObject<
- // extendShape, Augmentation>,
- // Def["unknownKeys"],
- // Def["catchall"]
- // > => {
- // return new ZodObject({
- // ...def,
- // shape: () => ({
- // ...def.shape(),
- // ...augmentation,
- // }),
- // }) as any;
- // };
- extend(augmentation) {
- return new _ZodObject({
- ...this._def,
- shape: () => ({
- ...this._def.shape(),
- ...augmentation
- })
+};
+
+// src/mlclaw-space-runtime/csrf.ts
+import { createHmac as createHmac2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
+var CSRF_TTL_SECONDS = 60 * 60;
+function createCsrfToken(params) {
+ const now = params.now ?? Date.now();
+ const body = Buffer.from(JSON.stringify({
+ username: params.username,
+ nonce: randomBytes2(24).toString("base64url"),
+ exp: Math.floor(now / 1e3) + CSRF_TTL_SECONDS
+ })).toString("base64url");
+ return `${body}.${sign(body, params.sessionSecret)}`;
+}
+function verifyCsrfToken(params) {
+ if (!params.token) {
+ return false;
+ }
+ const [body, signature] = params.token.split(".");
+ if (!body || !signature || !signatureMatches(signature, sign(body, params.sessionSecret))) {
+ return false;
+ }
+ let parsed;
+ try {
+ parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
+ } catch {
+ return false;
+ }
+ if (!parsed || typeof parsed !== "object") {
+ return false;
+ }
+ const payload = parsed;
+ const now = Math.floor((params.now ?? Date.now()) / 1e3);
+ return payload.username === params.username && typeof payload.exp === "number" && payload.exp > now && typeof payload.nonce === "string" && payload.nonce.length > 0;
+}
+function sign(value, secret) {
+ return createHmac2("sha256", secret).update(value).digest("base64url");
+}
+function signatureMatches(a, b) {
+ const left = Buffer.from(a);
+ const right = Buffer.from(b);
+ return left.length === right.length && timingSafeEqual2(left, right);
+}
+
+// src/mlclaw-space-runtime/delegated-brokerkit.ts
+import { createHash as createHash2, createHmac as createHmac3, randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
+
+// src/mlclaw-space-runtime/delegated-revisions.ts
+import { randomBytes as randomBytes3 } from "node:crypto";
+var DelegatedRevisions = class {
+ epoch = randomBytes3(16).toString("base64url");
+ revision = 0;
+ material = "";
+ current;
+ waiters = /* @__PURE__ */ new Set();
+ publish(material, value) {
+ if (this.current && material === this.material) return this.current;
+ this.material = material;
+ this.revision += 1;
+ this.current = value(this.cursor());
+ for (const waiter of [...this.waiters])
+ this.finish(waiter, { api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: true });
+ return this.current;
+ }
+ wait(cursor, waitSeconds, signal) {
+ const observed = this.parse(cursor);
+ if (observed === void 0) return Promise.reject(revisionError("cursor_expired"));
+ if (observed !== this.revision) {
+ return Promise.resolve({ api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: true });
+ }
+ if (this.waiters.size >= 256) return Promise.reject(revisionError("source_unavailable"));
+ if (signal?.aborted) return Promise.reject(abortError());
+ return new Promise((resolve, reject) => {
+ const waiter = {
+ resolve,
+ reject,
+ timer: setTimeout(() => {
+ this.finish(waiter, { api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: false });
+ }, waitSeconds * 1e3),
+ ...signal ? { signal } : {}
+ };
+ waiter.timer.unref();
+ if (signal) {
+ waiter.abort = () => this.fail(waiter, abortError());
+ signal.addEventListener("abort", waiter.abort, { once: true });
+ }
+ this.waiters.add(waiter);
});
}
- /**
- * Prior to zod@1.0.12 there was a bug in the
- * inferred type of merged objects. Please
- * upgrade if you are experiencing issues.
- */
- merge(merging) {
- const merged = new _ZodObject({
- unknownKeys: merging._def.unknownKeys,
- catchall: merging._def.catchall,
- shape: () => ({
- ...this._def.shape(),
- ...merging._def.shape()
- }),
- typeName: ZodFirstPartyTypeKind.ZodObject
- });
- return merged;
+ cursor() {
+ return `${this.epoch}.${this.revision.toString(36)}`;
+ }
+ parse(value) {
+ const match2 = /^([A-Za-z0-9_-]{22})\.([0-9a-z]{1,13})$/u.exec(value);
+ if (!match2 || match2[1] !== this.epoch) return void 0;
+ const revision = Number.parseInt(match2[2] ?? "", 36);
+ return Number.isSafeInteger(revision) && revision <= this.revision ? revision : void 0;
+ }
+ finish(waiter, value) {
+ this.cleanup(waiter);
+ waiter.resolve(value);
+ }
+ fail(waiter, error) {
+ this.cleanup(waiter);
+ waiter.reject(error);
+ }
+ cleanup(waiter) {
+ if (!this.waiters.delete(waiter)) return;
+ clearTimeout(waiter.timer);
+ if (waiter.signal && waiter.abort) waiter.signal.removeEventListener("abort", waiter.abort);
+ }
+};
+function revisionError(code) {
+ return Object.assign(new Error(code), { code });
+}
+function abortError() {
+ return new DOMException("The operation was aborted", "AbortError");
+}
+
+// src/mlclaw-space-runtime/delegated-brokerkit.ts
+var API_VERSION = "brokerkit.io/delegated-web/v1";
+var TOKEN_LIFETIME_SECONDS = 4 * 60;
+var MAX_PAGES_PER_SOURCE = 32;
+var MAX_HANDLES = 4096;
+var SOURCE_DEADLINE_MS = 15e3;
+var DelegatedBrokerKit = class {
+ constructor(registry, sessionSecret, now = () => /* @__PURE__ */ new Date(), sourceDeadlineMs = SOURCE_DEADLINE_MS) {
+ this.registry = registry;
+ this.now = now;
+ this.sourceDeadlineMs = sourceDeadlineMs;
+ this.key = createHmac3("sha256", sessionSecret).update("mlclaw/brokerkit-delegated-web/v1", "utf8").digest();
+ }
+ key;
+ handles = /* @__PURE__ */ new Map();
+ handlesByIdentity = /* @__PURE__ */ new Map();
+ snapshotInFlight;
+ revisions = new DelegatedRevisions();
+ issueSession(actor, access) {
+ const issuedAt = Math.floor(this.now().getTime() / 1e3);
+ const expiresAt = issuedAt + TOKEN_LIFETIME_SECONDS;
+ const payload = {
+ version: 1,
+ audience: "brokerkit-delegated-web",
+ subject: actor,
+ issuedAt,
+ expiresAt,
+ nonce: randomBytes4(16).toString("base64url"),
+ access
+ };
+ const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
+ const signature = this.sign(encoded);
+ return {
+ api_version: API_VERSION,
+ token: `${encoded}.${signature}`,
+ expires_at: new Date(expiresAt * 1e3).toISOString(),
+ access,
+ renewal_transport: "direct"
+ };
}
- // merge<
- // Incoming extends AnyZodObject,
- // Augmentation extends Incoming["shape"],
- // NewOutput extends {
- // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation
- // ? Augmentation[k]["_output"]
- // : k extends keyof Output
- // ? Output[k]
- // : never;
- // },
- // NewInput extends {
- // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation
- // ? Augmentation[k]["_input"]
- // : k extends keyof Input
- // ? Input[k]
- // : never;
- // }
- // >(
- // merging: Incoming
- // ): ZodObject<
- // extendShape>,
- // Incoming["_def"]["unknownKeys"],
- // Incoming["_def"]["catchall"],
- // NewOutput,
- // NewInput
- // > {
- // const merged: any = new ZodObject({
- // unknownKeys: merging._def.unknownKeys,
- // catchall: merging._def.catchall,
- // shape: () =>
- // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
- // typeName: ZodFirstPartyTypeKind.ZodObject,
- // }) as any;
- // return merged;
- // }
- setKey(key, schema) {
- return this.augment({ [key]: schema });
+ authorize(token) {
+ return this.authorizeSession(token)?.actor;
}
- // merge(
- // merging: Incoming
- // ): //ZodObject = (merging) => {
- // ZodObject<
- // extendShape>,
- // Incoming["_def"]["unknownKeys"],
- // Incoming["_def"]["catchall"]
- // > {
- // // const mergedShape = objectUtil.mergeShapes(
- // // this._def.shape(),
- // // merging._def.shape()
- // // );
- // const merged: any = new ZodObject({
- // unknownKeys: merging._def.unknownKeys,
- // catchall: merging._def.catchall,
- // shape: () =>
- // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
- // typeName: ZodFirstPartyTypeKind.ZodObject,
- // }) as any;
- // return merged;
- // }
- catchall(index) {
- return new _ZodObject({
- ...this._def,
- catchall: index
- });
+ authorizeSession(token) {
+ const encoded = authenticatedTokenPayload(token, (value) => this.sign(value));
+ if (!encoded) return void 0;
+ const payload = parseTokenPayload(encoded);
+ return payload && tokenIsCurrent(payload, this.now()) ? { actor: payload.subject, sessionId: payload.nonce, access: payload.access } : void 0;
}
- pick(mask) {
- const shape = {};
- for (const key of util.objectKeys(mask)) {
- if (mask[key] && this.shape[key]) {
- shape[key] = this.shape[key];
- }
+ async snapshot() {
+ if (this.snapshotInFlight) return this.snapshotInFlight;
+ const pending = this.buildSnapshot();
+ this.snapshotInFlight = pending;
+ try {
+ return await pending;
+ } finally {
+ if (this.snapshotInFlight === pending) this.snapshotInFlight = void 0;
}
- return new _ZodObject({
- ...this._def,
- shape: () => shape
+ }
+ async buildSnapshot() {
+ this.pruneHandles();
+ const synchronizedAt = this.now().toISOString();
+ const results = await Promise.all(
+ this.registry.entries().map(async ([summary, client]) => this.sourceSnapshot(summary, client, synchronizedAt))
+ );
+ const selected = selectSnapshotRequests(results, MAX_HANDLES);
+ const reservedHandles = this.selectedExistingHandles(selected);
+ const sources = results.map((result) => result.source);
+ const requests = selected.map(
+ ({ source, request }) => project(source, request, this.handle(source.id, request, reservedHandles))
+ );
+ const material = JSON.stringify({
+ sources: sources.map((source) => ({
+ id: source.id,
+ label: source.label,
+ healthy: source.healthy,
+ ...source.error ? { error: source.error } : {}
+ })),
+ requests
});
+ return this.revisions.publish(material, (cursor) => ({
+ api_version: "brokerkit.io/operator-ui/v1",
+ cursor,
+ sources,
+ requests,
+ synchronized_at: synchronizedAt
+ }));
}
- omit(mask) {
- const shape = {};
- for (const key of util.objectKeys(this.shape)) {
- if (!mask[key]) {
- shape[key] = this.shape[key];
+ async events(cursor, waitSeconds, signal) {
+ await this.snapshot();
+ const waiting = this.revisions.wait(cursor, waitSeconds, signal);
+ const refresh = setInterval(() => void this.snapshot().catch(() => void 0), 1e3);
+ refresh.unref();
+ try {
+ return await waiting;
+ } catch (error) {
+ if (error instanceof Error && "code" in error && (error.code === "cursor_expired" || error.code === "source_unavailable")) {
+ throw delegatedError(error.code);
}
+ throw error;
+ } finally {
+ clearInterval(refresh);
}
- return new _ZodObject({
- ...this._def,
- shape: () => shape
- });
}
- /**
- * @deprecated
- */
- deepPartial() {
- return deepPartialify(this);
+ async summary() {
+ const snapshot = await this.snapshot();
+ return {
+ api_version: snapshot.api_version,
+ cursor: snapshot.cursor,
+ pending: snapshot.requests.filter((value) => value.request.status === "pending").length,
+ healthy: snapshot.sources.every((source) => source.healthy)
+ };
}
- partial(mask) {
- const newShape = {};
- for (const key of util.objectKeys(this.shape)) {
- const fieldSchema = this.shape[key];
- if (mask && !mask[key]) {
- newShape[key] = fieldSchema;
- } else {
- newShape[key] = fieldSchema.optional();
- }
- }
- return new _ZodObject({
- ...this._def,
- shape: () => newShape
- });
+ async detail(handle) {
+ const record = this.resolveHandle(handle);
+ const source = this.registry.get(record.sourceId);
+ if (!source) throw delegatedError("source_unavailable");
+ const request = await source.get(record.requestId);
+ if (request.revision !== record.revision) throw delegatedError("revision_stale");
+ return project(source.summary(), request, handle);
}
- required(mask) {
- const newShape = {};
- for (const key of util.objectKeys(this.shape)) {
- if (mask && !mask[key]) {
- newShape[key] = this.shape[key];
- } else {
- const fieldSchema = this.shape[key];
- let newField = fieldSchema;
- while (newField instanceof ZodOptional) {
- newField = newField._def.innerType;
- }
- newShape[key] = newField;
- }
+ async decide(handle, action, expectedRevision, actor, options = {}) {
+ const record = this.resolveHandle(handle);
+ const source = this.registry.get(record.sourceId);
+ if (!source) throw delegatedError("source_unavailable");
+ const current = await source.get(record.requestId);
+ assertDecisionAllowed(current, record, action, expectedRevision, options);
+ const decision = decisionOptions(record, action, expectedRevision, actor, options);
+ const updated = await decideWithRecovery(source, record.requestId, action, decision);
+ if (updated.status === "pending" || updated.status === "active") {
+ this.removeHandle(handle, record);
+ return project(source.summary(), updated, this.handle(record.sourceId, updated));
}
- return new _ZodObject({
- ...this._def,
- shape: () => newShape
- });
- }
- keyof() {
- return createZodEnum(util.objectKeys(this.shape));
+ this.removeHandle(handle, record);
+ return project(source.summary(), updated, handle);
}
-};
-ZodObject.create = (shape, params) => {
- return new ZodObject({
- shape: () => shape,
- unknownKeys: "strip",
- catchall: ZodNever.create(),
- typeName: ZodFirstPartyTypeKind.ZodObject,
- ...processCreateParams(params)
- });
-};
-ZodObject.strictCreate = (shape, params) => {
- return new ZodObject({
- shape: () => shape,
- unknownKeys: "strict",
- catchall: ZodNever.create(),
- typeName: ZodFirstPartyTypeKind.ZodObject,
- ...processCreateParams(params)
- });
-};
-ZodObject.lazycreate = (shape, params) => {
- return new ZodObject({
- shape,
- unknownKeys: "strip",
- catchall: ZodNever.create(),
- typeName: ZodFirstPartyTypeKind.ZodObject,
- ...processCreateParams(params)
- });
-};
-var ZodUnion = class extends ZodType {
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- const options = this._def.options;
- function handleResults(results) {
- for (const result of results) {
- if (result.result.status === "valid") {
- return result.result;
- }
- }
- for (const result of results) {
- if (result.result.status === "dirty") {
- ctx.common.issues.push(...result.ctx.common.issues);
- return result.result;
- }
- }
- const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_union,
- unionErrors
- });
- return INVALID;
+ async sourceSnapshot(summary, client, synchronizedAt) {
+ const deadline = new AbortController();
+ const timer = setTimeout(() => deadline.abort(), this.sourceDeadlineMs);
+ timer.unref?.();
+ try {
+ await client.discover(deadline.signal);
+ const pages = await Promise.all([
+ this.sourceRequests(client, "pending", deadline.signal),
+ this.sourceRequests(client, "active", deadline.signal)
+ ]);
+ const requests = reconcileRequests(pages.map((page2) => page2.requests));
+ return {
+ source: deadline.signal.aborted ? { ...summary, healthy: false, error: "broker_timeout" } : pages.some((page2) => page2.truncated) ? { ...summary, healthy: false, error: "source_truncated" } : { ...summary, healthy: true, last_sync_at: synchronizedAt },
+ requests
+ };
+ } catch (error) {
+ return {
+ source: { ...summary, healthy: false, error: safeSourceError(error) },
+ requests: []
+ };
+ } finally {
+ clearTimeout(timer);
}
- if (ctx.common.async) {
- return Promise.all(options.map(async (option) => {
- const childCtx = {
- ...ctx,
- common: {
- ...ctx.common,
- issues: []
- },
- parent: null
- };
- return {
- result: await option._parseAsync({
- data: ctx.data,
- path: ctx.path,
- parent: childCtx
- }),
- ctx: childCtx
- };
- })).then(handleResults);
- } else {
- let dirty = void 0;
- const issues = [];
- for (const option of options) {
- const childCtx = {
- ...ctx,
- common: {
- ...ctx.common,
- issues: []
- },
- parent: null
- };
- const result = option._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: childCtx
- });
- if (result.status === "valid") {
- return result;
- } else if (result.status === "dirty" && !dirty) {
- dirty = { result, ctx: childCtx };
- }
- if (childCtx.common.issues.length) {
- issues.push(childCtx.common.issues);
- }
- }
- if (dirty) {
- ctx.common.issues.push(...dirty.ctx.common.issues);
- return dirty.result;
+ }
+ async sourceRequests(client, status, signal) {
+ const requests = [];
+ let cursor;
+ try {
+ for (let pageNumber = 0; pageNumber < MAX_PAGES_PER_SOURCE; pageNumber += 1) {
+ const page2 = await client.list({ status, ...cursor ? { cursor } : {}, limit: 100 }, signal);
+ requests.push(...page2.requests);
+ cursor = page2.next_cursor;
+ if (!cursor) return { requests, truncated: false };
}
- const unionErrors = issues.map((issues2) => new ZodError(issues2));
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_union,
- unionErrors
- });
- return INVALID;
+ } catch (error) {
+ if (!signal.aborted) throw error;
}
+ return { requests, truncated: Boolean(cursor) };
}
- get options() {
- return this._def.options;
- }
-};
-ZodUnion.create = (types, params) => {
- return new ZodUnion({
- options: types,
- typeName: ZodFirstPartyTypeKind.ZodUnion,
- ...processCreateParams(params)
- });
-};
-var getDiscriminator = (type) => {
- if (type instanceof ZodLazy) {
- return getDiscriminator(type.schema);
- } else if (type instanceof ZodEffects) {
- return getDiscriminator(type.innerType());
- } else if (type instanceof ZodLiteral) {
- return [type.value];
- } else if (type instanceof ZodEnum) {
- return type.options;
- } else if (type instanceof ZodNativeEnum) {
- return util.objectValues(type.enum);
- } else if (type instanceof ZodDefault) {
- return getDiscriminator(type._def.innerType);
- } else if (type instanceof ZodUndefined) {
- return [void 0];
- } else if (type instanceof ZodNull) {
- return [null];
- } else if (type instanceof ZodOptional) {
- return [void 0, ...getDiscriminator(type.unwrap())];
- } else if (type instanceof ZodNullable) {
- return [null, ...getDiscriminator(type.unwrap())];
- } else if (type instanceof ZodBranded) {
- return getDiscriminator(type.unwrap());
- } else if (type instanceof ZodReadonly) {
- return getDiscriminator(type.unwrap());
- } else if (type instanceof ZodCatch) {
- return getDiscriminator(type._def.innerType);
- } else {
- return [];
+ selectedExistingHandles(selected) {
+ const handles = /* @__PURE__ */ new Set();
+ for (const { source, request } of selected) {
+ const handle = this.handlesByIdentity.get(requestIdentity(source.id, request.id, request.revision));
+ if (handle && this.handles.has(handle)) handles.add(handle);
+ }
+ return handles;
}
-};
-var ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType {
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.object) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.object,
- received: ctx.parsedType
- });
- return INVALID;
+ handle(sourceId, request, reservedHandles = /* @__PURE__ */ new Set()) {
+ const identity = requestIdentity(sourceId, request.id, request.revision);
+ const existing = this.handlesByIdentity.get(identity);
+ if (existing && this.handles.has(existing)) {
+ reservedHandles.add(existing);
+ return existing;
}
- const discriminator = this.discriminator;
- const discriminatorValue = ctx.data[discriminator];
- const option = this.optionsMap.get(discriminatorValue);
- if (!option) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_union_discriminator,
- options: Array.from(this.optionsMap.keys()),
- path: [discriminator]
- });
- return INVALID;
+ if (this.handles.size >= MAX_HANDLES && !this.pruneOldestHandle(reservedHandles)) {
+ throw delegatedError("source_unavailable");
}
- if (ctx.common.async) {
- return option._parseAsync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
- } else {
- return option._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
+ const handle = randomBytes4(18).toString("base64url");
+ const requestExpiry = Date.parse(handleExpiry(request));
+ const expiresAtMs = Number.isFinite(requestExpiry) ? Math.min(requestExpiry, this.now().getTime() + 24 * 60 * 6e4) : this.now().getTime() + 5 * 6e4;
+ this.handles.set(handle, { sourceId, requestId: request.id, revision: request.revision, expiresAtMs });
+ this.handlesByIdentity.set(identity, handle);
+ reservedHandles.add(handle);
+ return handle;
+ }
+ resolveHandle(handle) {
+ if (!/^[A-Za-z0-9_-]{24}$/u.test(handle)) throw delegatedError("request_not_found");
+ const record = this.handles.get(handle);
+ if (!record || record.expiresAtMs <= this.now().getTime()) {
+ if (record) this.removeHandle(handle, record);
+ throw delegatedError("request_not_found");
}
+ return record;
}
- get discriminator() {
- return this._def.discriminator;
+ pruneHandles() {
+ for (const [handle, record] of this.handles) {
+ if (record.expiresAtMs <= this.now().getTime()) this.removeHandle(handle, record);
+ }
}
- get options() {
- return this._def.options;
+ pruneOldestHandle(reservedHandles) {
+ for (const [handle, record] of this.handles) {
+ if (reservedHandles.has(handle)) continue;
+ this.removeHandle(handle, record);
+ return true;
+ }
+ return false;
}
- get optionsMap() {
- return this._def.optionsMap;
+ removeHandle(handle, record) {
+ this.handles.delete(handle);
+ this.handlesByIdentity.delete(requestIdentity(record.sourceId, record.requestId, record.revision));
}
- /**
- * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.
- * However, it only allows a union of objects, all of which need to share a discriminator property. This property must
- * have a different value for each object in the union.
- * @param discriminator the name of the discriminator property
- * @param types an array of object schemas
- * @param params
- */
- static create(discriminator, options, params) {
- const optionsMap = /* @__PURE__ */ new Map();
- for (const type of options) {
- const discriminatorValues = getDiscriminator(type.shape[discriminator]);
- if (!discriminatorValues.length) {
- throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
- }
- for (const value of discriminatorValues) {
- if (optionsMap.has(value)) {
- throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
- }
- optionsMap.set(value, type);
- }
- }
- return new _ZodDiscriminatedUnion({
- typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
- discriminator,
- options,
- optionsMap,
- ...processCreateParams(params)
- });
+ sign(encoded) {
+ return createHmac3("sha256", this.key).update(encoded, "utf8").digest("base64url");
}
};
-function mergeValues(a, b) {
- const aType = getParsedType(a);
- const bType = getParsedType(b);
- if (a === b) {
- return { valid: true, data: a };
- } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
- const bKeys = util.objectKeys(b);
- const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
- const newObj = { ...a, ...b };
- for (const key of sharedKeys) {
- const sharedValue = mergeValues(a[key], b[key]);
- if (!sharedValue.valid) {
- return { valid: false };
- }
- newObj[key] = sharedValue.data;
+async function decideWithRecovery(source, requestId, action, decision) {
+ try {
+ return await source.decide(requestId, action, decision);
+ } catch (error) {
+ if (error instanceof BrokerOperatorError) throw error;
+ try {
+ await source.get(requestId);
+ } catch {
+ throw delegatedError("source_unavailable");
}
- return { valid: true, data: newObj };
- } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
- if (a.length !== b.length) {
- return { valid: false };
+ try {
+ return await source.decide(requestId, action, decision);
+ } catch (retryError) {
+ if (retryError instanceof BrokerOperatorError) throw retryError;
+ throw delegatedError("source_unavailable");
}
- const newArray = [];
- for (let index = 0; index < a.length; index++) {
- const itemA = a[index];
- const itemB = b[index];
- const sharedValue = mergeValues(itemA, itemB);
- if (!sharedValue.valid) {
- return { valid: false };
- }
- newArray.push(sharedValue.data);
+ }
+}
+function selectSnapshotRequests(results, limit) {
+ const buckets = results.flatMap(
+ (result) => ["pending", "active"].map((status) => ({
+ source: result.source,
+ requests: result.requests.filter((request) => request.status === status),
+ index: 0
+ }))
+ );
+ const selected = [];
+ while (selected.length < limit) {
+ let added = false;
+ for (const bucket of buckets) {
+ const request = bucket.requests[bucket.index];
+ if (!request) continue;
+ selected.push({ source: bucket.source, request });
+ bucket.index += 1;
+ added = true;
+ if (selected.length === limit) break;
}
- return { valid: true, data: newArray };
- } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {
- return { valid: true, data: a };
- } else {
- return { valid: false };
+ if (!added) break;
+ }
+ return selected;
+}
+function reconcileRequests(pages) {
+ const requests = /* @__PURE__ */ new Map();
+ for (const request of pages.flat()) {
+ const current = requests.get(request.id);
+ if (!current || request.revision > current.revision || request.revision === current.revision && request.status === "active" && current.status !== "active") {
+ requests.set(request.id, request);
+ }
+ }
+ return [...requests.values()];
+}
+var DelegatedBrokerKitError = class extends Error {
+ constructor(code) {
+ super(code);
+ this.code = code;
+ }
+};
+function delegatedError(code) {
+ return new DelegatedBrokerKitError(code);
+}
+function project(source, request, handle) {
+ return { source_id: source.id, source_label: source.label, handle, request };
+}
+function requestIdentity(sourceId, requestId, revision) {
+ return `${sourceId}\0${requestId}\0${revision}`;
+}
+function handleExpiry(request) {
+ if (request.status === "active") return request.active_expires_at ?? "";
+ return request.pending_expires_at ?? request.active_expires_at ?? "";
+}
+function decisionKey(record, action, actor) {
+ return createHash2("sha256").update(
+ ["mlclaw-brokerkit-decision-v1", record.sourceId, record.requestId, String(record.revision), action, actor].join(
+ "\0"
+ ),
+ "utf8"
+ ).digest("base64url");
+}
+function decisionOptions(record, action, expectedRevision, actor, options) {
+ return {
+ expectedRevision,
+ idempotencyKey: decisionKey(record, action, actor),
+ onBehalfOf: `mlclaw:${actor}`,
+ ...options.durationSeconds ? { durationSeconds: options.durationSeconds } : {},
+ ...options.maxUses !== void 0 ? { maxUses: options.maxUses } : {}
+ };
+}
+function decisionWithinBounds(action, request, options) {
+ if (options.durationSeconds === void 0 && options.maxUses === void 0) return true;
+ const bounds = request.approval_bounds;
+ return Boolean(
+ action === "approve" && bounds && options.durationSeconds !== void 0 && options.durationSeconds <= bounds.max_duration_seconds && useLimitWithinBounds(options.maxUses, bounds.max_uses)
+ );
+}
+function useLimitWithinBounds(requested, maximum) {
+ if (requested === void 0) return false;
+ if (requested === null) return maximum === null;
+ return maximum === null || requested <= maximum;
+}
+function assertDecisionAllowed(request, record, action, expectedRevision, options) {
+ if (request.revision !== record.revision || request.revision !== expectedRevision) {
+ throw delegatedError("revision_stale");
+ }
+ if (!request.allowed_actions.includes(action) || !decisionWithinBounds(action, request, options)) {
+ throw delegatedError("action_not_allowed");
+ }
+}
+function authenticatedTokenPayload(token, sign3) {
+ if (!token || token.length > 4096 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/u.test(token)) return void 0;
+ const [encoded, signature, extra] = token.split(".");
+ return encoded && signature && extra === void 0 && safeEqual(signature, sign3(encoded)) ? encoded : void 0;
+}
+function parseTokenPayload(encoded) {
+ try {
+ const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
+ return validTokenPayload(payload) ? payload : void 0;
+ } catch {
+ return void 0;
+ }
+}
+function tokenIsCurrent(payload, now) {
+ const current = Math.floor(now.getTime() / 1e3);
+ return payload.issuedAt <= current + 5 && payload.expiresAt > current && payload.expiresAt - payload.issuedAt <= TOKEN_LIFETIME_SECONDS;
+}
+function validTokenPayload(value) {
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
+ const record = value;
+ return hasExactTokenFields(record) && validTokenIdentity(record) && validTokenTimes(record) && validTokenNonce(record);
+}
+function hasExactTokenFields(record) {
+ return Object.keys(record).sort().join(",") === "access,audience,expiresAt,issuedAt,nonce,subject,version";
+}
+function validTokenIdentity(record) {
+ return record.version === 1 && record.audience === "brokerkit-delegated-web" && (record.access === "read" || record.access === "decide") && typeof record.subject === "string" && record.subject.length >= 1 && record.subject.length <= 200;
+}
+function validTokenTimes(record) {
+ return typeof record.issuedAt === "number" && Number.isSafeInteger(record.issuedAt) && typeof record.expiresAt === "number" && Number.isSafeInteger(record.expiresAt);
+}
+function validTokenNonce(record) {
+ return typeof record.nonce === "string" && /^[A-Za-z0-9_-]{22}$/u.test(record.nonce);
+}
+function safeEqual(left, right) {
+ const a = Buffer.from(left, "utf8");
+ const b = Buffer.from(right, "utf8");
+ return a.length === b.length && timingSafeEqual3(a, b);
+}
+function safeSourceError(error) {
+ const code = error instanceof BrokerOperatorError ? error.code : error instanceof DelegatedBrokerKitError ? error.code : void 0;
+ if (code === "broker_timeout" || code === "unavailable" || code === "source_unavailable") return code;
+ return "source_unavailable";
+}
+
+// src/mlclaw-space-runtime/hub-settings.ts
+function runtimeSettings(config2) {
+ return {
+ agentName: config2.agentName ?? null,
+ model: config2.model,
+ stateBucket: config2.stateBucket ?? null,
+ stateMountDir: config2.stateMountDir ?? null,
+ statePrefix: config2.statePrefix ?? null,
+ gatewayLocation: config2.gatewayLocation ?? null,
+ runtimeImage: config2.runtimeImage ?? null,
+ runtimeId: config2.runtimeId ?? null,
+ templateRev: config2.templateRev ?? null,
+ allowedUsers: config2.allowedUsers,
+ adminUsers: config2.adminUsers,
+ modelChoices: config2.modelChoices,
+ presetModels: PRESET_MODEL_CHOICES,
+ branding: publicBranding(config2.branding)
+ };
+}
+function normalizeModel(value) {
+ return normalizeModelRef(value);
+}
+async function setCurrentSpaceVariable(config2, key, value) {
+ if (!config2.spaceId || !config2.hfToken) {
+ throw new Error("Space mutation requires SPACE_ID and HF_TOKEN");
+ }
+ await hubRequest(config2, `/api/spaces/${config2.spaceId}/variables`, {
+ method: "POST",
+ body: JSON.stringify({ key, value }),
+ headers: { "content-type": "application/json" }
+ });
+}
+async function setCurrentSpaceSecret(config2, key, value) {
+ if (!config2.spaceId || !config2.hfToken) {
+ throw new Error("Space mutation requires SPACE_ID and HF_TOKEN");
}
+ await hubRequest(config2, `/api/spaces/${config2.spaceId}/secrets`, {
+ method: "POST",
+ body: JSON.stringify({ key, value }),
+ headers: { "content-type": "application/json" }
+ });
}
-var ZodIntersection = class extends ZodType {
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- const handleParsed = (parsedLeft, parsedRight) => {
- if (isAborted(parsedLeft) || isAborted(parsedRight)) {
- return INVALID;
- }
- const merged = mergeValues(parsedLeft.value, parsedRight.value);
- if (!merged.valid) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_intersection_types
- });
- return INVALID;
- }
- if (isDirty(parsedLeft) || isDirty(parsedRight)) {
- status.dirty();
- }
- return { status: status.value, value: merged.data };
- };
- if (ctx.common.async) {
- return Promise.all([
- this._def.left._parseAsync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- }),
- this._def.right._parseAsync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- })
- ]).then(([left, right]) => handleParsed(left, right));
- } else {
- return handleParsed(this._def.left._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- }), this._def.right._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- }));
- }
+async function restartCurrentSpace(config2) {
+ if (!config2.spaceId || !config2.hfToken) {
+ return false;
}
-};
-ZodIntersection.create = (left, right, params) => {
- return new ZodIntersection({
- left,
- right,
- typeName: ZodFirstPartyTypeKind.ZodIntersection,
- ...processCreateParams(params)
+ await hubRequest(config2, `/api/spaces/${config2.spaceId}/restart`, {
+ method: "POST",
+ body: JSON.stringify({ factoryReboot: false }),
+ headers: { "content-type": "application/json" }
});
-};
-var ZodTuple = class _ZodTuple extends ZodType {
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.array) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.array,
- received: ctx.parsedType
- });
- return INVALID;
+ return true;
+}
+async function hubRequest(config2, path5, init) {
+ const response = await fetch(`${config2.hubUrl.replace(/\/+$/, "")}${path5}`, {
+ ...init,
+ headers: {
+ authorization: `Bearer ${config2.hfToken}`,
+ ...init.headers
}
- if (ctx.data.length < this._def.items.length) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: this._def.items.length,
- inclusive: true,
- exact: false,
- type: "array"
- });
- return INVALID;
+ });
+ if (!response.ok) {
+ throw new Error(`Hub request failed: ${response.status} ${await response.text()}`);
+ }
+ return response;
+}
+
+// node_modules/zod/v3/external.js
+var external_exports = {};
+__export(external_exports, {
+ BRAND: () => BRAND,
+ DIRTY: () => DIRTY,
+ EMPTY_PATH: () => EMPTY_PATH,
+ INVALID: () => INVALID,
+ NEVER: () => NEVER,
+ OK: () => OK,
+ ParseStatus: () => ParseStatus,
+ Schema: () => ZodType,
+ ZodAny: () => ZodAny,
+ ZodArray: () => ZodArray,
+ ZodBigInt: () => ZodBigInt,
+ ZodBoolean: () => ZodBoolean,
+ ZodBranded: () => ZodBranded,
+ ZodCatch: () => ZodCatch,
+ ZodDate: () => ZodDate,
+ ZodDefault: () => ZodDefault,
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
+ ZodEffects: () => ZodEffects,
+ ZodEnum: () => ZodEnum,
+ ZodError: () => ZodError,
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
+ ZodFunction: () => ZodFunction,
+ ZodIntersection: () => ZodIntersection,
+ ZodIssueCode: () => ZodIssueCode,
+ ZodLazy: () => ZodLazy,
+ ZodLiteral: () => ZodLiteral,
+ ZodMap: () => ZodMap,
+ ZodNaN: () => ZodNaN,
+ ZodNativeEnum: () => ZodNativeEnum,
+ ZodNever: () => ZodNever,
+ ZodNull: () => ZodNull,
+ ZodNullable: () => ZodNullable,
+ ZodNumber: () => ZodNumber,
+ ZodObject: () => ZodObject,
+ ZodOptional: () => ZodOptional,
+ ZodParsedType: () => ZodParsedType,
+ ZodPipeline: () => ZodPipeline,
+ ZodPromise: () => ZodPromise,
+ ZodReadonly: () => ZodReadonly,
+ ZodRecord: () => ZodRecord,
+ ZodSchema: () => ZodType,
+ ZodSet: () => ZodSet,
+ ZodString: () => ZodString,
+ ZodSymbol: () => ZodSymbol,
+ ZodTransformer: () => ZodEffects,
+ ZodTuple: () => ZodTuple,
+ ZodType: () => ZodType,
+ ZodUndefined: () => ZodUndefined,
+ ZodUnion: () => ZodUnion,
+ ZodUnknown: () => ZodUnknown,
+ ZodVoid: () => ZodVoid,
+ addIssueToContext: () => addIssueToContext,
+ any: () => anyType,
+ array: () => arrayType,
+ bigint: () => bigIntType,
+ boolean: () => booleanType,
+ coerce: () => coerce,
+ custom: () => custom,
+ date: () => dateType,
+ datetimeRegex: () => datetimeRegex,
+ defaultErrorMap: () => en_default,
+ discriminatedUnion: () => discriminatedUnionType,
+ effect: () => effectsType,
+ enum: () => enumType,
+ function: () => functionType,
+ getErrorMap: () => getErrorMap,
+ getParsedType: () => getParsedType,
+ instanceof: () => instanceOfType,
+ intersection: () => intersectionType,
+ isAborted: () => isAborted,
+ isAsync: () => isAsync,
+ isDirty: () => isDirty,
+ isValid: () => isValid,
+ late: () => late,
+ lazy: () => lazyType,
+ literal: () => literalType,
+ makeIssue: () => makeIssue,
+ map: () => mapType,
+ nan: () => nanType,
+ nativeEnum: () => nativeEnumType,
+ never: () => neverType,
+ null: () => nullType,
+ nullable: () => nullableType,
+ number: () => numberType,
+ object: () => objectType,
+ objectUtil: () => objectUtil,
+ oboolean: () => oboolean,
+ onumber: () => onumber,
+ optional: () => optionalType,
+ ostring: () => ostring,
+ pipeline: () => pipelineType,
+ preprocess: () => preprocessType,
+ promise: () => promiseType,
+ quotelessJson: () => quotelessJson,
+ record: () => recordType,
+ set: () => setType,
+ setErrorMap: () => setErrorMap,
+ strictObject: () => strictObjectType,
+ string: () => stringType,
+ symbol: () => symbolType,
+ transformer: () => effectsType,
+ tuple: () => tupleType,
+ undefined: () => undefinedType,
+ union: () => unionType,
+ unknown: () => unknownType,
+ util: () => util,
+ void: () => voidType
+});
+
+// node_modules/zod/v3/helpers/util.js
+var util;
+(function(util2) {
+ util2.assertEqual = (_) => {
+ };
+ function assertIs(_arg) {
+ }
+ util2.assertIs = assertIs;
+ function assertNever(_x) {
+ throw new Error();
+ }
+ util2.assertNever = assertNever;
+ util2.arrayToEnum = (items) => {
+ const obj = {};
+ for (const item of items) {
+ obj[item] = item;
}
- const rest = this._def.rest;
- if (!rest && ctx.data.length > this._def.items.length) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: this._def.items.length,
- inclusive: true,
- exact: false,
- type: "array"
- });
- status.dirty();
+ return obj;
+ };
+ util2.getValidEnumValues = (obj) => {
+ const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
+ const filtered = {};
+ for (const k of validKeys) {
+ filtered[k] = obj[k];
+ }
+ return util2.objectValues(filtered);
+ };
+ util2.objectValues = (obj) => {
+ return util2.objectKeys(obj).map(function(e) {
+ return obj[e];
+ });
+ };
+ util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object2) => {
+ const keys = [];
+ for (const key in object2) {
+ if (Object.prototype.hasOwnProperty.call(object2, key)) {
+ keys.push(key);
+ }
}
- const items = [...ctx.data].map((item, itemIndex) => {
- const schema = this._def.items[itemIndex] || this._def.rest;
- if (!schema)
- return null;
- return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
- }).filter((x) => !!x);
- if (ctx.common.async) {
- return Promise.all(items).then((results) => {
- return ParseStatus.mergeArray(status, results);
- });
- } else {
- return ParseStatus.mergeArray(status, items);
+ return keys;
+ };
+ util2.find = (arr, checker) => {
+ for (const item of arr) {
+ if (checker(item))
+ return item;
}
+ return void 0;
+ };
+ util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
+ function joinValues(array, separator = " | ") {
+ return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
}
- get items() {
- return this._def.items;
- }
- rest(rest) {
- return new _ZodTuple({
- ...this._def,
- rest
- });
+ util2.joinValues = joinValues;
+ util2.jsonStringifyReplacer = (_, value) => {
+ if (typeof value === "bigint") {
+ return value.toString();
+ }
+ return value;
+ };
+})(util || (util = {}));
+var objectUtil;
+(function(objectUtil2) {
+ objectUtil2.mergeShapes = (first, second) => {
+ return {
+ ...first,
+ ...second
+ // second overwrites first
+ };
+ };
+})(objectUtil || (objectUtil = {}));
+var ZodParsedType = util.arrayToEnum([
+ "string",
+ "nan",
+ "number",
+ "integer",
+ "float",
+ "boolean",
+ "date",
+ "bigint",
+ "symbol",
+ "function",
+ "undefined",
+ "null",
+ "array",
+ "object",
+ "unknown",
+ "promise",
+ "void",
+ "never",
+ "map",
+ "set"
+]);
+var getParsedType = (data) => {
+ const t = typeof data;
+ switch (t) {
+ case "undefined":
+ return ZodParsedType.undefined;
+ case "string":
+ return ZodParsedType.string;
+ case "number":
+ return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
+ case "boolean":
+ return ZodParsedType.boolean;
+ case "function":
+ return ZodParsedType.function;
+ case "bigint":
+ return ZodParsedType.bigint;
+ case "symbol":
+ return ZodParsedType.symbol;
+ case "object":
+ if (Array.isArray(data)) {
+ return ZodParsedType.array;
+ }
+ if (data === null) {
+ return ZodParsedType.null;
+ }
+ if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
+ return ZodParsedType.promise;
+ }
+ if (typeof Map !== "undefined" && data instanceof Map) {
+ return ZodParsedType.map;
+ }
+ if (typeof Set !== "undefined" && data instanceof Set) {
+ return ZodParsedType.set;
+ }
+ if (typeof Date !== "undefined" && data instanceof Date) {
+ return ZodParsedType.date;
+ }
+ return ZodParsedType.object;
+ default:
+ return ZodParsedType.unknown;
}
};
-ZodTuple.create = (schemas, params) => {
- if (!Array.isArray(schemas)) {
- throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
- }
- return new ZodTuple({
- items: schemas,
- typeName: ZodFirstPartyTypeKind.ZodTuple,
- rest: null,
- ...processCreateParams(params)
- });
+
+// node_modules/zod/v3/ZodError.js
+var ZodIssueCode = util.arrayToEnum([
+ "invalid_type",
+ "invalid_literal",
+ "custom",
+ "invalid_union",
+ "invalid_union_discriminator",
+ "invalid_enum_value",
+ "unrecognized_keys",
+ "invalid_arguments",
+ "invalid_return_type",
+ "invalid_date",
+ "invalid_string",
+ "too_small",
+ "too_big",
+ "invalid_intersection_types",
+ "not_multiple_of",
+ "not_finite"
+]);
+var quotelessJson = (obj) => {
+ const json = JSON.stringify(obj, null, 2);
+ return json.replace(/"([^"]+)":/g, "$1:");
};
-var ZodRecord = class _ZodRecord extends ZodType {
- get keySchema() {
- return this._def.keyType;
- }
- get valueSchema() {
- return this._def.valueType;
+var ZodError = class _ZodError extends Error {
+ get errors() {
+ return this.issues;
}
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.object) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.object,
- received: ctx.parsedType
- });
- return INVALID;
- }
- const pairs = [];
- const keyType = this._def.keyType;
- const valueType = this._def.valueType;
- for (const key in ctx.data) {
- pairs.push({
- key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
- value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
- alwaysSet: key in ctx.data
- });
- }
- if (ctx.common.async) {
- return ParseStatus.mergeObjectAsync(status, pairs);
+ constructor(issues) {
+ super();
+ this.issues = [];
+ this.addIssue = (sub) => {
+ this.issues = [...this.issues, sub];
+ };
+ this.addIssues = (subs = []) => {
+ this.issues = [...this.issues, ...subs];
+ };
+ const actualProto = new.target.prototype;
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(this, actualProto);
} else {
- return ParseStatus.mergeObjectSync(status, pairs);
+ this.__proto__ = actualProto;
}
+ this.name = "ZodError";
+ this.issues = issues;
}
- get element() {
- return this._def.valueType;
+ format(_mapper) {
+ const mapper = _mapper || function(issue) {
+ return issue.message;
+ };
+ const fieldErrors = { _errors: [] };
+ const processError = (error) => {
+ for (const issue of error.issues) {
+ if (issue.code === "invalid_union") {
+ issue.unionErrors.map(processError);
+ } else if (issue.code === "invalid_return_type") {
+ processError(issue.returnTypeError);
+ } else if (issue.code === "invalid_arguments") {
+ processError(issue.argumentsError);
+ } else if (issue.path.length === 0) {
+ fieldErrors._errors.push(mapper(issue));
+ } else {
+ let curr = fieldErrors;
+ let i = 0;
+ while (i < issue.path.length) {
+ const el = issue.path[i];
+ const terminal = i === issue.path.length - 1;
+ if (!terminal) {
+ curr[el] = curr[el] || { _errors: [] };
+ } else {
+ curr[el] = curr[el] || { _errors: [] };
+ curr[el]._errors.push(mapper(issue));
+ }
+ curr = curr[el];
+ i++;
+ }
+ }
+ }
+ };
+ processError(this);
+ return fieldErrors;
}
- static create(first, second, third) {
- if (second instanceof ZodType) {
- return new _ZodRecord({
- keyType: first,
- valueType: second,
- typeName: ZodFirstPartyTypeKind.ZodRecord,
- ...processCreateParams(third)
- });
+ static assert(value) {
+ if (!(value instanceof _ZodError)) {
+ throw new Error(`Not a ZodError: ${value}`);
}
- return new _ZodRecord({
- keyType: ZodString.create(),
- valueType: first,
- typeName: ZodFirstPartyTypeKind.ZodRecord,
- ...processCreateParams(second)
- });
}
-};
-var ZodMap = class extends ZodType {
- get keySchema() {
- return this._def.keyType;
+ toString() {
+ return this.message;
}
- get valueSchema() {
- return this._def.valueType;
+ get message() {
+ return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
}
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.map) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.map,
- received: ctx.parsedType
- });
- return INVALID;
+ get isEmpty() {
+ return this.issues.length === 0;
+ }
+ flatten(mapper = (issue) => issue.message) {
+ const fieldErrors = {};
+ const formErrors = [];
+ for (const sub of this.issues) {
+ if (sub.path.length > 0) {
+ const firstEl = sub.path[0];
+ fieldErrors[firstEl] = fieldErrors[firstEl] || [];
+ fieldErrors[firstEl].push(mapper(sub));
+ } else {
+ formErrors.push(mapper(sub));
+ }
}
- const keyType = this._def.keyType;
- const valueType = this._def.valueType;
- const pairs = [...ctx.data.entries()].map(([key, value], index) => {
- return {
- key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
- value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
- };
- });
- if (ctx.common.async) {
- const finalMap = /* @__PURE__ */ new Map();
- return Promise.resolve().then(async () => {
- for (const pair of pairs) {
- const key = await pair.key;
- const value = await pair.value;
- if (key.status === "aborted" || value.status === "aborted") {
- return INVALID;
- }
- if (key.status === "dirty" || value.status === "dirty") {
- status.dirty();
+ return { formErrors, fieldErrors };
+ }
+ get formErrors() {
+ return this.flatten();
+ }
+};
+ZodError.create = (issues) => {
+ const error = new ZodError(issues);
+ return error;
+};
+
+// node_modules/zod/v3/locales/en.js
+var errorMap = (issue, _ctx) => {
+ let message;
+ switch (issue.code) {
+ case ZodIssueCode.invalid_type:
+ if (issue.received === ZodParsedType.undefined) {
+ message = "Required";
+ } else {
+ message = `Expected ${issue.expected}, received ${issue.received}`;
+ }
+ break;
+ case ZodIssueCode.invalid_literal:
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
+ break;
+ case ZodIssueCode.unrecognized_keys:
+ message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
+ break;
+ case ZodIssueCode.invalid_union:
+ message = `Invalid input`;
+ break;
+ case ZodIssueCode.invalid_union_discriminator:
+ message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
+ break;
+ case ZodIssueCode.invalid_enum_value:
+ message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
+ break;
+ case ZodIssueCode.invalid_arguments:
+ message = `Invalid function arguments`;
+ break;
+ case ZodIssueCode.invalid_return_type:
+ message = `Invalid function return type`;
+ break;
+ case ZodIssueCode.invalid_date:
+ message = `Invalid date`;
+ break;
+ case ZodIssueCode.invalid_string:
+ if (typeof issue.validation === "object") {
+ if ("includes" in issue.validation) {
+ message = `Invalid input: must include "${issue.validation.includes}"`;
+ if (typeof issue.validation.position === "number") {
+ message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
}
- finalMap.set(key.value, value.value);
- }
- return { status: status.value, value: finalMap };
- });
- } else {
- const finalMap = /* @__PURE__ */ new Map();
- for (const pair of pairs) {
- const key = pair.key;
- const value = pair.value;
- if (key.status === "aborted" || value.status === "aborted") {
- return INVALID;
- }
- if (key.status === "dirty" || value.status === "dirty") {
- status.dirty();
+ } else if ("startsWith" in issue.validation) {
+ message = `Invalid input: must start with "${issue.validation.startsWith}"`;
+ } else if ("endsWith" in issue.validation) {
+ message = `Invalid input: must end with "${issue.validation.endsWith}"`;
+ } else {
+ util.assertNever(issue.validation);
}
- finalMap.set(key.value, value.value);
+ } else if (issue.validation !== "regex") {
+ message = `Invalid ${issue.validation}`;
+ } else {
+ message = "Invalid";
}
- return { status: status.value, value: finalMap };
- }
+ break;
+ case ZodIssueCode.too_small:
+ if (issue.type === "array")
+ message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
+ else if (issue.type === "string")
+ message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
+ else if (issue.type === "number")
+ message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
+ else if (issue.type === "bigint")
+ message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
+ else if (issue.type === "date")
+ message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
+ else
+ message = "Invalid input";
+ break;
+ case ZodIssueCode.too_big:
+ if (issue.type === "array")
+ message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
+ else if (issue.type === "string")
+ message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
+ else if (issue.type === "number")
+ message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
+ else if (issue.type === "bigint")
+ message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
+ else if (issue.type === "date")
+ message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
+ else
+ message = "Invalid input";
+ break;
+ case ZodIssueCode.custom:
+ message = `Invalid input`;
+ break;
+ case ZodIssueCode.invalid_intersection_types:
+ message = `Intersection results could not be merged`;
+ break;
+ case ZodIssueCode.not_multiple_of:
+ message = `Number must be a multiple of ${issue.multipleOf}`;
+ break;
+ case ZodIssueCode.not_finite:
+ message = "Number must be finite";
+ break;
+ default:
+ message = _ctx.defaultError;
+ util.assertNever(issue);
}
+ return { message };
};
-ZodMap.create = (keyType, valueType, params) => {
- return new ZodMap({
- valueType,
- keyType,
- typeName: ZodFirstPartyTypeKind.ZodMap,
- ...processCreateParams(params)
- });
+var en_default = errorMap;
+
+// node_modules/zod/v3/errors.js
+var overrideErrorMap = en_default;
+function setErrorMap(map) {
+ overrideErrorMap = map;
+}
+function getErrorMap() {
+ return overrideErrorMap;
+}
+
+// node_modules/zod/v3/helpers/parseUtil.js
+var makeIssue = (params) => {
+ const { data, path: path5, errorMaps, issueData } = params;
+ const fullPath = [...path5, ...issueData.path || []];
+ const fullIssue = {
+ ...issueData,
+ path: fullPath
+ };
+ if (issueData.message !== void 0) {
+ return {
+ ...issueData,
+ path: fullPath,
+ message: issueData.message
+ };
+ }
+ let errorMessage = "";
+ const maps = errorMaps.filter((m) => !!m).slice().reverse();
+ for (const map of maps) {
+ errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
+ }
+ return {
+ ...issueData,
+ path: fullPath,
+ message: errorMessage
+ };
};
-var ZodSet = class _ZodSet extends ZodType {
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.set) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.set,
- received: ctx.parsedType
+var EMPTY_PATH = [];
+function addIssueToContext(ctx, issueData) {
+ const overrideMap = getErrorMap();
+ const issue = makeIssue({
+ issueData,
+ data: ctx.data,
+ path: ctx.path,
+ errorMaps: [
+ ctx.common.contextualErrorMap,
+ // contextual error map is first priority
+ ctx.schemaErrorMap,
+ // then schema-bound map if available
+ overrideMap,
+ // then global override map
+ overrideMap === en_default ? void 0 : en_default
+ // then global default map
+ ].filter((x) => !!x)
+ });
+ ctx.common.issues.push(issue);
+}
+var ParseStatus = class _ParseStatus {
+ constructor() {
+ this.value = "valid";
+ }
+ dirty() {
+ if (this.value === "valid")
+ this.value = "dirty";
+ }
+ abort() {
+ if (this.value !== "aborted")
+ this.value = "aborted";
+ }
+ static mergeArray(status, results) {
+ const arrayValue = [];
+ for (const s of results) {
+ if (s.status === "aborted")
+ return INVALID;
+ if (s.status === "dirty")
+ status.dirty();
+ arrayValue.push(s.value);
+ }
+ return { status: status.value, value: arrayValue };
+ }
+ static async mergeObjectAsync(status, pairs) {
+ const syncPairs = [];
+ for (const pair of pairs) {
+ const key = await pair.key;
+ const value = await pair.value;
+ syncPairs.push({
+ key,
+ value
});
- return INVALID;
}
- const def = this._def;
- if (def.minSize !== null) {
- if (ctx.data.size < def.minSize.value) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_small,
- minimum: def.minSize.value,
- type: "set",
- inclusive: true,
- exact: false,
- message: def.minSize.message
- });
+ return _ParseStatus.mergeObjectSync(status, syncPairs);
+ }
+ static mergeObjectSync(status, pairs) {
+ const finalObject = {};
+ for (const pair of pairs) {
+ const { key, value } = pair;
+ if (key.status === "aborted")
+ return INVALID;
+ if (value.status === "aborted")
+ return INVALID;
+ if (key.status === "dirty")
status.dirty();
- }
- }
- if (def.maxSize !== null) {
- if (ctx.data.size > def.maxSize.value) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.too_big,
- maximum: def.maxSize.value,
- type: "set",
- inclusive: true,
- exact: false,
- message: def.maxSize.message
- });
+ if (value.status === "dirty")
status.dirty();
+ if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
+ finalObject[key.value] = value.value;
}
}
- const valueType = this._def.valueType;
- function finalizeSet(elements2) {
- const parsedSet = /* @__PURE__ */ new Set();
- for (const element of elements2) {
- if (element.status === "aborted")
- return INVALID;
- if (element.status === "dirty")
- status.dirty();
- parsedSet.add(element.value);
- }
- return { status: status.value, value: parsedSet };
- }
- const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
- if (ctx.common.async) {
- return Promise.all(elements).then((elements2) => finalizeSet(elements2));
- } else {
- return finalizeSet(elements);
- }
- }
- min(minSize, message) {
- return new _ZodSet({
- ...this._def,
- minSize: { value: minSize, message: errorUtil.toString(message) }
- });
- }
- max(maxSize, message) {
- return new _ZodSet({
- ...this._def,
- maxSize: { value: maxSize, message: errorUtil.toString(message) }
- });
+ return { status: status.value, value: finalObject };
}
- size(size, message) {
- return this.min(size, message).max(size, message);
+};
+var INVALID = Object.freeze({
+ status: "aborted"
+});
+var DIRTY = (value) => ({ status: "dirty", value });
+var OK = (value) => ({ status: "valid", value });
+var isAborted = (x) => x.status === "aborted";
+var isDirty = (x) => x.status === "dirty";
+var isValid = (x) => x.status === "valid";
+var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
+
+// node_modules/zod/v3/helpers/errorUtil.js
+var errorUtil;
+(function(errorUtil2) {
+ errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
+ errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
+})(errorUtil || (errorUtil = {}));
+
+// node_modules/zod/v3/types.js
+var ParseInputLazyPath = class {
+ constructor(parent, value, path5, key) {
+ this._cachedPath = [];
+ this.parent = parent;
+ this.data = value;
+ this._path = path5;
+ this._key = key;
}
- nonempty(message) {
- return this.min(1, message);
+ get path() {
+ if (!this._cachedPath.length) {
+ if (Array.isArray(this._key)) {
+ this._cachedPath.push(...this._path, ...this._key);
+ } else {
+ this._cachedPath.push(...this._path, this._key);
+ }
+ }
+ return this._cachedPath;
}
};
-ZodSet.create = (valueType, params) => {
- return new ZodSet({
- valueType,
- minSize: null,
- maxSize: null,
- typeName: ZodFirstPartyTypeKind.ZodSet,
- ...processCreateParams(params)
- });
+var handleResult = (ctx, result) => {
+ if (isValid(result)) {
+ return { success: true, data: result.value };
+ } else {
+ if (!ctx.common.issues.length) {
+ throw new Error("Validation failed but no issues detected.");
+ }
+ return {
+ success: false,
+ get error() {
+ if (this._error)
+ return this._error;
+ const error = new ZodError(ctx.common.issues);
+ this._error = error;
+ return this._error;
+ }
+ };
+ }
};
-var ZodFunction = class _ZodFunction extends ZodType {
- constructor() {
- super(...arguments);
- this.validate = this.implement;
+function processCreateParams(params) {
+ if (!params)
+ return {};
+ const { errorMap: errorMap2, invalid_type_error, required_error, description } = params;
+ if (errorMap2 && (invalid_type_error || required_error)) {
+ throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
}
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.function) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.function,
- received: ctx.parsedType
- });
- return INVALID;
- }
- function makeArgsIssue(args, error) {
- return makeIssue({
- data: args,
- path: ctx.path,
- errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), en_default].filter((x) => !!x),
- issueData: {
- code: ZodIssueCode.invalid_arguments,
- argumentsError: error
- }
- });
+ if (errorMap2)
+ return { errorMap: errorMap2, description };
+ const customMap = (iss, ctx) => {
+ const { message } = params;
+ if (iss.code === "invalid_enum_value") {
+ return { message: message ?? ctx.defaultError };
}
- function makeReturnsIssue(returns, error) {
- return makeIssue({
- data: returns,
- path: ctx.path,
- errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), en_default].filter((x) => !!x),
- issueData: {
- code: ZodIssueCode.invalid_return_type,
- returnTypeError: error
- }
- });
+ if (typeof ctx.data === "undefined") {
+ return { message: message ?? required_error ?? ctx.defaultError };
}
- const params = { errorMap: ctx.common.contextualErrorMap };
- const fn = ctx.data;
- if (this._def.returns instanceof ZodPromise) {
- const me = this;
- return OK(async function(...args) {
- const error = new ZodError([]);
- const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
- error.addIssue(makeArgsIssue(args, e));
- throw error;
- });
- const result = await Reflect.apply(fn, this, parsedArgs);
- const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
- error.addIssue(makeReturnsIssue(result, e));
- throw error;
- });
- return parsedReturns;
- });
- } else {
- const me = this;
- return OK(function(...args) {
- const parsedArgs = me._def.args.safeParse(args, params);
- if (!parsedArgs.success) {
- throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
- }
- const result = Reflect.apply(fn, this, parsedArgs.data);
- const parsedReturns = me._def.returns.safeParse(result, params);
- if (!parsedReturns.success) {
- throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
- }
- return parsedReturns.data;
- });
+ if (iss.code !== "invalid_type")
+ return { message: ctx.defaultError };
+ return { message: message ?? invalid_type_error ?? ctx.defaultError };
+ };
+ return { errorMap: customMap, description };
+}
+var ZodType = class {
+ get description() {
+ return this._def.description;
+ }
+ _getType(input) {
+ return getParsedType(input.data);
+ }
+ _getOrReturnCtx(input, ctx) {
+ return ctx || {
+ common: input.parent.common,
+ data: input.data,
+ parsedType: getParsedType(input.data),
+ schemaErrorMap: this._def.errorMap,
+ path: input.path,
+ parent: input.parent
+ };
+ }
+ _processInputParams(input) {
+ return {
+ status: new ParseStatus(),
+ ctx: {
+ common: input.parent.common,
+ data: input.data,
+ parsedType: getParsedType(input.data),
+ schemaErrorMap: this._def.errorMap,
+ path: input.path,
+ parent: input.parent
+ }
+ };
+ }
+ _parseSync(input) {
+ const result = this._parse(input);
+ if (isAsync(result)) {
+ throw new Error("Synchronous parse encountered promise.");
}
+ return result;
}
- parameters() {
- return this._def.args;
+ _parseAsync(input) {
+ const result = this._parse(input);
+ return Promise.resolve(result);
}
- returnType() {
- return this._def.returns;
+ parse(data, params) {
+ const result = this.safeParse(data, params);
+ if (result.success)
+ return result.data;
+ throw result.error;
}
- args(...items) {
- return new _ZodFunction({
- ...this._def,
- args: ZodTuple.create(items).rest(ZodUnknown.create())
- });
+ safeParse(data, params) {
+ const ctx = {
+ common: {
+ issues: [],
+ async: params?.async ?? false,
+ contextualErrorMap: params?.errorMap
+ },
+ path: params?.path || [],
+ schemaErrorMap: this._def.errorMap,
+ parent: null,
+ data,
+ parsedType: getParsedType(data)
+ };
+ const result = this._parseSync({ data, path: ctx.path, parent: ctx });
+ return handleResult(ctx, result);
}
- returns(returnType) {
- return new _ZodFunction({
- ...this._def,
- returns: returnType
+ "~validate"(data) {
+ const ctx = {
+ common: {
+ issues: [],
+ async: !!this["~standard"].async
+ },
+ path: [],
+ schemaErrorMap: this._def.errorMap,
+ parent: null,
+ data,
+ parsedType: getParsedType(data)
+ };
+ if (!this["~standard"].async) {
+ try {
+ const result = this._parseSync({ data, path: [], parent: ctx });
+ return isValid(result) ? {
+ value: result.value
+ } : {
+ issues: ctx.common.issues
+ };
+ } catch (err) {
+ if (err?.message?.toLowerCase()?.includes("encountered")) {
+ this["~standard"].async = true;
+ }
+ ctx.common = {
+ issues: [],
+ async: true
+ };
+ }
+ }
+ return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? {
+ value: result.value
+ } : {
+ issues: ctx.common.issues
});
}
- implement(func) {
- const validatedFunc = this.parse(func);
- return validatedFunc;
+ async parseAsync(data, params) {
+ const result = await this.safeParseAsync(data, params);
+ if (result.success)
+ return result.data;
+ throw result.error;
}
- strictImplement(func) {
- const validatedFunc = this.parse(func);
- return validatedFunc;
+ async safeParseAsync(data, params) {
+ const ctx = {
+ common: {
+ issues: [],
+ contextualErrorMap: params?.errorMap,
+ async: true
+ },
+ path: params?.path || [],
+ schemaErrorMap: this._def.errorMap,
+ parent: null,
+ data,
+ parsedType: getParsedType(data)
+ };
+ const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
+ const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
+ return handleResult(ctx, result);
}
- static create(args, returns, params) {
- return new _ZodFunction({
- args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()),
- returns: returns || ZodUnknown.create(),
- typeName: ZodFirstPartyTypeKind.ZodFunction,
- ...processCreateParams(params)
+ refine(check, message) {
+ const getIssueProperties = (val) => {
+ if (typeof message === "string" || typeof message === "undefined") {
+ return { message };
+ } else if (typeof message === "function") {
+ return message(val);
+ } else {
+ return message;
+ }
+ };
+ return this._refinement((val, ctx) => {
+ const result = check(val);
+ const setError = () => ctx.addIssue({
+ code: ZodIssueCode.custom,
+ ...getIssueProperties(val)
+ });
+ if (typeof Promise !== "undefined" && result instanceof Promise) {
+ return result.then((data) => {
+ if (!data) {
+ setError();
+ return false;
+ } else {
+ return true;
+ }
+ });
+ }
+ if (!result) {
+ setError();
+ return false;
+ } else {
+ return true;
+ }
});
}
-};
-var ZodLazy = class extends ZodType {
- get schema() {
- return this._def.getter();
- }
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- const lazySchema = this._def.getter();
- return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
+ refinement(check, refinementData) {
+ return this._refinement((val, ctx) => {
+ if (!check(val)) {
+ ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
+ return false;
+ } else {
+ return true;
+ }
+ });
}
-};
-ZodLazy.create = (getter, params) => {
- return new ZodLazy({
- getter,
- typeName: ZodFirstPartyTypeKind.ZodLazy,
- ...processCreateParams(params)
- });
-};
-var ZodLiteral = class extends ZodType {
- _parse(input) {
- if (input.data !== this._def.value) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- received: ctx.data,
- code: ZodIssueCode.invalid_literal,
- expected: this._def.value
- });
- return INVALID;
- }
- return { status: "valid", value: input.data };
+ _refinement(refinement) {
+ return new ZodEffects({
+ schema: this,
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
+ effect: { type: "refinement", refinement }
+ });
}
- get value() {
- return this._def.value;
+ superRefine(refinement) {
+ return this._refinement(refinement);
}
-};
-ZodLiteral.create = (value, params) => {
- return new ZodLiteral({
- value,
- typeName: ZodFirstPartyTypeKind.ZodLiteral,
- ...processCreateParams(params)
- });
-};
-function createZodEnum(values, params) {
- return new ZodEnum({
- values,
- typeName: ZodFirstPartyTypeKind.ZodEnum,
- ...processCreateParams(params)
- });
-}
-var ZodEnum = class _ZodEnum extends ZodType {
- _parse(input) {
- if (typeof input.data !== "string") {
- const ctx = this._getOrReturnCtx(input);
- const expectedValues = this._def.values;
- addIssueToContext(ctx, {
- expected: util.joinValues(expectedValues),
- received: ctx.parsedType,
- code: ZodIssueCode.invalid_type
- });
- return INVALID;
- }
- if (!this._cache) {
- this._cache = new Set(this._def.values);
- }
- if (!this._cache.has(input.data)) {
- const ctx = this._getOrReturnCtx(input);
- const expectedValues = this._def.values;
- addIssueToContext(ctx, {
- received: ctx.data,
- code: ZodIssueCode.invalid_enum_value,
- options: expectedValues
- });
- return INVALID;
- }
- return OK(input.data);
+ constructor(def) {
+ this.spa = this.safeParseAsync;
+ this._def = def;
+ this.parse = this.parse.bind(this);
+ this.safeParse = this.safeParse.bind(this);
+ this.parseAsync = this.parseAsync.bind(this);
+ this.safeParseAsync = this.safeParseAsync.bind(this);
+ this.spa = this.spa.bind(this);
+ this.refine = this.refine.bind(this);
+ this.refinement = this.refinement.bind(this);
+ this.superRefine = this.superRefine.bind(this);
+ this.optional = this.optional.bind(this);
+ this.nullable = this.nullable.bind(this);
+ this.nullish = this.nullish.bind(this);
+ this.array = this.array.bind(this);
+ this.promise = this.promise.bind(this);
+ this.or = this.or.bind(this);
+ this.and = this.and.bind(this);
+ this.transform = this.transform.bind(this);
+ this.brand = this.brand.bind(this);
+ this.default = this.default.bind(this);
+ this.catch = this.catch.bind(this);
+ this.describe = this.describe.bind(this);
+ this.pipe = this.pipe.bind(this);
+ this.readonly = this.readonly.bind(this);
+ this.isNullable = this.isNullable.bind(this);
+ this.isOptional = this.isOptional.bind(this);
+ this["~standard"] = {
+ version: 1,
+ vendor: "zod",
+ validate: (data) => this["~validate"](data)
+ };
}
- get options() {
- return this._def.values;
+ optional() {
+ return ZodOptional.create(this, this._def);
}
- get enum() {
- const enumValues = {};
- for (const val of this._def.values) {
- enumValues[val] = val;
- }
- return enumValues;
+ nullable() {
+ return ZodNullable.create(this, this._def);
}
- get Values() {
- const enumValues = {};
- for (const val of this._def.values) {
- enumValues[val] = val;
- }
- return enumValues;
+ nullish() {
+ return this.nullable().optional();
}
- get Enum() {
- const enumValues = {};
- for (const val of this._def.values) {
- enumValues[val] = val;
- }
- return enumValues;
+ array() {
+ return ZodArray.create(this);
}
- extract(values, newDef = this._def) {
- return _ZodEnum.create(values, {
- ...this._def,
- ...newDef
+ promise() {
+ return ZodPromise.create(this, this._def);
+ }
+ or(option) {
+ return ZodUnion.create([this, option], this._def);
+ }
+ and(incoming) {
+ return ZodIntersection.create(this, incoming, this._def);
+ }
+ transform(transform) {
+ return new ZodEffects({
+ ...processCreateParams(this._def),
+ schema: this,
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
+ effect: { type: "transform", transform }
});
}
- exclude(values, newDef = this._def) {
- return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
+ default(def) {
+ const defaultValueFunc = typeof def === "function" ? def : () => def;
+ return new ZodDefault({
+ ...processCreateParams(this._def),
+ innerType: this,
+ defaultValue: defaultValueFunc,
+ typeName: ZodFirstPartyTypeKind.ZodDefault
+ });
+ }
+ brand() {
+ return new ZodBranded({
+ typeName: ZodFirstPartyTypeKind.ZodBranded,
+ type: this,
+ ...processCreateParams(this._def)
+ });
+ }
+ catch(def) {
+ const catchValueFunc = typeof def === "function" ? def : () => def;
+ return new ZodCatch({
+ ...processCreateParams(this._def),
+ innerType: this,
+ catchValue: catchValueFunc,
+ typeName: ZodFirstPartyTypeKind.ZodCatch
+ });
+ }
+ describe(description) {
+ const This = this.constructor;
+ return new This({
...this._def,
- ...newDef
+ description
});
}
-};
-ZodEnum.create = createZodEnum;
-var ZodNativeEnum = class extends ZodType {
- _parse(input) {
- const nativeEnumValues = util.getValidEnumValues(this._def.values);
- const ctx = this._getOrReturnCtx(input);
- if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {
- const expectedValues = util.objectValues(nativeEnumValues);
- addIssueToContext(ctx, {
- expected: util.joinValues(expectedValues),
- received: ctx.parsedType,
- code: ZodIssueCode.invalid_type
- });
- return INVALID;
- }
- if (!this._cache) {
- this._cache = new Set(util.getValidEnumValues(this._def.values));
- }
- if (!this._cache.has(input.data)) {
- const expectedValues = util.objectValues(nativeEnumValues);
- addIssueToContext(ctx, {
- received: ctx.data,
- code: ZodIssueCode.invalid_enum_value,
- options: expectedValues
- });
- return INVALID;
- }
- return OK(input.data);
+ pipe(target) {
+ return ZodPipeline.create(this, target);
}
- get enum() {
- return this._def.values;
+ readonly() {
+ return ZodReadonly.create(this);
}
-};
-ZodNativeEnum.create = (values, params) => {
- return new ZodNativeEnum({
- values,
- typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
- ...processCreateParams(params)
- });
-};
-var ZodPromise = class extends ZodType {
- unwrap() {
- return this._def.type;
+ isOptional() {
+ return this.safeParse(void 0).success;
}
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.promise,
- received: ctx.parsedType
- });
- return INVALID;
- }
- const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
- return OK(promisified.then((data) => {
- return this._def.type.parseAsync(data, {
- path: ctx.path,
- errorMap: ctx.common.contextualErrorMap
- });
- }));
+ isNullable() {
+ return this.safeParse(null).success;
}
};
-ZodPromise.create = (schema, params) => {
- return new ZodPromise({
- type: schema,
- typeName: ZodFirstPartyTypeKind.ZodPromise,
- ...processCreateParams(params)
- });
-};
-var ZodEffects = class extends ZodType {
- innerType() {
- return this._def.schema;
+var cuidRegex = /^c[^\s-]{8,}$/i;
+var cuid2Regex = /^[0-9a-z]+$/;
+var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
+var uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
+var nanoidRegex = /^[a-z0-9_-]{21}$/i;
+var jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
+var durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
+var emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
+var _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
+var emojiRegex;
+var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
+var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
+var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
+var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
+var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
+var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
+var dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
+var dateRegex = new RegExp(`^${dateRegexSource}$`);
+function timeRegexSource(args) {
+ let secondsRegexSource = `[0-5]\\d`;
+ if (args.precision) {
+ secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
+ } else if (args.precision == null) {
+ secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
}
- sourceType() {
- return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
+ const secondsQuantifier = args.precision ? "+" : "?";
+ return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
+}
+function timeRegex(args) {
+ return new RegExp(`^${timeRegexSource(args)}$`);
+}
+function datetimeRegex(args) {
+ let regex = `${dateRegexSource}T${timeRegexSource(args)}`;
+ const opts = [];
+ opts.push(args.local ? `Z?` : `Z`);
+ if (args.offset)
+ opts.push(`([+-]\\d{2}:?\\d{2})`);
+ regex = `${regex}(${opts.join("|")})`;
+ return new RegExp(`^${regex}$`);
+}
+function isValidIP(ip, version) {
+ if ((version === "v4" || !version) && ipv4Regex.test(ip)) {
+ return true;
}
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- const effect = this._def.effect || null;
- const checkCtx = {
- addIssue: (arg) => {
- addIssueToContext(ctx, arg);
- if (arg.fatal) {
- status.abort();
- } else {
+ if ((version === "v6" || !version) && ipv6Regex.test(ip)) {
+ return true;
+ }
+ return false;
+}
+function isValidJWT(jwt, alg) {
+ if (!jwtRegex.test(jwt))
+ return false;
+ try {
+ const [header] = jwt.split(".");
+ if (!header)
+ return false;
+ const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
+ const decoded = JSON.parse(atob(base64));
+ if (typeof decoded !== "object" || decoded === null)
+ return false;
+ if ("typ" in decoded && decoded?.typ !== "JWT")
+ return false;
+ if (!decoded.alg)
+ return false;
+ if (alg && decoded.alg !== alg)
+ return false;
+ return true;
+ } catch {
+ return false;
+ }
+}
+function isValidCidr(ip, version) {
+ if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
+ return true;
+ }
+ if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
+ return true;
+ }
+ return false;
+}
+var ZodString = class _ZodString extends ZodType {
+ _parse(input) {
+ if (this._def.coerce) {
+ input.data = String(input.data);
+ }
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.string) {
+ const ctx2 = this._getOrReturnCtx(input);
+ addIssueToContext(ctx2, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.string,
+ received: ctx2.parsedType
+ });
+ return INVALID;
+ }
+ const status = new ParseStatus();
+ let ctx = void 0;
+ for (const check of this._def.checks) {
+ if (check.kind === "min") {
+ if (input.data.length < check.value) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: check.value,
+ type: "string",
+ inclusive: true,
+ exact: false,
+ message: check.message
+ });
status.dirty();
}
- },
- get path() {
- return ctx.path;
- }
- };
- checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
- if (effect.type === "preprocess") {
- const processed = effect.transform(ctx.data, checkCtx);
- if (ctx.common.async) {
- return Promise.resolve(processed).then(async (processed2) => {
- if (status.value === "aborted")
- return INVALID;
- const result = await this._def.schema._parseAsync({
- data: processed2,
- path: ctx.path,
- parent: ctx
+ } else if (check.kind === "max") {
+ if (input.data.length > check.value) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: check.value,
+ type: "string",
+ inclusive: true,
+ exact: false,
+ message: check.message
});
- if (result.status === "aborted")
- return INVALID;
- if (result.status === "dirty")
- return DIRTY(result.value);
- if (status.value === "dirty")
- return DIRTY(result.value);
- return result;
- });
- } else {
- if (status.value === "aborted")
- return INVALID;
- const result = this._def.schema._parseSync({
- data: processed,
- path: ctx.path,
- parent: ctx
- });
- if (result.status === "aborted")
- return INVALID;
- if (result.status === "dirty")
- return DIRTY(result.value);
- if (status.value === "dirty")
- return DIRTY(result.value);
- return result;
- }
- }
- if (effect.type === "refinement") {
- const executeRefinement = (acc) => {
- const result = effect.refinement(acc, checkCtx);
- if (ctx.common.async) {
- return Promise.resolve(result);
+ status.dirty();
}
- if (result instanceof Promise) {
- throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
+ } else if (check.kind === "length") {
+ const tooBig = input.data.length > check.value;
+ const tooSmall = input.data.length < check.value;
+ if (tooBig || tooSmall) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ if (tooBig) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: check.value,
+ type: "string",
+ inclusive: true,
+ exact: true,
+ message: check.message
+ });
+ } else if (tooSmall) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: check.value,
+ type: "string",
+ inclusive: true,
+ exact: true,
+ message: check.message
+ });
+ }
+ status.dirty();
+ }
+ } else if (check.kind === "email") {
+ if (!emailRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "email",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "emoji") {
+ if (!emojiRegex) {
+ emojiRegex = new RegExp(_emojiRegex, "u");
+ }
+ if (!emojiRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "emoji",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "uuid") {
+ if (!uuidRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "uuid",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "nanoid") {
+ if (!nanoidRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "nanoid",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "cuid") {
+ if (!cuidRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "cuid",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "cuid2") {
+ if (!cuid2Regex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "cuid2",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "ulid") {
+ if (!ulidRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "ulid",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "url") {
+ try {
+ new URL(input.data);
+ } catch {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "url",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "regex") {
+ check.regex.lastIndex = 0;
+ const testResult = check.regex.test(input.data);
+ if (!testResult) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "regex",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "trim") {
+ input.data = input.data.trim();
+ } else if (check.kind === "includes") {
+ if (!input.data.includes(check.value, check.position)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: { includes: check.value, position: check.position },
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "toLowerCase") {
+ input.data = input.data.toLowerCase();
+ } else if (check.kind === "toUpperCase") {
+ input.data = input.data.toUpperCase();
+ } else if (check.kind === "startsWith") {
+ if (!input.data.startsWith(check.value)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: { startsWith: check.value },
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "endsWith") {
+ if (!input.data.endsWith(check.value)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: { endsWith: check.value },
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "datetime") {
+ const regex = datetimeRegex(check);
+ if (!regex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: "datetime",
+ message: check.message
+ });
+ status.dirty();
}
- return acc;
- };
- if (ctx.common.async === false) {
- const inner = this._def.schema._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
- if (inner.status === "aborted")
- return INVALID;
- if (inner.status === "dirty")
+ } else if (check.kind === "date") {
+ const regex = dateRegex;
+ if (!regex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: "date",
+ message: check.message
+ });
status.dirty();
- executeRefinement(inner.value);
- return { status: status.value, value: inner.value };
- } else {
- return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
- if (inner.status === "aborted")
- return INVALID;
- if (inner.status === "dirty")
- status.dirty();
- return executeRefinement(inner.value).then(() => {
- return { status: status.value, value: inner.value };
+ }
+ } else if (check.kind === "time") {
+ const regex = timeRegex(check);
+ if (!regex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_string,
+ validation: "time",
+ message: check.message
});
- });
- }
- }
- if (effect.type === "transform") {
- if (ctx.common.async === false) {
- const base = this._def.schema._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
- if (!isValid(base))
- return INVALID;
- const result = effect.transform(base.value, checkCtx);
- if (result instanceof Promise) {
- throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
+ status.dirty();
}
- return { status: status.value, value: result };
- } else {
- return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
- if (!isValid(base))
- return INVALID;
- return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
- status: status.value,
- value: result
- }));
- });
- }
- }
- util.assertNever(effect);
- }
-};
-ZodEffects.create = (schema, effect, params) => {
- return new ZodEffects({
- schema,
- typeName: ZodFirstPartyTypeKind.ZodEffects,
- effect,
- ...processCreateParams(params)
- });
-};
-ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
- return new ZodEffects({
- schema,
- effect: { type: "preprocess", transform: preprocess },
- typeName: ZodFirstPartyTypeKind.ZodEffects,
- ...processCreateParams(params)
- });
-};
-var ZodOptional = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType === ZodParsedType.undefined) {
- return OK(void 0);
- }
- return this._def.innerType._parse(input);
- }
- unwrap() {
- return this._def.innerType;
- }
-};
-ZodOptional.create = (type, params) => {
- return new ZodOptional({
- innerType: type,
- typeName: ZodFirstPartyTypeKind.ZodOptional,
- ...processCreateParams(params)
- });
-};
-var ZodNullable = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType === ZodParsedType.null) {
- return OK(null);
- }
- return this._def.innerType._parse(input);
- }
- unwrap() {
- return this._def.innerType;
- }
-};
-ZodNullable.create = (type, params) => {
- return new ZodNullable({
- innerType: type,
- typeName: ZodFirstPartyTypeKind.ZodNullable,
- ...processCreateParams(params)
- });
-};
-var ZodDefault = class extends ZodType {
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- let data = ctx.data;
- if (ctx.parsedType === ZodParsedType.undefined) {
- data = this._def.defaultValue();
- }
- return this._def.innerType._parse({
- data,
- path: ctx.path,
- parent: ctx
- });
- }
- removeDefault() {
- return this._def.innerType;
- }
-};
-ZodDefault.create = (type, params) => {
- return new ZodDefault({
- innerType: type,
- typeName: ZodFirstPartyTypeKind.ZodDefault,
- defaultValue: typeof params.default === "function" ? params.default : () => params.default,
- ...processCreateParams(params)
- });
-};
-var ZodCatch = class extends ZodType {
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- const newCtx = {
- ...ctx,
- common: {
- ...ctx.common,
- issues: []
- }
- };
- const result = this._def.innerType._parse({
- data: newCtx.data,
- path: newCtx.path,
- parent: {
- ...newCtx
- }
- });
- if (isAsync(result)) {
- return result.then((result2) => {
- return {
- status: "valid",
- value: result2.status === "valid" ? result2.value : this._def.catchValue({
- get error() {
- return new ZodError(newCtx.common.issues);
- },
- input: newCtx.data
- })
- };
- });
- } else {
- return {
- status: "valid",
- value: result.status === "valid" ? result.value : this._def.catchValue({
- get error() {
- return new ZodError(newCtx.common.issues);
- },
- input: newCtx.data
- })
- };
- }
- }
- removeCatch() {
- return this._def.innerType;
- }
-};
-ZodCatch.create = (type, params) => {
- return new ZodCatch({
- innerType: type,
- typeName: ZodFirstPartyTypeKind.ZodCatch,
- catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
- ...processCreateParams(params)
- });
-};
-var ZodNaN = class extends ZodType {
- _parse(input) {
- const parsedType = this._getType(input);
- if (parsedType !== ZodParsedType.nan) {
- const ctx = this._getOrReturnCtx(input);
- addIssueToContext(ctx, {
- code: ZodIssueCode.invalid_type,
- expected: ZodParsedType.nan,
- received: ctx.parsedType
- });
- return INVALID;
- }
- return { status: "valid", value: input.data };
- }
-};
-ZodNaN.create = (params) => {
- return new ZodNaN({
- typeName: ZodFirstPartyTypeKind.ZodNaN,
- ...processCreateParams(params)
- });
-};
-var BRAND = Symbol("zod_brand");
-var ZodBranded = class extends ZodType {
- _parse(input) {
- const { ctx } = this._processInputParams(input);
- const data = ctx.data;
- return this._def.type._parse({
- data,
- path: ctx.path,
- parent: ctx
- });
- }
- unwrap() {
- return this._def.type;
- }
-};
-var ZodPipeline = class _ZodPipeline extends ZodType {
- _parse(input) {
- const { status, ctx } = this._processInputParams(input);
- if (ctx.common.async) {
- const handleAsync = async () => {
- const inResult = await this._def.in._parseAsync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
- if (inResult.status === "aborted")
- return INVALID;
- if (inResult.status === "dirty") {
+ } else if (check.kind === "duration") {
+ if (!durationRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "duration",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
status.dirty();
- return DIRTY(inResult.value);
- } else {
- return this._def.out._parseAsync({
- data: inResult.value,
- path: ctx.path,
- parent: ctx
+ }
+ } else if (check.kind === "ip") {
+ if (!isValidIP(input.data, check.version)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "ip",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
});
+ status.dirty();
}
- };
- return handleAsync();
- } else {
- const inResult = this._def.in._parseSync({
- data: ctx.data,
- path: ctx.path,
- parent: ctx
- });
- if (inResult.status === "aborted")
- return INVALID;
- if (inResult.status === "dirty") {
- status.dirty();
- return {
- status: "dirty",
- value: inResult.value
- };
- } else {
- return this._def.out._parseSync({
- data: inResult.value,
- path: ctx.path,
- parent: ctx
- });
- }
- }
- }
- static create(a, b) {
- return new _ZodPipeline({
- in: a,
- out: b,
- typeName: ZodFirstPartyTypeKind.ZodPipeline
- });
- }
-};
-var ZodReadonly = class extends ZodType {
- _parse(input) {
- const result = this._def.innerType._parse(input);
- const freeze = (data) => {
- if (isValid(data)) {
- data.value = Object.freeze(data.value);
- }
- return data;
- };
- return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
- }
- unwrap() {
- return this._def.innerType;
- }
-};
-ZodReadonly.create = (type, params) => {
- return new ZodReadonly({
- innerType: type,
- typeName: ZodFirstPartyTypeKind.ZodReadonly,
- ...processCreateParams(params)
- });
-};
-function cleanParams(params, data) {
- const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
- const p2 = typeof p === "string" ? { message: p } : p;
- return p2;
-}
-function custom(check, _params = {}, fatal) {
- if (check)
- return ZodAny.create().superRefine((data, ctx) => {
- const r = check(data);
- if (r instanceof Promise) {
- return r.then((r2) => {
- if (!r2) {
- const params = cleanParams(_params, data);
- const _fatal = params.fatal ?? fatal ?? true;
- ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
- }
- });
- }
- if (!r) {
- const params = cleanParams(_params, data);
- const _fatal = params.fatal ?? fatal ?? true;
- ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
- }
- return;
- });
- return ZodAny.create();
-}
-var late = {
- object: ZodObject.lazycreate
-};
-var ZodFirstPartyTypeKind;
-(function(ZodFirstPartyTypeKind2) {
- ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
- ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
- ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
- ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
- ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
- ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
- ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
- ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
- ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
- ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
- ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
- ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
- ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
- ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
- ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
- ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
- ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
- ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
- ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
- ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
- ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
- ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
- ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
- ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
- ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
- ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
- ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
- ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
- ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
- ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
- ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
- ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
- ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
- ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
- ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
- ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
-})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
-var instanceOfType = (cls, params = {
- message: `Input not instance of ${cls.name}`
-}) => custom((data) => data instanceof cls, params);
-var stringType = ZodString.create;
-var numberType = ZodNumber.create;
-var nanType = ZodNaN.create;
-var bigIntType = ZodBigInt.create;
-var booleanType = ZodBoolean.create;
-var dateType = ZodDate.create;
-var symbolType = ZodSymbol.create;
-var undefinedType = ZodUndefined.create;
-var nullType = ZodNull.create;
-var anyType = ZodAny.create;
-var unknownType = ZodUnknown.create;
-var neverType = ZodNever.create;
-var voidType = ZodVoid.create;
-var arrayType = ZodArray.create;
-var objectType = ZodObject.create;
-var strictObjectType = ZodObject.strictCreate;
-var unionType = ZodUnion.create;
-var discriminatedUnionType = ZodDiscriminatedUnion.create;
-var intersectionType = ZodIntersection.create;
-var tupleType = ZodTuple.create;
-var recordType = ZodRecord.create;
-var mapType = ZodMap.create;
-var setType = ZodSet.create;
-var functionType = ZodFunction.create;
-var lazyType = ZodLazy.create;
-var literalType = ZodLiteral.create;
-var enumType = ZodEnum.create;
-var nativeEnumType = ZodNativeEnum.create;
-var promiseType = ZodPromise.create;
-var effectsType = ZodEffects.create;
-var optionalType = ZodOptional.create;
-var nullableType = ZodNullable.create;
-var preprocessType = ZodEffects.createWithPreprocess;
-var pipelineType = ZodPipeline.create;
-var ostring = () => stringType().optional();
-var onumber = () => numberType().optional();
-var oboolean = () => booleanType().optional();
-var coerce = {
- string: ((arg) => ZodString.create({ ...arg, coerce: true })),
- number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
- boolean: ((arg) => ZodBoolean.create({
- ...arg,
- coerce: true
- })),
- bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
- date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
-};
-var NEVER = INVALID;
-
-// src/mlclaw-space-runtime/operator-brokers.ts
-var MAX_CONFIG_BYTES = 64 * 1024;
-var MAX_TOKEN_BYTES = 4096;
-var MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
-var DEFAULT_REQUEST_TIMEOUT_MS = 1e4;
-var BROKER_ID = /^[a-z](?:[a-z0-9-]{0,38}[a-z0-9])?$/;
-var displayFieldSchema = external_exports.object({
- label: external_exports.string().min(1).max(80),
- value: external_exports.string().min(1).max(500)
-}).strict();
-var approvalSchema = external_exports.object({
- id: external_exports.string().min(1).max(128),
- revision: external_exports.number().int().positive().safe(),
- requester: external_exports.string().min(1).max(80),
- operation: external_exports.string().min(1).max(500),
- status: external_exports.enum(["pending", "active", "denied", "canceled", "expired", "consumed", "revoked"]),
- requested_at: external_exports.string().datetime({ offset: true }),
- pending_expires_at: external_exports.string().datetime({ offset: true }).optional(),
- active_expires_at: external_exports.string().datetime({ offset: true }).optional(),
- requested_duration_seconds: external_exports.number().int().positive().safe(),
- requested_max_uses: external_exports.number().int().positive().safe().nullable(),
- granted_max_uses: external_exports.number().int().positive().safe().nullable(),
- used_count: external_exports.number().int().nonnegative().safe(),
- request_reason: external_exports.string().max(2e3).optional(),
- decided_at: external_exports.string().datetime({ offset: true }).optional(),
- decided_by: external_exports.string().max(200).optional(),
- decided_on_behalf_of: external_exports.string().max(200).optional(),
- presentation: external_exports.object({
- risk: external_exports.enum(["unknown", "low", "medium", "high", "critical"]),
- title: external_exports.string().min(1).max(200),
- summary: external_exports.string().max(2e3).optional(),
- facts: external_exports.array(displayFieldSchema).max(20).optional()
- }).strict(),
- presentation_unavailable: external_exports.boolean().optional(),
- allowed_actions: external_exports.array(external_exports.enum(["approve", "deny", "revoke"])).max(3),
- approval_bounds: external_exports.object({
- max_duration_seconds: external_exports.number().int().positive().safe(),
- max_uses: external_exports.number().int().positive().safe().nullable()
- }).strict().optional()
-}).strict();
-var approvalPageSchema = external_exports.object({
- requests: external_exports.array(approvalSchema).max(100),
- next_cursor: external_exports.string().min(1).max(1024).optional(),
- event_cursor: external_exports.string().min(1).max(1024).optional()
-}).strict();
-var operatorErrorSchema = external_exports.object({
- error: external_exports.object({
- code: external_exports.string().min(1).max(200).optional(),
- message: external_exports.string().min(1).max(2e3).optional()
- }).optional()
-}).passthrough();
-var BrokerOperatorError = class extends Error {
- constructor(broker, status, code, message) {
- super(message);
- this.broker = broker;
- this.status = status;
- this.code = code;
- }
-};
-function requestDeadline(timeoutMs, signal) {
- const timeout = new AbortController();
- const timer = setTimeout(() => timeout.abort(), timeoutMs);
- timer.unref?.();
- return {
- signal: signal ? AbortSignal.any([signal, timeout.signal]) : timeout.signal,
- timedOut: () => timeout.signal.aborted,
- clear: () => clearTimeout(timer)
- };
-}
-var BrokerOperatorClient = class {
- constructor(options) {
- this.options = options;
- this.baseUrl = options.baseUrl.replace(/\/+$/, "");
- this.fetchImpl = options.fetch ?? fetch;
- this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
- if (!Number.isSafeInteger(this.requestTimeoutMs) || this.requestTimeoutMs < 1) {
- throw new Error("operator broker request timeout must be a positive integer");
+ } else if (check.kind === "jwt") {
+ if (!isValidJWT(input.data, check.alg)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "jwt",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "cidr") {
+ if (!isValidCidr(input.data, check.version)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "cidr",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "base64") {
+ if (!base64Regex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "base64",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "base64url") {
+ if (!base64urlRegex.test(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ validation: "base64url",
+ code: ZodIssueCode.invalid_string,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else {
+ util.assertNever(check);
+ }
}
+ return { status: status.value, value: input.data };
}
- fetchImpl;
- baseUrl;
- requestTimeoutMs;
- summary() {
- return { id: this.options.id, label: this.options.label };
- }
- discover(signal) {
- return this.request(
- "/.well-known/brokerkit-operator",
- signal ? { signal } : void 0,
- external_exports.object({ api_version: external_exports.literal("brokerkit.io/operator/v1") }).passthrough(),
- "discovery"
- );
- }
- list(params = {}, signal) {
- const query = new URLSearchParams();
- if (params.status) {
- query.set("status", params.status);
- }
- if (params.cursor) {
- query.set("cursor", params.cursor);
- }
- if (params.limit) {
- query.set("limit", String(params.limit));
- }
- const suffix = query.size > 0 ? `?${query}` : "";
- return this.request(
- `/api/operator/v1/requests${suffix}`,
- signal ? { signal } : void 0,
- approvalPageSchema,
- "request list"
- );
+ _regex(regex, validation, message) {
+ return this.refinement((data) => regex.test(data), {
+ validation,
+ code: ZodIssueCode.invalid_string,
+ ...errorUtil.errToObj(message)
+ });
}
- get(id) {
- return this.request(
- `/api/operator/v1/requests/${approvalId(id)}`,
- void 0,
- approvalSchema,
- "request"
- );
+ _addCheck(check) {
+ return new _ZodString({
+ ...this._def,
+ checks: [...this._def.checks, check]
+ });
}
- decide(id, action, decision) {
- return this.request(
- `/api/operator/v1/requests/${approvalId(id)}/${action}`,
- {
- method: "POST",
- headers: { "content-type": "application/json" },
- body: JSON.stringify({
- expected_revision: decision.expectedRevision,
- idempotency_key: decision.idempotencyKey,
- on_behalf_of: decision.onBehalfOf,
- ...decision.durationSeconds !== void 0 || decision.maxUses !== void 0 ? {
- constraints: {
- ...decision.durationSeconds !== void 0 ? { duration_seconds: decision.durationSeconds } : {},
- ...decision.maxUses !== void 0 ? { max_uses: decision.maxUses } : {}
- }
- } : {}
- })
- },
- approvalSchema,
- "request"
- );
+ email(message) {
+ return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });
}
- async events(lastEventId, signal) {
- const headers = {
- accept: "text/event-stream",
- authorization: `Bearer ${this.options.token}`
- };
- const cursor = lastEventId ? `?cursor=${encodeURIComponent(lastEventId)}` : "";
- const response = await this.fetchImpl(`${this.baseUrl}/api/operator/v1/events${cursor}`, {
- headers,
- redirect: "error",
- ...signal ? { signal } : {}
- });
- if (!response.ok) {
- throw await this.operatorError(response);
- }
- if (!response.headers.get("content-type")?.toLowerCase().startsWith("text/event-stream")) {
- await response.body?.cancel();
- throw new BrokerOperatorError(
- this.summary(),
- 502,
- "invalid_event_stream",
- "Broker returned an invalid event stream"
- );
- }
- return response;
+ url(message) {
+ return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });
}
- async request(pathname, init, schema, label) {
- const headers = new Headers(init?.headers);
- headers.set("accept", "application/json");
- headers.set("authorization", `Bearer ${this.options.token}`);
- const deadline = requestDeadline(this.requestTimeoutMs, init?.signal ?? void 0);
- try {
- const response = await this.fetchImpl(`${this.baseUrl}${pathname}`, {
- ...init ?? {},
- headers,
- redirect: "error",
- signal: deadline.signal
- });
- if (!response.ok) {
- throw await this.operatorError(response);
- }
- return validatedBrokerPayload(await boundedJson(response), schema, label);
- } catch (err) {
- if (deadline.timedOut()) {
- throw new BrokerOperatorError(
- this.summary(),
- 504,
- "broker_timeout",
- `${this.options.label} operator request timed out`
- );
- }
- throw err;
- } finally {
- deadline.clear();
- }
+ emoji(message) {
+ return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });
}
- async operatorError(response) {
- const fallback = `${this.options.label} operator request failed`;
- try {
- const value = validatedBrokerPayload(
- await boundedJson(response),
- operatorErrorSchema,
- "error"
- );
- const message = value.error?.message?.trim() || fallback;
- const code = value.error?.code?.trim();
- return new BrokerOperatorError(this.summary(), response.status, code, message);
- } catch {
- return new BrokerOperatorError(this.summary(), response.status, void 0, fallback);
- }
+ uuid(message) {
+ return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });
}
-};
-var OperatorBrokerRegistry = class {
- clients;
- constructor(configs, fetchImpl) {
- this.clients = new Map(
- configs.map((config2) => [
- config2.id,
- new BrokerOperatorClient({ ...config2, ...fetchImpl ? { fetch: fetchImpl } : {} })
- ])
- );
+ nanoid(message) {
+ return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) });
}
- list() {
- return [...this.clients.values()].map((client) => client.summary());
+ cuid(message) {
+ return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });
}
- get(id) {
- return this.clients.get(id);
+ cuid2(message) {
+ return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });
}
- entries() {
- return [...this.clients.values()].map((client) => [client.summary(), client]);
+ ulid(message) {
+ return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });
}
-};
-function loadOperatorBrokers(file) {
- if (!file) {
- return [];
+ base64(message) {
+ return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });
}
- if (!isAbsolute(file)) {
- throw new Error("MLCLAW_OPERATOR_BROKERS_FILE must be absolute");
+ base64url(message) {
+ return this._addCheck({
+ kind: "base64url",
+ ...errorUtil.errToObj(message)
+ });
}
- const raw2 = readBoundedFile(file, MAX_CONFIG_BYTES, "operator broker configuration");
- let parsed;
- try {
- parsed = JSON.parse(raw2);
- } catch {
- throw new Error("operator broker configuration must be valid JSON");
+ jwt(options) {
+ return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });
}
- const root = strictRecord(parsed, ["version", "brokers"], "operator broker configuration");
- if (root.version !== 1) {
- throw new Error("operator broker configuration version must be 1");
+ ip(options) {
+ return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
}
- if (!Array.isArray(root.brokers) || root.brokers.length > 16) {
- throw new Error("operator broker configuration must contain at most 16 brokers");
+ cidr(options) {
+ return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });
}
- const ids = /* @__PURE__ */ new Set();
- const urls = /* @__PURE__ */ new Set();
- return root.brokers.map((value, index) => {
- const entry = strictRecord(value, ["id", "label", "url", "token_file"], `broker ${index}`);
- const id = requiredString(entry.id, `broker ${index} id`);
- if (!BROKER_ID.test(id) || ids.has(id)) {
- throw new Error(`broker ${index} id is invalid or duplicated`);
- }
- ids.add(id);
- const label = requiredString(entry.label, `broker ${index} label`);
- if ([...label].length > 80 || new RegExp("\\p{Cc}", "u").test(label)) {
- throw new Error(`broker ${index} label is invalid`);
- }
- const baseUrl = operatorOrigin(requiredString(entry.url, `broker ${index} url`));
- if (urls.has(baseUrl)) {
- throw new Error(`broker ${index} URL is duplicated`);
- }
- urls.add(baseUrl);
- const tokenFile = requiredString(entry.token_file, `broker ${index} token_file`);
- if (!isAbsolute(tokenFile)) {
- throw new Error(`broker ${index} token_file must be absolute`);
- }
- const token = readBoundedFile(tokenFile, MAX_TOKEN_BYTES, `broker ${id} token`).trim();
- if (!/^[\x21-\x7e]{24,4096}$/u.test(token)) {
- throw new Error(`broker ${id} token is invalid`);
+ datetime(options) {
+ if (typeof options === "string") {
+ return this._addCheck({
+ kind: "datetime",
+ precision: null,
+ offset: false,
+ local: false,
+ message: options
+ });
}
- return { id, label, baseUrl, token };
- });
-}
-function operatorOrigin(value) {
- let url;
- try {
- url = new URL(value);
- } catch {
- throw new Error("broker URL must be an absolute HTTP URL");
+ return this._addCheck({
+ kind: "datetime",
+ precision: typeof options?.precision === "undefined" ? null : options?.precision,
+ offset: options?.offset ?? false,
+ local: options?.local ?? false,
+ ...errorUtil.errToObj(options?.message)
+ });
}
- const supportedProtocol = (/* @__PURE__ */ new Set(["http:", "https:"])).has(url.protocol);
- const hasAuthorityOrSuffix = [url.username, url.password, url.search, url.hash].some(Boolean);
- const hasPath = !["", "/"].includes(url.pathname);
- if (!supportedProtocol || hasAuthorityOrSuffix || hasPath) {
- throw new Error("broker URL must be one HTTP origin without credentials, path, query, or fragment");
+ date(message) {
+ return this._addCheck({ kind: "date", message });
}
- return url.origin;
-}
-function strictRecord(value, keys, label) {
- if (!value || typeof value !== "object" || Array.isArray(value)) {
- throw new Error(`${label} must be an object`);
+ time(options) {
+ if (typeof options === "string") {
+ return this._addCheck({
+ kind: "time",
+ precision: null,
+ message: options
+ });
+ }
+ return this._addCheck({
+ kind: "time",
+ precision: typeof options?.precision === "undefined" ? null : options?.precision,
+ ...errorUtil.errToObj(options?.message)
+ });
}
- const record = value;
- if (Object.keys(record).some((key) => !keys.includes(key)) || keys.some((key) => !(key in record))) {
- throw new Error(`${label} has missing or unknown fields`);
+ duration(message) {
+ return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) });
}
- return record;
-}
-function requiredString(value, label) {
- if (typeof value !== "string" || !value || value !== value.trim()) {
- throw new Error(`${label} must be a non-empty trimmed string`);
+ regex(regex, message) {
+ return this._addCheck({
+ kind: "regex",
+ regex,
+ ...errorUtil.errToObj(message)
+ });
}
- return value;
-}
-function readBoundedFile(file, maximum, label) {
- let value;
- try {
- value = readFileSync(file, "utf8");
- } catch {
- throw new Error(`${label} could not be read`);
+ includes(value, options) {
+ return this._addCheck({
+ kind: "includes",
+ value,
+ position: options?.position,
+ ...errorUtil.errToObj(options?.message)
+ });
}
- if (Buffer.byteLength(value) > maximum) {
- throw new Error(`${label} is too large`);
+ startsWith(value, message) {
+ return this._addCheck({
+ kind: "startsWith",
+ value,
+ ...errorUtil.errToObj(message)
+ });
}
- return value;
-}
-function approvalId(id) {
- return encodeURIComponent(id);
-}
-async function boundedJson(response) {
- if (!response.body) {
- throw new Error("broker response body is empty");
+ endsWith(value, message) {
+ return this._addCheck({
+ kind: "endsWith",
+ value,
+ ...errorUtil.errToObj(message)
+ });
}
- const reader = response.body.getReader();
- const chunks = [];
- let size = 0;
- while (true) {
- const { done, value } = await reader.read();
- if (done) {
- break;
- }
- size += value.byteLength;
- if (size > MAX_RESPONSE_BYTES) {
- await reader.cancel();
- throw new Error("broker response is too large");
- }
- chunks.push(value);
+ min(minLength, message) {
+ return this._addCheck({
+ kind: "min",
+ value: minLength,
+ ...errorUtil.errToObj(message)
+ });
}
- return JSON.parse(Buffer.concat(chunks).toString("utf8"));
-}
-function validatedBrokerPayload(value, schema, label) {
- const parsed = schema.safeParse(value);
- if (!parsed.success) {
- throw new Error(`broker ${label} response is invalid`);
+ max(maxLength, message) {
+ return this._addCheck({
+ kind: "max",
+ value: maxLength,
+ ...errorUtil.errToObj(message)
+ });
}
- return parsed.data;
-}
-
-// src/mlclaw-space-runtime/local-access.ts
-import { createHmac, timingSafeEqual } from "node:crypto";
-var LOCAL_ACCESS_CONTEXT = "mlclaw-local-access-v1";
-function deriveLocalAccessToken(sessionSecret) {
- return createHmac("sha256", sessionSecret).update(LOCAL_ACCESS_CONTEXT).digest("base64url");
-}
-function localAccessTokenMatches(candidate, expected) {
- const left = Buffer.from(candidate);
- const right = Buffer.from(expected);
- return left.length === right.length && timingSafeEqual(left, right);
-}
-
-// src/mlclaw-space-runtime/config.ts
-function loadConfig(env = process.env) {
- const port = integer(env.PORT ?? env.MLCLAW_SPACE_PORT, 7860);
- const openclawPort = integer(env.MLCLAW_OPENCLAW_PORT ?? env.OPENCLAW_GATEWAY_PORT, 7861);
- const mcpPort = integer(env.MLCLAW_MCP_PORT, 7862);
- const spaceId = trim(env.SPACE_ID);
- const canonicalSpaceId = trim(env.MLCLAW_CANONICAL_SPACE_ID) ?? "osolmaz/mlclaw";
- const canonicalCreatorUserId = trim(env.MLCLAW_CANONICAL_CREATOR_USER_ID);
- const spaceCreatorUserId = trim(env.SPACE_CREATOR_USER_ID);
- const mode = resolveMode({
- env,
- spaceId,
- canonicalSpaceId,
- canonicalCreatorUserId,
- spaceCreatorUserId
- });
- const owner = ownerFromSpaceId(spaceId);
- const stateBucket = trim(env.OPENCLAW_HF_STATE_BUCKET);
- const gatewayLocation = trim(env.MLCLAW_GATEWAY_LOCATION);
- const localAccessUser = gatewayLocation === "local" ? trim(env.MLCLAW_LOCAL_ACCESS_USER) ?? ownerFromRepoId(stateBucket) : void 0;
- const configuredAllowedUsers = splitUsers(env.MLCLAW_ALLOWED_USERS ?? env.ALLOWED_USERS);
- const configuredAdmins = splitUsers(env.MLCLAW_ADMINS);
- const resolvedAdmins = uniqueUsers([
- ...configuredAdmins.length > 0 ? configuredAdmins : owner ? [owner] : configuredAllowedUsers.slice(0, 1),
- ...localAccessUser ? [localAccessUser] : []
- ]);
- const allowedUsers = uniqueUsers([...configuredAllowedUsers, ...resolvedAdmins, ...owner ? [owner] : []]);
- const publicUrl = publicUrlFromEnv(env, port);
- const accessOrigins = accessOriginsFromEnv(env, publicUrl);
- const sessionSecret = trim(env.MLCLAW_SESSION_SECRET ?? env.SESSION_SECRET) ?? randomBytes(48).toString("base64url");
- const configuredCredentialKey = trim(env.MLCLAW_CREDENTIAL_KEY);
- if (mode === "app" && !configuredCredentialKey) {
- throw new Error("MLCLAW_CREDENTIAL_KEY is required in app mode; run mlclaw doctor --fix");
+ length(len, message) {
+ return this._addCheck({
+ kind: "length",
+ value: len,
+ ...errorUtil.errToObj(message)
+ });
}
- const credentialKey = configuredCredentialKey ?? randomBytes(32).toString("base64url");
- const openclawCommand = trim(env.MLCLAW_OPENCLAW_COMMAND) ?? "openclaw";
- const openclawArgs = splitArgs(env.MLCLAW_OPENCLAW_ARGS) ?? ["gateway"];
- const runtimeSettingsFile = trim(env.MLCLAW_RUNTIME_SETTINGS_FILE) ?? "/home/node/.local/share/mlclaw/live/.mlclaw/settings.json";
- const stateMountDir = trim(env.MLCLAW_STATE_MOUNT_DIR);
- const statePrefix = trim(env.OPENCLAW_HF_STATE_PREFIX);
- const mcpCredentialFile = trim(env.MLCLAW_MCP_CREDENTIAL_FILE) ?? (stateMountDir ? `${stateMountDir.replace(/\/+$/, "")}/${normalizeBucketPrefix(statePrefix)}/.mlclaw/mcp-oauth.enc` : `${pathDirname(runtimeSettingsFile)}/mcp-oauth.enc`);
- const openaiCredentialStoreFile = trim(env.MLCLAW_OPENAI_CREDENTIAL_STORE_FILE) ?? (stateMountDir ? `${stateMountDir.replace(/\/+$/, "")}/${normalizeBucketPrefix(statePrefix)}/.mlclaw/openai-api-key.enc` : `${pathDirname(pathDirname(runtimeSettingsFile))}/.mlclaw-protected/control/openai-api-key.enc`);
- const runtimeSettings2 = readRuntimeSettings(runtimeSettingsFile);
- const model = runtimeSettings2.model ?? trim(env.OPENCLAW_MODEL) ?? DEFAULT_MODEL;
- const agentName = trim(env.OPENCLAW_AGENT_NAME);
- return {
- port,
- openclawPort,
- mcpPort,
- openclawHost: trim(env.MLCLAW_OPENCLAW_HOST) ?? "127.0.0.1",
- openclawUid: integer(env.MLCLAW_OPENCLAW_UID, 1e3),
- openclawGid: integer(env.MLCLAW_OPENCLAW_GID, 1e3),
- publicUrl,
- accessOrigins,
- providerUrl: trim(env.OPENID_PROVIDER_URL) ?? "https://huggingface.co",
- oauthClientId: trim(env.OAUTH_CLIENT_ID),
- oauthClientSecret: trim(env.OAUTH_CLIENT_SECRET),
- sessionSecret,
- sessionSecretGenerated: !trim(env.MLCLAW_SESSION_SECRET ?? env.SESSION_SECRET),
- credentialKey,
- credentialKeyGenerated: !configuredCredentialKey,
- cookieSecure: env.MLCLAW_COOKIE_SECURE === "0" ? false : !publicUrl.startsWith("http://"),
- sessionCookieName: gatewayLocation === "local" ? localSessionCookieName(trim(env.MLCLAW_RUNTIME_ID) ?? publicUrl) : SESSION_COOKIE_PREFIX,
- spaceId,
- canonicalSpaceId,
- canonicalCreatorUserId,
- spaceCreatorUserId,
- allowedUsers,
- adminUsers: resolvedAdmins,
- allowAnySignedIn: env.MLCLAW_ALLOW_ANY_SIGNED_IN === "1" || env.MLCLAW_ALLOW_ANY_SIGNED_IN === "true",
- localAccessUser,
- localAccessToken: gatewayLocation === "local" && localAccessUser ? deriveLocalAccessToken(sessionSecret) : void 0,
- mode,
- hfToken: readOptionalSecret(trim(env.MLCLAW_TRUSTED_HF_TOKEN_FILE)) ?? trim(env.HF_TOKEN ?? env.HUGGINGFACE_HUB_TOKEN),
- routerToken: trim(env.MLCLAW_ROUTER_TOKEN ?? env.HF_ROUTER_TOKEN),
- brokerAgentUrl: trim(env.MLCLAW_HF_BROKER_URL),
- brokerAgentSecret: readOptionalSecret(trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE)),
- brokerAgentSecretFile: trim(env.MLCLAW_HF_BROKER_AGENT_SECRET_FILE),
- operatorBrokers: loadOperatorBrokers(trim(env.MLCLAW_OPERATOR_BROKERS_FILE)),
- brokerKitPopoverDecisions: env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "0" && env.MLCLAW_BROKERKIT_POPOVER_DECISIONS !== "false",
- hubUrl: trim(env.HF_ENDPOINT) ?? "https://huggingface.co",
- openaiCredentialFile: trim(env.MLCLAW_OPENAI_CREDENTIAL_FILE) ?? "/tmp/mlclaw-secrets/openai.env",
- openaiCredentialStoreFile,
- mcpCredentialFile,
- hfMcpUrl: trim(env.MLCLAW_HF_MCP_URL) ?? "https://huggingface.co/mcp?bouquet=hf",
- researchMcpUrl: trim(env.MLCLAW_RESEARCH_MCP_URL) ?? "https://evalstate-research-agent-two.hf.space/mcp",
- researchTimeoutMs: integer(env.MLCLAW_RESEARCH_TIMEOUT_MS, 30 * 60 * 1e3),
- researchPollMs: integer(env.MLCLAW_RESEARCH_POLL_MS, 1500),
- runtimeSettingsFile,
- openclawConfigPath: trim(env.OPENCLAW_CONFIG_PATH) ?? "/home/node/.local/share/mlclaw/live/.openclaw/openclaw.json",
- openclawCommand,
- openclawArgs,
- brokerKitPluginPath: trim(env.MLCLAW_BROKERKIT_PLUGIN_PATH) ?? "/opt/openclaw-plugins/node_modules/openclaw-brokerkit",
- agentName,
- model,
- modelChoices: runtimeSettings2.modelChoices ?? parseModelChoicesEnv(env.MLCLAW_MODEL_CHOICES, model),
- routerModelsUrl: trim(env.MLCLAW_ROUTER_MODELS_URL) ?? "https://router.huggingface.co/v1/models",
- stateBucket,
- stateMountDir,
- statePrefix,
- gatewayLocation,
- runtimeImage: trim(env.MLCLAW_RUNTIME_IMAGE),
- runtimeId: trim(env.MLCLAW_RUNTIME_ID),
- templateRev: trim(env.MLCLAW_TEMPLATE_REV),
- assetsDir: trim(env.MLCLAW_ASSETS_DIR) ?? "/app/assets",
- branding: resolveBranding(env, agentName)
- };
-}
-var SESSION_COOKIE_PREFIX = "mlclaw_session";
-function localSessionCookieName(identity) {
- return `${SESSION_COOKIE_PREFIX}_${createHash("sha256").update(identity).digest("hex").slice(0, 12)}`;
-}
-function accessOriginsFromEnv(env, publicUrl) {
- const configured = (env.MLCLAW_ACCESS_ORIGINS ?? "").split(",").map((value) => value.trim()).filter(Boolean);
- if (configured.length > 8) {
- throw new Error("MLCLAW_ACCESS_ORIGINS supports at most 8 origins");
+ /**
+ * Equivalent to `.min(1)`
+ */
+ nonempty(message) {
+ return this.min(1, errorUtil.errToObj(message));
}
- const origins = [.../* @__PURE__ */ new Set([publicUrl, ...configured.map(parseAccessOrigin)])];
- if (origins.length > 8) {
- throw new Error("MLCLAW_ACCESS_ORIGINS supports at most 8 origins including MLCLAW_PUBLIC_URL");
+ trim() {
+ return new _ZodString({
+ ...this._def,
+ checks: [...this._def.checks, { kind: "trim" }]
+ });
}
- return origins;
-}
-function parseAccessOrigin(value) {
- const url = new URL(value);
- if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.hostname.includes("*") || url.pathname !== "/" || url.search || url.hash) {
- throw new Error(
- "MLCLAW_ACCESS_ORIGINS entries must be HTTP origins without credentials, wildcard hosts, paths, queries, or fragments"
- );
+ toLowerCase() {
+ return new _ZodString({
+ ...this._def,
+ checks: [...this._def.checks, { kind: "toLowerCase" }]
+ });
}
- return url.origin;
-}
-function readOptionalSecret(file) {
- if (!file) {
- return void 0;
+ toUpperCase() {
+ return new _ZodString({
+ ...this._def,
+ checks: [...this._def.checks, { kind: "toUpperCase" }]
+ });
}
- try {
- return trim(readFileSync2(file, "utf8"));
- } catch {
- return void 0;
+ get isDatetime() {
+ return !!this._def.checks.find((ch) => ch.kind === "datetime");
}
-}
-function integrationCredentialSlot(config2) {
- return config2.adminUsers[0];
-}
-function pathDirname(file) {
- const slash = file.lastIndexOf("/");
- return slash > 0 ? file.slice(0, slash) : ".";
-}
-function resolveMode(params) {
- if (params.env.MLCLAW_FORCE_TEMPLATE === "1") {
- return "template";
+ get isDate() {
+ return !!this._def.checks.find((ch) => ch.kind === "date");
}
- if (params.env.MLCLAW_FORCE_APP === "1") {
- return "app";
+ get isTime() {
+ return !!this._def.checks.find((ch) => ch.kind === "time");
}
- const isCanonicalSpace = Boolean(params.spaceId && params.spaceId === params.canonicalSpaceId);
- if (!isCanonicalSpace) {
- return "app";
+ get isDuration() {
+ return !!this._def.checks.find((ch) => ch.kind === "duration");
}
- if (!params.canonicalCreatorUserId || !params.spaceCreatorUserId) {
- return "template";
+ get isEmail() {
+ return !!this._def.checks.find((ch) => ch.kind === "email");
}
- return params.canonicalCreatorUserId === params.spaceCreatorUserId ? "template" : "app";
-}
-function publicUrlFromEnv(env, port) {
- const explicit = trim(env.MLCLAW_PUBLIC_URL);
- if (explicit) {
- const url = new URL(explicit);
- if (url.protocol !== "http:" && url.protocol !== "https:" || url.username || url.password || url.pathname !== "/" || url.search || url.hash) {
- throw new Error("MLCLAW_PUBLIC_URL must be one HTTP origin without credentials, path, query, or fragment");
- }
- return url.origin;
+ get isURL() {
+ return !!this._def.checks.find((ch) => ch.kind === "url");
}
- const host = trim(env.SPACE_HOST);
- if (host) {
- return host.startsWith("http") ? host.replace(/\/+$/, "") : `https://${host.replace(/\/+$/, "")}`;
+ get isEmoji() {
+ return !!this._def.checks.find((ch) => ch.kind === "emoji");
}
- return `http://127.0.0.1:${port}`;
-}
-function ownerFromSpaceId(spaceId) {
- return ownerFromRepoId(spaceId);
-}
-function ownerFromRepoId(repoId) {
- const owner = repoId?.split("/")[0]?.trim();
- return owner || void 0;
-}
-function integer(value, fallback) {
- if (!value) {
- return fallback;
+ get isUUID() {
+ return !!this._def.checks.find((ch) => ch.kind === "uuid");
}
- const parsed = Number.parseInt(value, 10);
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
-}
-function splitUsers(value) {
- return (value ?? "").split(",").map((item) => item.trim()).filter(Boolean);
-}
-function uniqueUsers(users) {
- return [...new Set(users)];
-}
-function splitArgs(value) {
- const trimmed = trim(value);
- return trimmed ? trimmed.split(/\s+/).filter(Boolean) : void 0;
-}
-function trim(value) {
- const trimmed = value?.trim();
- return trimmed || void 0;
-}
-function readRuntimeSettings(file) {
- try {
- const parsed = JSON.parse(readFileSync2(file, "utf8"));
- const model = typeof parsed.model === "string" ? parsed.model.trim() : void 0;
- if (!model) {
- return {};
- }
- const modelChoices = normalizeModelChoices(parsed.modelChoices, model);
- return {
- model,
- ...modelChoices ? { modelChoices } : {}
- };
- } catch {
- return {};
+ get isNANOID() {
+ return !!this._def.checks.find((ch) => ch.kind === "nanoid");
}
-}
-
-// src/mlclaw-space-runtime/server.ts
-import { spawn } from "node:child_process";
-import http3 from "node:http";
-import { Readable as Readable2 } from "node:stream";
-
-// src/mlclaw-space-runtime/app.ts
-import fs3 from "node:fs/promises";
-import path3 from "node:path";
-
-// node_modules/hono/dist/compose.js
-var compose = (middleware, onError, onNotFound) => {
- return (context, next) => {
- let index = -1;
- return dispatch(0);
- async function dispatch(i) {
- if (i <= index) {
- throw new Error("next() called multiple times");
- }
- index = i;
- let res;
- let isError = false;
- let handler;
- if (middleware[i]) {
- handler = middleware[i][0][0];
- context.req.routeIndex = i;
- } else {
- handler = i === middleware.length && next || void 0;
- }
- if (handler) {
- try {
- res = await handler(context, () => dispatch(i + 1));
- } catch (err) {
- if (err instanceof Error && onError) {
- context.error = err;
- res = await onError(err, context);
- isError = true;
- } else {
- throw err;
- }
- }
- } else {
- if (context.finalized === false && onNotFound) {
- res = await onNotFound(context);
- }
- }
- if (res && (context.finalized === false || isError)) {
- context.res = res;
- }
- return context;
- }
- };
-};
-
-// node_modules/hono/dist/request/constants.js
-var GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
-
-// node_modules/hono/dist/utils/buffer.js
-var bufferToFormData = (arrayBuffer, contentType2) => {
- const response = new Response(arrayBuffer, {
- headers: {
- // Normalize the media type (case-insensitive) while keeping parameters like the boundary
- "Content-Type": contentType2.replace(/^[^;]+/, (mediaType) => mediaType.toLowerCase())
- }
- });
- return response.formData();
-};
-
-// node_modules/hono/dist/utils/body.js
-var isRawRequest = (request) => "headers" in request;
-var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {
- const { all = false, dot = false } = options;
- const headers = isRawRequest(request) ? request.headers : request.raw.headers;
- const contentType2 = headers.get("Content-Type");
- const mediaType = contentType2?.split(";")[0].trim().toLowerCase();
- if (mediaType === "multipart/form-data" || mediaType === "application/x-www-form-urlencoded") {
- return parseFormData(request, { all, dot });
+ get isCUID() {
+ return !!this._def.checks.find((ch) => ch.kind === "cuid");
}
- return {};
-};
-async function parseFormData(request, options) {
- const headers = isRawRequest(request) ? request.headers : request.raw.headers;
- const arrayBuffer = await request.arrayBuffer();
- const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
- if (!isRawRequest(request)) {
- request.bodyCache.formData = formDataPromise;
+ get isCUID2() {
+ return !!this._def.checks.find((ch) => ch.kind === "cuid2");
}
- const formData = await formDataPromise;
- if (formData) {
- return convertFormDataToBodyData(formData, options);
+ get isULID() {
+ return !!this._def.checks.find((ch) => ch.kind === "ulid");
}
- return {};
-}
-function convertFormDataToBodyData(formData, options) {
- const form = /* @__PURE__ */ Object.create(null);
- formData.forEach((value, key) => {
- const shouldParseAllValues = options.all || key.endsWith("[]");
- if (!shouldParseAllValues) {
- form[key] = value;
- } else {
- handleParsingAllValues(form, key, value);
- }
- });
- if (options.dot) {
- Object.entries(form).forEach(([key, value]) => {
- const shouldParseDotValues = key.includes(".");
- if (shouldParseDotValues) {
- handleParsingNestedValues(form, key, value);
- delete form[key];
- }
- });
+ get isIP() {
+ return !!this._def.checks.find((ch) => ch.kind === "ip");
}
- return form;
-}
-var handleParsingAllValues = (form, key, value) => {
- if (form[key] !== void 0) {
- if (Array.isArray(form[key])) {
- ;
- form[key].push(value);
- } else {
- form[key] = [form[key], value];
- }
- } else {
- if (!key.endsWith("[]")) {
- form[key] = value;
- } else {
- form[key] = [value];
- }
+ get isCIDR() {
+ return !!this._def.checks.find((ch) => ch.kind === "cidr");
+ }
+ get isBase64() {
+ return !!this._def.checks.find((ch) => ch.kind === "base64");
}
-};
-var handleParsingNestedValues = (form, key, value) => {
- if (/(?:^|\.)__proto__\./.test(key)) {
- return;
+ get isBase64url() {
+ return !!this._def.checks.find((ch) => ch.kind === "base64url");
}
- let nestedForm = form;
- const keys = key.split(".");
- keys.forEach((key2, index) => {
- if (index === keys.length - 1) {
- nestedForm[key2] = value;
- } else {
- if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {
- nestedForm[key2] = /* @__PURE__ */ Object.create(null);
+ get minLength() {
+ let min = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "min") {
+ if (min === null || ch.value > min)
+ min = ch.value;
}
- nestedForm = nestedForm[key2];
}
- });
-};
-
-// node_modules/hono/dist/utils/url.js
-var splitPath = (path5) => {
- const paths = path5.split("/");
- if (paths[0] === "") {
- paths.shift();
+ return min;
}
- return paths;
-};
-var splitRoutingPath = (routePath) => {
- const { groups, path: path5 } = extractGroupsFromPath(routePath);
- const paths = splitPath(path5);
- return replaceGroupMarks(paths, groups);
-};
-var extractGroupsFromPath = (path5) => {
- const groups = [];
- path5 = path5.replace(/\{[^}]+\}/g, (match2, index) => {
- const mark = `@${index}`;
- groups.push([mark, match2]);
- return mark;
- });
- return { groups, path: path5 };
-};
-var replaceGroupMarks = (paths, groups) => {
- for (let i = groups.length - 1; i >= 0; i--) {
- const [mark] = groups[i];
- for (let j = paths.length - 1; j >= 0; j--) {
- if (paths[j].includes(mark)) {
- paths[j] = paths[j].replace(mark, groups[i][1]);
- break;
+ get maxLength() {
+ let max = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "max") {
+ if (max === null || ch.value < max)
+ max = ch.value;
}
}
+ return max;
}
- return paths;
};
-var patternCache = {};
-var getPattern = (label, next) => {
- if (label === "*") {
- return "*";
+ZodString.create = (params) => {
+ return new ZodString({
+ checks: [],
+ typeName: ZodFirstPartyTypeKind.ZodString,
+ coerce: params?.coerce ?? false,
+ ...processCreateParams(params)
+ });
+};
+function floatSafeRemainder(val, step) {
+ const valDecCount = (val.toString().split(".")[1] || "").length;
+ const stepDecCount = (step.toString().split(".")[1] || "").length;
+ const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
+ const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
+ const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
+ return valInt % stepInt / 10 ** decCount;
+}
+var ZodNumber = class _ZodNumber extends ZodType {
+ constructor() {
+ super(...arguments);
+ this.min = this.gte;
+ this.max = this.lte;
+ this.step = this.multipleOf;
}
- const match2 = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
- if (match2) {
- const cacheKey = `${label}#${next}`;
- if (!patternCache[cacheKey]) {
- if (match2[2]) {
- patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match2[1], new RegExp(`^${match2[2]}(?=/${next})`)] : [label, match2[1], new RegExp(`^${match2[2]}$`)];
+ _parse(input) {
+ if (this._def.coerce) {
+ input.data = Number(input.data);
+ }
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.number) {
+ const ctx2 = this._getOrReturnCtx(input);
+ addIssueToContext(ctx2, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.number,
+ received: ctx2.parsedType
+ });
+ return INVALID;
+ }
+ let ctx = void 0;
+ const status = new ParseStatus();
+ for (const check of this._def.checks) {
+ if (check.kind === "int") {
+ if (!util.isInteger(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: "integer",
+ received: "float",
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "min") {
+ const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
+ if (tooSmall) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: check.value,
+ type: "number",
+ inclusive: check.inclusive,
+ exact: false,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "max") {
+ const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
+ if (tooBig) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: check.value,
+ type: "number",
+ inclusive: check.inclusive,
+ exact: false,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "multipleOf") {
+ if (floatSafeRemainder(input.data, check.value) !== 0) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.not_multiple_of,
+ multipleOf: check.value,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "finite") {
+ if (!Number.isFinite(input.data)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.not_finite,
+ message: check.message
+ });
+ status.dirty();
+ }
} else {
- patternCache[cacheKey] = [label, match2[1], true];
+ util.assertNever(check);
}
}
- return patternCache[cacheKey];
+ return { status: status.value, value: input.data };
}
- return null;
-};
-var tryDecode = (str, decoder) => {
- try {
- return decoder(str);
- } catch {
- return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
- try {
- return decoder(match2);
- } catch {
- return match2;
- }
+ gte(value, message) {
+ return this.setLimit("min", value, true, errorUtil.toString(message));
+ }
+ gt(value, message) {
+ return this.setLimit("min", value, false, errorUtil.toString(message));
+ }
+ lte(value, message) {
+ return this.setLimit("max", value, true, errorUtil.toString(message));
+ }
+ lt(value, message) {
+ return this.setLimit("max", value, false, errorUtil.toString(message));
+ }
+ setLimit(kind, value, inclusive, message) {
+ return new _ZodNumber({
+ ...this._def,
+ checks: [
+ ...this._def.checks,
+ {
+ kind,
+ value,
+ inclusive,
+ message: errorUtil.toString(message)
+ }
+ ]
});
}
-};
-var tryDecodeURI = (str) => tryDecode(str, decodeURI);
-var getPath = (request) => {
- const url = request.url;
- const start = url.indexOf("/", url.indexOf(":") + 4);
- let i = start;
- for (; i < url.length; i++) {
- const charCode = url.charCodeAt(i);
- if (charCode === 37) {
- const queryIndex = url.indexOf("?", i);
- const hashIndex = url.indexOf("#", i);
- const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);
- const path5 = url.slice(start, end);
- return tryDecodeURI(path5.includes("%25") ? path5.replace(/%25/g, "%2525") : path5);
- } else if (charCode === 63 || charCode === 35) {
- break;
- }
+ _addCheck(check) {
+ return new _ZodNumber({
+ ...this._def,
+ checks: [...this._def.checks, check]
+ });
+ }
+ int(message) {
+ return this._addCheck({
+ kind: "int",
+ message: errorUtil.toString(message)
+ });
+ }
+ positive(message) {
+ return this._addCheck({
+ kind: "min",
+ value: 0,
+ inclusive: false,
+ message: errorUtil.toString(message)
+ });
+ }
+ negative(message) {
+ return this._addCheck({
+ kind: "max",
+ value: 0,
+ inclusive: false,
+ message: errorUtil.toString(message)
+ });
+ }
+ nonpositive(message) {
+ return this._addCheck({
+ kind: "max",
+ value: 0,
+ inclusive: true,
+ message: errorUtil.toString(message)
+ });
}
- return url.slice(start, i);
-};
-var getPathNoStrict = (request) => {
- const result = getPath(request);
- return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
-};
-var mergePath = (base, sub, ...rest) => {
- if (rest.length) {
- sub = mergePath(sub, ...rest);
+ nonnegative(message) {
+ return this._addCheck({
+ kind: "min",
+ value: 0,
+ inclusive: true,
+ message: errorUtil.toString(message)
+ });
}
- return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
-};
-var checkOptionalParameter = (path5) => {
- if (path5.charCodeAt(path5.length - 1) !== 63 || !path5.includes(":")) {
- return null;
+ multipleOf(value, message) {
+ return this._addCheck({
+ kind: "multipleOf",
+ value,
+ message: errorUtil.toString(message)
+ });
}
- const segments = path5.split("/");
- const results = [];
- let basePath = "";
- segments.forEach((segment) => {
- if (segment !== "" && !/\:/.test(segment)) {
- basePath += "/" + segment;
- } else if (/\:/.test(segment)) {
- if (/\?/.test(segment)) {
- if (results.length === 0 && basePath === "") {
- results.push("/");
- } else {
- results.push(basePath);
- }
- const optionalSegment = segment.replace("?", "");
- basePath += "/" + optionalSegment;
- results.push(basePath);
- } else {
- basePath += "/" + segment;
- }
- }
- });
- return results.filter((v, i, a) => a.indexOf(v) === i);
-};
-var _decodeURI = (value) => {
- if (!/[%+]/.test(value)) {
- return value;
+ finite(message) {
+ return this._addCheck({
+ kind: "finite",
+ message: errorUtil.toString(message)
+ });
}
- if (value.indexOf("+") !== -1) {
- value = value.replace(/\+/g, " ");
+ safe(message) {
+ return this._addCheck({
+ kind: "min",
+ inclusive: true,
+ value: Number.MIN_SAFE_INTEGER,
+ message: errorUtil.toString(message)
+ })._addCheck({
+ kind: "max",
+ inclusive: true,
+ value: Number.MAX_SAFE_INTEGER,
+ message: errorUtil.toString(message)
+ });
}
- return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
-};
-var _getQueryParam = (url, key, multiple) => {
- let encoded;
- if (!multiple && key && !/[%+]/.test(key)) {
- let keyIndex2 = url.indexOf("?", 8);
- if (keyIndex2 === -1) {
- return void 0;
- }
- if (!url.startsWith(key, keyIndex2 + 1)) {
- keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
- }
- while (keyIndex2 !== -1) {
- const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);
- if (trailingKeyCode === 61) {
- const valueIndex = keyIndex2 + key.length + 2;
- const endIndex = url.indexOf("&", valueIndex);
- return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));
- } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {
- return "";
+ get minValue() {
+ let min = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "min") {
+ if (min === null || ch.value > min)
+ min = ch.value;
}
- keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);
- }
- encoded = /[%+]/.test(url);
- if (!encoded) {
- return void 0;
}
+ return min;
}
- const results = {};
- encoded ??= /[%+]/.test(url);
- let keyIndex = url.indexOf("?", 8);
- while (keyIndex !== -1) {
- const nextKeyIndex = url.indexOf("&", keyIndex + 1);
- let valueIndex = url.indexOf("=", keyIndex);
- if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {
- valueIndex = -1;
- }
- let name = url.slice(
- keyIndex + 1,
- valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex
- );
- if (encoded) {
- name = _decodeURI(name);
- }
- keyIndex = nextKeyIndex;
- if (name === "") {
- continue;
- }
- let value;
- if (valueIndex === -1) {
- value = "";
- } else {
- value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);
- if (encoded) {
- value = _decodeURI(value);
+ get maxValue() {
+ let max = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "max") {
+ if (max === null || ch.value < max)
+ max = ch.value;
}
}
- if (multiple) {
- if (!(results[name] && Array.isArray(results[name]))) {
- results[name] = [];
+ return max;
+ }
+ get isInt() {
+ return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value));
+ }
+ get isFinite() {
+ let max = null;
+ let min = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
+ return true;
+ } else if (ch.kind === "min") {
+ if (min === null || ch.value > min)
+ min = ch.value;
+ } else if (ch.kind === "max") {
+ if (max === null || ch.value < max)
+ max = ch.value;
}
- ;
- results[name].push(value);
- } else {
- results[name] ??= value;
}
+ return Number.isFinite(min) && Number.isFinite(max);
}
- return key ? results[key] : results;
};
-var getQueryParam = _getQueryParam;
-var getQueryParams = (url, key) => {
- return _getQueryParam(url, key, true);
+ZodNumber.create = (params) => {
+ return new ZodNumber({
+ checks: [],
+ typeName: ZodFirstPartyTypeKind.ZodNumber,
+ coerce: params?.coerce || false,
+ ...processCreateParams(params)
+ });
};
-var decodeURIComponent_ = decodeURIComponent;
-
-// node_modules/hono/dist/request.js
-var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
-var HonoRequest = class {
- /**
- * `.raw` can get the raw Request object.
- *
- * @see {@link https://hono.dev/docs/api/request#raw}
- *
- * @example
- * ```ts
- * // For Cloudflare Workers
- * app.post('/', async (c) => {
- * const metadata = c.req.raw.cf?.hostMetadata?
- * ...
- * })
- * ```
- */
- raw;
- #validatedData;
- // Short name of validatedData
- #matchResult;
- routeIndex = 0;
- /**
- * `.path` can get the pathname of the request.
- *
- * @see {@link https://hono.dev/docs/api/request#path}
- *
- * @example
- * ```ts
- * app.get('/about/me', (c) => {
- * const pathname = c.req.path // `/about/me`
- * })
- * ```
- */
- path;
- bodyCache = {};
- constructor(request, path5 = "/", matchResult = [[]]) {
- this.raw = request;
- this.path = path5;
- this.#matchResult = matchResult;
- this.#validatedData = {};
+var ZodBigInt = class _ZodBigInt extends ZodType {
+ constructor() {
+ super(...arguments);
+ this.min = this.gte;
+ this.max = this.lte;
+ }
+ _parse(input) {
+ if (this._def.coerce) {
+ try {
+ input.data = BigInt(input.data);
+ } catch {
+ return this._getInvalidInput(input);
+ }
+ }
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.bigint) {
+ return this._getInvalidInput(input);
+ }
+ let ctx = void 0;
+ const status = new ParseStatus();
+ for (const check of this._def.checks) {
+ if (check.kind === "min") {
+ const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
+ if (tooSmall) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ type: "bigint",
+ minimum: check.value,
+ inclusive: check.inclusive,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "max") {
+ const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
+ if (tooBig) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ type: "bigint",
+ maximum: check.value,
+ inclusive: check.inclusive,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "multipleOf") {
+ if (input.data % check.value !== BigInt(0)) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.not_multiple_of,
+ multipleOf: check.value,
+ message: check.message
+ });
+ status.dirty();
+ }
+ } else {
+ util.assertNever(check);
+ }
+ }
+ return { status: status.value, value: input.data };
}
- param(key) {
- return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
+ _getInvalidInput(input) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.bigint,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- #getDecodedParam(key) {
- const paramKey = this.#matchResult[0][this.routeIndex][1][key];
- const param = this.#getParamValue(paramKey);
- return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
+ gte(value, message) {
+ return this.setLimit("min", value, true, errorUtil.toString(message));
}
- #getAllDecodedParams() {
- const decoded = {};
- const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);
- for (const key of keys) {
- const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
- if (value !== void 0) {
- decoded[key] = /\%/.test(value) ? tryDecodeURIComponent(value) : value;
- }
- }
- return decoded;
+ gt(value, message) {
+ return this.setLimit("min", value, false, errorUtil.toString(message));
}
- #getParamValue(paramKey) {
- return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
+ lte(value, message) {
+ return this.setLimit("max", value, true, errorUtil.toString(message));
}
- query(key) {
- return getQueryParam(this.url, key);
+ lt(value, message) {
+ return this.setLimit("max", value, false, errorUtil.toString(message));
}
- queries(key) {
- return getQueryParams(this.url, key);
+ setLimit(kind, value, inclusive, message) {
+ return new _ZodBigInt({
+ ...this._def,
+ checks: [
+ ...this._def.checks,
+ {
+ kind,
+ value,
+ inclusive,
+ message: errorUtil.toString(message)
+ }
+ ]
+ });
}
- header(name) {
- if (name) {
- return this.raw.headers.get(name) ?? void 0;
- }
- const headerData = {};
- this.raw.headers.forEach((value, key) => {
- headerData[key] = value;
+ _addCheck(check) {
+ return new _ZodBigInt({
+ ...this._def,
+ checks: [...this._def.checks, check]
});
- return headerData;
}
- async parseBody(options) {
- return parseBody(this, options);
+ positive(message) {
+ return this._addCheck({
+ kind: "min",
+ value: BigInt(0),
+ inclusive: false,
+ message: errorUtil.toString(message)
+ });
}
- #cachedBody = (key) => {
- const { bodyCache, raw: raw2 } = this;
- const cachedBody = bodyCache[key];
- if (cachedBody) {
- return cachedBody;
- }
- const anyCachedKey = Object.keys(bodyCache)[0];
- if (anyCachedKey) {
- return bodyCache[anyCachedKey].then((body) => {
- if (anyCachedKey === "json") {
- body = JSON.stringify(body);
- }
- return new Response(body)[key]();
- });
- }
- return bodyCache[key] = raw2[key]();
- };
- /**
- * `.json()` can parse Request body of type `application/json`
- *
- * @see {@link https://hono.dev/docs/api/request#json}
- *
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.json()
- * })
- * ```
- */
- json() {
- return this.#cachedBody("text").then((text) => JSON.parse(text));
+ negative(message) {
+ return this._addCheck({
+ kind: "max",
+ value: BigInt(0),
+ inclusive: false,
+ message: errorUtil.toString(message)
+ });
}
- /**
- * `.text()` can parse Request body of type `text/plain`
- *
- * @see {@link https://hono.dev/docs/api/request#text}
- *
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.text()
- * })
- * ```
- */
- text() {
- return this.#cachedBody("text");
+ nonpositive(message) {
+ return this._addCheck({
+ kind: "max",
+ value: BigInt(0),
+ inclusive: true,
+ message: errorUtil.toString(message)
+ });
}
- /**
- * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
- *
- * @see {@link https://hono.dev/docs/api/request#arraybuffer}
- *
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.arrayBuffer()
- * })
- * ```
- */
- arrayBuffer() {
- return this.#cachedBody("arrayBuffer");
+ nonnegative(message) {
+ return this._addCheck({
+ kind: "min",
+ value: BigInt(0),
+ inclusive: true,
+ message: errorUtil.toString(message)
+ });
}
- /**
- * `.bytes()` parses the request body as a `Uint8Array`.
- *
- * @see {@link https://hono.dev/docs/api/request#bytes}
- *
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.bytes()
- * })
- * ```
- */
- bytes() {
- return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
+ multipleOf(value, message) {
+ return this._addCheck({
+ kind: "multipleOf",
+ value,
+ message: errorUtil.toString(message)
+ });
}
- /**
- * Parses the request body as a `Blob`.
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.blob();
- * });
- * ```
- * @see https://hono.dev/docs/api/request#blob
- */
- blob() {
- return this.#cachedBody("blob");
+ get minValue() {
+ let min = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "min") {
+ if (min === null || ch.value > min)
+ min = ch.value;
+ }
+ }
+ return min;
+ }
+ get maxValue() {
+ let max = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "max") {
+ if (max === null || ch.value < max)
+ max = ch.value;
+ }
+ }
+ return max;
+ }
+};
+ZodBigInt.create = (params) => {
+ return new ZodBigInt({
+ checks: [],
+ typeName: ZodFirstPartyTypeKind.ZodBigInt,
+ coerce: params?.coerce ?? false,
+ ...processCreateParams(params)
+ });
+};
+var ZodBoolean = class extends ZodType {
+ _parse(input) {
+ if (this._def.coerce) {
+ input.data = Boolean(input.data);
+ }
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.boolean) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.boolean,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return OK(input.data);
}
- /**
- * Parses the request body as `FormData`.
- * @example
- * ```ts
- * app.post('/entry', async (c) => {
- * const body = await c.req.formData();
- * });
- * ```
- * @see https://hono.dev/docs/api/request#formdata
- */
- formData() {
- return this.#cachedBody("formData");
+};
+ZodBoolean.create = (params) => {
+ return new ZodBoolean({
+ typeName: ZodFirstPartyTypeKind.ZodBoolean,
+ coerce: params?.coerce || false,
+ ...processCreateParams(params)
+ });
+};
+var ZodDate = class _ZodDate extends ZodType {
+ _parse(input) {
+ if (this._def.coerce) {
+ input.data = new Date(input.data);
+ }
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.date) {
+ const ctx2 = this._getOrReturnCtx(input);
+ addIssueToContext(ctx2, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.date,
+ received: ctx2.parsedType
+ });
+ return INVALID;
+ }
+ if (Number.isNaN(input.data.getTime())) {
+ const ctx2 = this._getOrReturnCtx(input);
+ addIssueToContext(ctx2, {
+ code: ZodIssueCode.invalid_date
+ });
+ return INVALID;
+ }
+ const status = new ParseStatus();
+ let ctx = void 0;
+ for (const check of this._def.checks) {
+ if (check.kind === "min") {
+ if (input.data.getTime() < check.value) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ message: check.message,
+ inclusive: true,
+ exact: false,
+ minimum: check.value,
+ type: "date"
+ });
+ status.dirty();
+ }
+ } else if (check.kind === "max") {
+ if (input.data.getTime() > check.value) {
+ ctx = this._getOrReturnCtx(input, ctx);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ message: check.message,
+ inclusive: true,
+ exact: false,
+ maximum: check.value,
+ type: "date"
+ });
+ status.dirty();
+ }
+ } else {
+ util.assertNever(check);
+ }
+ }
+ return {
+ status: status.value,
+ value: new Date(input.data.getTime())
+ };
}
- /**
- * Adds validated data to the request.
- *
- * @param target - The target of the validation.
- * @param data - The validated data to add.
- */
- addValidatedData(target, data) {
- this.#validatedData[target] = data;
+ _addCheck(check) {
+ return new _ZodDate({
+ ...this._def,
+ checks: [...this._def.checks, check]
+ });
}
- valid(target) {
- return this.#validatedData[target];
+ min(minDate, message) {
+ return this._addCheck({
+ kind: "min",
+ value: minDate.getTime(),
+ message: errorUtil.toString(message)
+ });
}
- /**
- * `.url()` can get the request url strings.
- *
- * @see {@link https://hono.dev/docs/api/request#url}
- *
- * @example
- * ```ts
- * app.get('/about/me', (c) => {
- * const url = c.req.url // `http://localhost:8787/about/me`
- * ...
- * })
- * ```
- */
- get url() {
- return this.raw.url;
+ max(maxDate, message) {
+ return this._addCheck({
+ kind: "max",
+ value: maxDate.getTime(),
+ message: errorUtil.toString(message)
+ });
}
- /**
- * `.method()` can get the method name of the request.
- *
- * @see {@link https://hono.dev/docs/api/request#method}
- *
- * @example
- * ```ts
- * app.get('/about/me', (c) => {
- * const method = c.req.method // `GET`
- * })
- * ```
- */
- get method() {
- return this.raw.method;
+ get minDate() {
+ let min = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "min") {
+ if (min === null || ch.value > min)
+ min = ch.value;
+ }
+ }
+ return min != null ? new Date(min) : null;
}
- get [GET_MATCH_RESULT]() {
- return this.#matchResult;
+ get maxDate() {
+ let max = null;
+ for (const ch of this._def.checks) {
+ if (ch.kind === "max") {
+ if (max === null || ch.value < max)
+ max = ch.value;
+ }
+ }
+ return max != null ? new Date(max) : null;
}
- /**
- * `.matchedRoutes()` can return a matched route in the handler
- *
- * @deprecated
- *
- * Use matchedRoutes helper defined in "hono/route" instead.
- *
- * @see {@link https://hono.dev/docs/api/request#matchedroutes}
- *
- * @example
- * ```ts
- * app.use('*', async function logger(c, next) {
- * await next()
- * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
- * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
- * console.log(
- * method,
- * ' ',
- * path,
- * ' '.repeat(Math.max(10 - path.length, 0)),
- * name,
- * i === c.req.routeIndex ? '<- respond from here' : ''
- * )
- * })
- * })
- * ```
- */
- get matchedRoutes() {
- return this.#matchResult[0].map(([[, route]]) => route);
+};
+ZodDate.create = (params) => {
+ return new ZodDate({
+ checks: [],
+ coerce: params?.coerce || false,
+ typeName: ZodFirstPartyTypeKind.ZodDate,
+ ...processCreateParams(params)
+ });
+};
+var ZodSymbol = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.symbol) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.symbol,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return OK(input.data);
}
- /**
- * `routePath()` can retrieve the path registered within the handler
- *
- * @deprecated
- *
- * Use routePath helper defined in "hono/route" instead.
- *
- * @see {@link https://hono.dev/docs/api/request#routepath}
- *
- * @example
- * ```ts
- * app.get('/posts/:id', (c) => {
- * return c.json({ path: c.req.routePath })
- * })
- * ```
- */
- get routePath() {
- return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
+};
+ZodSymbol.create = (params) => {
+ return new ZodSymbol({
+ typeName: ZodFirstPartyTypeKind.ZodSymbol,
+ ...processCreateParams(params)
+ });
+};
+var ZodUndefined = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.undefined) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.undefined,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return OK(input.data);
+ }
+};
+ZodUndefined.create = (params) => {
+ return new ZodUndefined({
+ typeName: ZodFirstPartyTypeKind.ZodUndefined,
+ ...processCreateParams(params)
+ });
+};
+var ZodNull = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.null) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.null,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return OK(input.data);
}
};
-
-// node_modules/hono/dist/utils/html.js
-var HtmlEscapedCallbackPhase = {
- Stringify: 1,
- BeforeStream: 2,
- Stream: 3
+ZodNull.create = (params) => {
+ return new ZodNull({
+ typeName: ZodFirstPartyTypeKind.ZodNull,
+ ...processCreateParams(params)
+ });
};
-var raw = (value, callbacks) => {
- const escapedString = new String(value);
- escapedString.isEscaped = true;
- escapedString.callbacks = callbacks;
- return escapedString;
+var ZodAny = class extends ZodType {
+ constructor() {
+ super(...arguments);
+ this._any = true;
+ }
+ _parse(input) {
+ return OK(input.data);
+ }
};
-var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {
- if (typeof str === "object" && !(str instanceof String)) {
- if (!(str instanceof Promise)) {
- str = str.toString();
- }
- if (str instanceof Promise) {
- str = await str;
- }
+ZodAny.create = (params) => {
+ return new ZodAny({
+ typeName: ZodFirstPartyTypeKind.ZodAny,
+ ...processCreateParams(params)
+ });
+};
+var ZodUnknown = class extends ZodType {
+ constructor() {
+ super(...arguments);
+ this._unknown = true;
}
- const callbacks = str.callbacks;
- if (!callbacks?.length) {
- return Promise.resolve(str);
+ _parse(input) {
+ return OK(input.data);
}
- if (buffer) {
- buffer[0] += str;
- } else {
- buffer = [str];
+};
+ZodUnknown.create = (params) => {
+ return new ZodUnknown({
+ typeName: ZodFirstPartyTypeKind.ZodUnknown,
+ ...processCreateParams(params)
+ });
+};
+var ZodNever = class extends ZodType {
+ _parse(input) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.never,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(
- (res) => Promise.all(
- res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))
- ).then(() => buffer[0])
- );
- if (preserveCallbacks) {
- return raw(await resStr, callbacks);
- } else {
- return resStr;
+};
+ZodNever.create = (params) => {
+ return new ZodNever({
+ typeName: ZodFirstPartyTypeKind.ZodNever,
+ ...processCreateParams(params)
+ });
+};
+var ZodVoid = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.undefined) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.void,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return OK(input.data);
}
};
-
-// node_modules/hono/dist/context.js
-var TEXT_PLAIN = "text/plain; charset=UTF-8";
-var setDefaultContentType = (contentType2, headers) => {
- return {
- "Content-Type": contentType2,
- ...headers
- };
+ZodVoid.create = (params) => {
+ return new ZodVoid({
+ typeName: ZodFirstPartyTypeKind.ZodVoid,
+ ...processCreateParams(params)
+ });
};
-var createResponseInstance = (body, init) => new Response(body, init);
-var Context = class {
- #rawRequest;
- #req;
- /**
- * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
- *
- * @see {@link https://hono.dev/docs/api/context#env}
- *
- * @example
- * ```ts
- * // Environment object for Cloudflare Workers
- * app.get('*', async c => {
- * const counter = c.env.COUNTER
- * })
- * ```
- */
- env = {};
- #var;
- finalized = false;
- /**
- * `.error` can get the error object from the middleware if the Handler throws an error.
- *
- * @see {@link https://hono.dev/docs/api/context#error}
- *
- * @example
- * ```ts
- * app.use('*', async (c, next) => {
- * await next()
- * if (c.error) {
- * // do something...
- * }
- * })
- * ```
- */
- error;
- #status;
- #executionCtx;
- #res;
- #layout;
- #renderer;
- #notFoundHandler;
- #preparedHeaders;
- #matchResult;
- #path;
- /**
- * Creates an instance of the Context class.
- *
- * @param req - The Request object.
- * @param options - Optional configuration options for the context.
- */
- constructor(req, options) {
- this.#rawRequest = req;
- if (options) {
- this.#executionCtx = options.executionCtx;
- this.env = options.env;
- this.#notFoundHandler = options.notFoundHandler;
- this.#path = options.path;
- this.#matchResult = options.matchResult;
+var ZodArray = class _ZodArray extends ZodType {
+ _parse(input) {
+ const { ctx, status } = this._processInputParams(input);
+ const def = this._def;
+ if (ctx.parsedType !== ZodParsedType.array) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.array,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ if (def.exactLength !== null) {
+ const tooBig = ctx.data.length > def.exactLength.value;
+ const tooSmall = ctx.data.length < def.exactLength.value;
+ if (tooBig || tooSmall) {
+ addIssueToContext(ctx, {
+ code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,
+ minimum: tooSmall ? def.exactLength.value : void 0,
+ maximum: tooBig ? def.exactLength.value : void 0,
+ type: "array",
+ inclusive: true,
+ exact: true,
+ message: def.exactLength.message
+ });
+ status.dirty();
+ }
+ }
+ if (def.minLength !== null) {
+ if (ctx.data.length < def.minLength.value) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: def.minLength.value,
+ type: "array",
+ inclusive: true,
+ exact: false,
+ message: def.minLength.message
+ });
+ status.dirty();
+ }
+ }
+ if (def.maxLength !== null) {
+ if (ctx.data.length > def.maxLength.value) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: def.maxLength.value,
+ type: "array",
+ inclusive: true,
+ exact: false,
+ message: def.maxLength.message
+ });
+ status.dirty();
+ }
+ }
+ if (ctx.common.async) {
+ return Promise.all([...ctx.data].map((item, i) => {
+ return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
+ })).then((result2) => {
+ return ParseStatus.mergeArray(status, result2);
+ });
}
+ const result = [...ctx.data].map((item, i) => {
+ return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
+ });
+ return ParseStatus.mergeArray(status, result);
+ }
+ get element() {
+ return this._def.type;
+ }
+ min(minLength, message) {
+ return new _ZodArray({
+ ...this._def,
+ minLength: { value: minLength, message: errorUtil.toString(message) }
+ });
+ }
+ max(maxLength, message) {
+ return new _ZodArray({
+ ...this._def,
+ maxLength: { value: maxLength, message: errorUtil.toString(message) }
+ });
}
- /**
- * `.req` is the instance of {@link HonoRequest}.
- */
- get req() {
- this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);
- return this.#req;
+ length(len, message) {
+ return new _ZodArray({
+ ...this._def,
+ exactLength: { value: len, message: errorUtil.toString(message) }
+ });
}
- /**
- * @see {@link https://hono.dev/docs/api/context#event}
- * The FetchEvent associated with the current request.
- *
- * @throws Will throw an error if the context does not have a FetchEvent.
- */
- get event() {
- if (this.#executionCtx && "respondWith" in this.#executionCtx) {
- return this.#executionCtx;
- } else {
- throw Error("This context has no FetchEvent");
- }
+ nonempty(message) {
+ return this.min(1, message);
}
- /**
- * @see {@link https://hono.dev/docs/api/context#executionctx}
- * The ExecutionContext associated with the current request.
- *
- * @throws Will throw an error if the context does not have an ExecutionContext.
- */
- get executionCtx() {
- if (this.#executionCtx) {
- return this.#executionCtx;
- } else {
- throw Error("This context has no ExecutionContext");
+};
+ZodArray.create = (schema, params) => {
+ return new ZodArray({
+ type: schema,
+ minLength: null,
+ maxLength: null,
+ exactLength: null,
+ typeName: ZodFirstPartyTypeKind.ZodArray,
+ ...processCreateParams(params)
+ });
+};
+function deepPartialify(schema) {
+ if (schema instanceof ZodObject) {
+ const newShape = {};
+ for (const key in schema.shape) {
+ const fieldSchema = schema.shape[key];
+ newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
}
- }
- /**
- * @see {@link https://hono.dev/docs/api/context#res}
- * The Response object for the current request.
- */
- get res() {
- return this.#res ||= createResponseInstance(null, {
- headers: this.#preparedHeaders ??= new Headers()
+ return new ZodObject({
+ ...schema._def,
+ shape: () => newShape
});
+ } else if (schema instanceof ZodArray) {
+ return new ZodArray({
+ ...schema._def,
+ type: deepPartialify(schema.element)
+ });
+ } else if (schema instanceof ZodOptional) {
+ return ZodOptional.create(deepPartialify(schema.unwrap()));
+ } else if (schema instanceof ZodNullable) {
+ return ZodNullable.create(deepPartialify(schema.unwrap()));
+ } else if (schema instanceof ZodTuple) {
+ return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
+ } else {
+ return schema;
}
- /**
- * Sets the Response object for the current request.
- *
- * @param _res - The Response object to set.
- */
- set res(_res) {
- if (this.#res && _res) {
- _res = createResponseInstance(_res.body, _res);
- for (const [k, v] of this.#res.headers.entries()) {
- if (k === "content-type") {
- continue;
- }
- if (k === "set-cookie") {
- const cookies = this.#res.headers.getSetCookie();
- _res.headers.delete("set-cookie");
- for (const cookie of cookies) {
- _res.headers.append("set-cookie", cookie);
- }
- } else {
- _res.headers.set(k, v);
- }
- }
- }
- this.#res = _res;
- this.finalized = true;
+}
+var ZodObject = class _ZodObject extends ZodType {
+ constructor() {
+ super(...arguments);
+ this._cached = null;
+ this.nonstrict = this.passthrough;
+ this.augment = this.extend;
}
- /**
- * `.render()` can create a response within a layout.
- *
- * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
- *
- * @example
- * ```ts
- * app.get('/', (c) => {
- * return c.render('Hello!')
- * })
- * ```
- */
- render = (...args) => {
- this.#renderer ??= (content) => this.html(content);
- return this.#renderer(...args);
- };
- /**
- * Sets the layout for the response.
- *
- * @param layout - The layout to set.
- * @returns The layout function.
- */
- setLayout = (layout) => this.#layout = layout;
- /**
- * Gets the current layout for the response.
- *
- * @returns The current layout function.
- */
- getLayout = () => this.#layout;
- /**
- * `.setRenderer()` can set the layout in the custom middleware.
- *
- * @see {@link https://hono.dev/docs/api/context#render-setrenderer}
- *
- * @example
- * ```tsx
- * app.use('*', async (c, next) => {
- * c.setRenderer((content) => {
- * return c.html(
- *
- *
- * {content}
- *
- *
- * )
- * })
- * await next()
- * })
- * ```
- */
- setRenderer = (renderer) => {
- this.#renderer = renderer;
- };
- /**
- * `.header()` can set headers.
- *
- * @see {@link https://hono.dev/docs/api/context#header}
- *
- * @example
- * ```ts
- * app.get('/welcome', (c) => {
- * // Set headers
- * c.header('X-Message', 'Hello!')
- * c.header('Content-Type', 'text/plain')
- *
- * return c.body('Thank you for coming')
- * })
- * ```
- */
- header = (name, value, options) => {
- if (this.finalized) {
- this.#res = createResponseInstance(this.#res.body, this.#res);
- }
- const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();
- if (value === void 0) {
- headers.delete(name);
- } else if (options?.append) {
- headers.append(name, value);
- } else {
- headers.set(name, value);
- }
- };
- status = (status) => {
- this.#status = status;
- };
- /**
- * `.set()` can set the value specified by the key.
- *
- * @see {@link https://hono.dev/docs/api/context#set-get}
- *
- * @example
- * ```ts
- * app.use('*', async (c, next) => {
- * c.set('message', 'Hono is hot!!')
- * await next()
- * })
- * ```
- */
- set = (key, value) => {
- this.#var ??= /* @__PURE__ */ new Map();
- this.#var.set(key, value);
- };
- /**
- * `.get()` can use the value specified by the key.
- *
- * @see {@link https://hono.dev/docs/api/context#set-get}
- *
- * @example
- * ```ts
- * app.get('/', (c) => {
- * const message = c.get('message')
- * return c.text(`The message is "${message}"`)
- * })
- * ```
- */
- get = (key) => {
- return this.#var ? this.#var.get(key) : void 0;
- };
- /**
- * `.var` can access the value of a variable.
- *
- * @see {@link https://hono.dev/docs/api/context#var}
- *
- * @example
- * ```ts
- * const result = c.var.client.oneMethod()
- * ```
- */
- // c.var.propName is a read-only
- get var() {
- if (!this.#var) {
- return {};
+ _getCached() {
+ if (this._cached !== null)
+ return this._cached;
+ const shape = this._def.shape();
+ const keys = util.objectKeys(shape);
+ this._cached = { shape, keys };
+ return this._cached;
+ }
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.object) {
+ const ctx2 = this._getOrReturnCtx(input);
+ addIssueToContext(ctx2, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.object,
+ received: ctx2.parsedType
+ });
+ return INVALID;
}
- return Object.fromEntries(this.#var);
- }
- #newResponse(data, arg, headers) {
- const responseHeaders2 = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();
- if (typeof arg === "object" && "headers" in arg) {
- const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);
- for (const [key, value] of argHeaders) {
- if (key.toLowerCase() === "set-cookie") {
- responseHeaders2.append(key, value);
- } else {
- responseHeaders2.set(key, value);
+ const { status, ctx } = this._processInputParams(input);
+ const { shape, keys: shapeKeys } = this._getCached();
+ const extraKeys = [];
+ if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
+ for (const key in ctx.data) {
+ if (!shapeKeys.includes(key)) {
+ extraKeys.push(key);
}
}
}
- if (headers) {
- for (const [k, v] of Object.entries(headers)) {
- if (typeof v === "string") {
- responseHeaders2.set(k, v);
- } else {
- responseHeaders2.delete(k);
- for (const v2 of v) {
- responseHeaders2.append(k, v2);
- }
- }
- }
+ const pairs = [];
+ for (const key of shapeKeys) {
+ const keyValidator = shape[key];
+ const value = ctx.data[key];
+ pairs.push({
+ key: { status: "valid", value: key },
+ value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
+ alwaysSet: key in ctx.data
+ });
}
- const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
- return createResponseInstance(data, { status, headers: responseHeaders2 });
- }
- newResponse = (...args) => this.#newResponse(...args);
- /**
- * `.body()` can return the HTTP response.
- * You can set headers with `.header()` and set HTTP status code with `.status`.
- * This can also be set in `.text()`, `.json()` and so on.
- *
- * @see {@link https://hono.dev/docs/api/context#body}
- *
- * @example
- * ```ts
- * app.get('/welcome', (c) => {
- * // Set headers
- * c.header('X-Message', 'Hello!')
- * c.header('Content-Type', 'text/plain')
- * // Set HTTP status code
- * c.status(201)
- *
- * // Return the response body
- * return c.body('Thank you for coming')
- * })
- * ```
- */
- body = (data, arg, headers) => this.#newResponse(data, arg, headers);
- /**
- * `.text()` can render text as `Content-Type:text/plain`.
- *
- * @see {@link https://hono.dev/docs/api/context#text}
- *
- * @example
- * ```ts
- * app.get('/say', (c) => {
- * return c.text('Hello!')
- * })
- * ```
- */
- text = (text, arg, headers) => {
- return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
- text,
- arg,
- setDefaultContentType(TEXT_PLAIN, headers)
- );
- };
- /**
- * `.json()` can render JSON as `Content-Type:application/json`.
- *
- * @see {@link https://hono.dev/docs/api/context#json}
- *
- * @example
- * ```ts
- * app.get('/api', (c) => {
- * return c.json({ message: 'Hello!' })
- * })
- * ```
- */
- json = (object2, arg, headers) => {
- return this.#newResponse(
- JSON.stringify(object2),
- arg,
- setDefaultContentType("application/json", headers)
- );
- };
- html = (html, arg, headers) => {
- const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers));
- return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
- };
- /**
- * `.redirect()` can Redirect, default status code is 302.
- *
- * @see {@link https://hono.dev/docs/api/context#redirect}
- *
- * @example
- * ```ts
- * app.get('/redirect', (c) => {
- * return c.redirect('/')
- * })
- * app.get('/redirect-permanently', (c) => {
- * return c.redirect('/', 301)
- * })
- * ```
- */
- redirect = (location, status) => {
- const locationString = String(location);
- this.header(
- "Location",
- // Multibyes should be encoded
- // eslint-disable-next-line no-control-regex
- !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
- );
- return this.newResponse(null, status ?? 302);
- };
- /**
- * `.notFound()` can return the Not Found Response.
- *
- * @see {@link https://hono.dev/docs/api/context#notfound}
- *
- * @example
- * ```ts
- * app.get('/notfound', (c) => {
- * return c.notFound()
- * })
- * ```
- */
- notFound = () => {
- this.#notFoundHandler ??= () => createResponseInstance();
- return this.#notFoundHandler(this);
- };
-};
-
-// node_modules/hono/dist/router.js
-var METHOD_NAME_ALL = "ALL";
-var METHOD_NAME_ALL_LOWERCASE = "all";
-var METHODS = ["get", "post", "put", "delete", "options", "patch"];
-var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
-var UnsupportedPathError = class extends Error {
-};
-
-// node_modules/hono/dist/utils/constants.js
-var COMPOSED_HANDLER = "__COMPOSED_HANDLER";
-
-// node_modules/hono/dist/hono-base.js
-var notFoundHandler = (c) => {
- return c.text("404 Not Found", 404);
-};
-var errorHandler = (err, c) => {
- if ("getResponse" in err) {
- const res = err.getResponse();
- return c.newResponse(res.body, res);
- }
- console.error(err);
- return c.text("Internal Server Error", 500);
-};
-var Hono = class _Hono {
- get;
- post;
- put;
- delete;
- options;
- patch;
- all;
- on;
- use;
- /*
- This class is like an abstract class and does not have a router.
- To use it, inherit the class and implement router in the constructor.
- */
- router;
- getPath;
- // Cannot use `#` because it requires visibility at JavaScript runtime.
- _basePath = "/";
- #path = "/";
- routes = [];
- constructor(options = {}) {
- const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
- allMethods.forEach((method) => {
- this[method] = (args1, ...args) => {
- if (typeof args1 === "string") {
- this.#path = args1;
- } else {
- this.#addRoute(method, this.#path, args1);
+ if (this._def.catchall instanceof ZodNever) {
+ const unknownKeys = this._def.unknownKeys;
+ if (unknownKeys === "passthrough") {
+ for (const key of extraKeys) {
+ pairs.push({
+ key: { status: "valid", value: key },
+ value: { status: "valid", value: ctx.data[key] }
+ });
}
- args.forEach((handler) => {
- this.#addRoute(method, this.#path, handler);
+ } else if (unknownKeys === "strict") {
+ if (extraKeys.length > 0) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.unrecognized_keys,
+ keys: extraKeys
+ });
+ status.dirty();
+ }
+ } else if (unknownKeys === "strip") {
+ } else {
+ throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
+ }
+ } else {
+ const catchall = this._def.catchall;
+ for (const key of extraKeys) {
+ const value = ctx.data[key];
+ pairs.push({
+ key: { status: "valid", value: key },
+ value: catchall._parse(
+ new ParseInputLazyPath(ctx, value, ctx.path, key)
+ //, ctx.child(key), value, getParsedType(value)
+ ),
+ alwaysSet: key in ctx.data
});
- return this;
- };
- });
- this.on = (method, path5, ...handlers) => {
- for (const p of [path5].flat()) {
- this.#path = p;
- for (const m of [method].flat()) {
- handlers.map((handler) => {
- this.#addRoute(m.toUpperCase(), this.#path, handler);
+ }
+ }
+ if (ctx.common.async) {
+ return Promise.resolve().then(async () => {
+ const syncPairs = [];
+ for (const pair of pairs) {
+ const key = await pair.key;
+ const value = await pair.value;
+ syncPairs.push({
+ key,
+ value,
+ alwaysSet: pair.alwaysSet
});
}
- }
- return this;
- };
- this.use = (arg1, ...handlers) => {
- if (typeof arg1 === "string") {
- this.#path = arg1;
- } else {
- this.#path = "*";
- handlers.unshift(arg1);
- }
- handlers.forEach((handler) => {
- this.#addRoute(METHOD_NAME_ALL, this.#path, handler);
+ return syncPairs;
+ }).then((syncPairs) => {
+ return ParseStatus.mergeObjectSync(status, syncPairs);
});
- return this;
- };
- const { strict, ...optionsWithoutStrict } = options;
- Object.assign(this, optionsWithoutStrict);
- this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
+ } else {
+ return ParseStatus.mergeObjectSync(status, pairs);
+ }
}
- #clone() {
- const clone = new _Hono({
- router: this.router,
- getPath: this.getPath
+ get shape() {
+ return this._def.shape();
+ }
+ strict(message) {
+ errorUtil.errToObj;
+ return new _ZodObject({
+ ...this._def,
+ unknownKeys: "strict",
+ ...message !== void 0 ? {
+ errorMap: (issue, ctx) => {
+ const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
+ if (issue.code === "unrecognized_keys")
+ return {
+ message: errorUtil.errToObj(message).message ?? defaultError
+ };
+ return {
+ message: defaultError
+ };
+ }
+ } : {}
});
- clone.errorHandler = this.errorHandler;
- clone.#notFoundHandler = this.#notFoundHandler;
- clone.routes = this.routes;
- return clone;
}
- #notFoundHandler = notFoundHandler;
- // Cannot use `#` because it requires visibility at JavaScript runtime.
- errorHandler = errorHandler;
- /**
- * `.route()` allows grouping other Hono instance in routes.
- *
- * @see {@link https://hono.dev/docs/api/routing#grouping}
- *
- * @param {string} path - base Path
- * @param {Hono} app - other Hono instance
- * @returns {Hono} routed Hono instance
- *
- * @example
- * ```ts
- * const app = new Hono()
- * const app2 = new Hono()
- *
- * app2.get("/user", (c) => c.text("user"))
- * app.route("/api", app2) // GET /api/user
- * ```
- */
- route(path5, app) {
- const subApp = this.basePath(path5);
- app.routes.map((r) => {
- let handler;
- if (app.errorHandler === errorHandler) {
- handler = r.handler;
- } else {
- handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
- handler[COMPOSED_HANDLER] = r.handler;
- }
- subApp.#addRoute(r.method, r.path, handler, r.basePath);
+ strip() {
+ return new _ZodObject({
+ ...this._def,
+ unknownKeys: "strip"
});
- return this;
}
- /**
- * `.basePath()` allows base paths to be specified.
- *
- * @see {@link https://hono.dev/docs/api/routing#base-path}
- *
- * @param {string} path - base Path
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * const api = new Hono().basePath('/api')
- * ```
- */
- basePath(path5) {
- const subApp = this.#clone();
- subApp._basePath = mergePath(this._basePath, path5);
- return subApp;
+ passthrough() {
+ return new _ZodObject({
+ ...this._def,
+ unknownKeys: "passthrough"
+ });
+ }
+ // const AugmentFactory =
+ // (def: Def) =>
+ // (
+ // augmentation: Augmentation
+ // ): ZodObject<
+ // extendShape, Augmentation>,
+ // Def["unknownKeys"],
+ // Def["catchall"]
+ // > => {
+ // return new ZodObject({
+ // ...def,
+ // shape: () => ({
+ // ...def.shape(),
+ // ...augmentation,
+ // }),
+ // }) as any;
+ // };
+ extend(augmentation) {
+ return new _ZodObject({
+ ...this._def,
+ shape: () => ({
+ ...this._def.shape(),
+ ...augmentation
+ })
+ });
}
/**
- * `.onError()` handles an error and returns a customized Response.
- *
- * @see {@link https://hono.dev/docs/api/hono#error-handling}
- *
- * @param {ErrorHandler} handler - request Handler for error
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * app.onError((err, c) => {
- * console.error(`${err}`)
- * return c.text('Custom Error Message', 500)
- * })
- * ```
- */
- onError = (handler) => {
- this.errorHandler = handler;
- return this;
- };
- /**
- * `.notFound()` allows you to customize a Not Found Response.
- *
- * @see {@link https://hono.dev/docs/api/hono#not-found}
- *
- * @param {NotFoundHandler} handler - request handler for not-found
- * @returns {Hono} changed Hono instance
- *
- * @example
- * ```ts
- * app.notFound((c) => {
- * return c.text('Custom 404 Message', 404)
- * })
- * ```
- */
- notFound = (handler) => {
- this.#notFoundHandler = handler;
- return this;
- };
- /**
- * `.mount()` allows you to mount applications built with other frameworks into your Hono application.
- *
- * @see {@link https://hono.dev/docs/api/hono#mount}
- *
- * @param {string} path - base Path
- * @param {Function} applicationHandler - other Request Handler
- * @param {MountOptions} [options] - options of `.mount()`
- * @returns {Hono} mounted Hono instance
- *
- * @example
- * ```ts
- * import { Router as IttyRouter } from 'itty-router'
- * import { Hono } from 'hono'
- * // Create itty-router application
- * const ittyRouter = IttyRouter()
- * // GET /itty-router/hello
- * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
- *
- * const app = new Hono()
- * app.mount('/itty-router', ittyRouter.handle)
- * ```
- *
- * @example
- * ```ts
- * const app = new Hono()
- * // Send the request to another application without modification.
- * app.mount('/app', anotherApp, {
- * replaceRequest: (req) => req,
- * })
- * ```
+ * Prior to zod@1.0.12 there was a bug in the
+ * inferred type of merged objects. Please
+ * upgrade if you are experiencing issues.
*/
- mount(path5, applicationHandler, options) {
- let replaceRequest;
- let optionHandler;
- if (options) {
- if (typeof options === "function") {
- optionHandler = options;
- } else {
- optionHandler = options.optionHandler;
- if (options.replaceRequest === false) {
- replaceRequest = (request) => request;
- } else {
- replaceRequest = options.replaceRequest;
- }
+ merge(merging) {
+ const merged = new _ZodObject({
+ unknownKeys: merging._def.unknownKeys,
+ catchall: merging._def.catchall,
+ shape: () => ({
+ ...this._def.shape(),
+ ...merging._def.shape()
+ }),
+ typeName: ZodFirstPartyTypeKind.ZodObject
+ });
+ return merged;
+ }
+ // merge<
+ // Incoming extends AnyZodObject,
+ // Augmentation extends Incoming["shape"],
+ // NewOutput extends {
+ // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation
+ // ? Augmentation[k]["_output"]
+ // : k extends keyof Output
+ // ? Output[k]
+ // : never;
+ // },
+ // NewInput extends {
+ // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation
+ // ? Augmentation[k]["_input"]
+ // : k extends keyof Input
+ // ? Input[k]
+ // : never;
+ // }
+ // >(
+ // merging: Incoming
+ // ): ZodObject<
+ // extendShape>,
+ // Incoming["_def"]["unknownKeys"],
+ // Incoming["_def"]["catchall"],
+ // NewOutput,
+ // NewInput
+ // > {
+ // const merged: any = new ZodObject({
+ // unknownKeys: merging._def.unknownKeys,
+ // catchall: merging._def.catchall,
+ // shape: () =>
+ // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
+ // typeName: ZodFirstPartyTypeKind.ZodObject,
+ // }) as any;
+ // return merged;
+ // }
+ setKey(key, schema) {
+ return this.augment({ [key]: schema });
+ }
+ // merge(
+ // merging: Incoming
+ // ): //ZodObject = (merging) => {
+ // ZodObject<
+ // extendShape>,
+ // Incoming["_def"]["unknownKeys"],
+ // Incoming["_def"]["catchall"]
+ // > {
+ // // const mergedShape = objectUtil.mergeShapes(
+ // // this._def.shape(),
+ // // merging._def.shape()
+ // // );
+ // const merged: any = new ZodObject({
+ // unknownKeys: merging._def.unknownKeys,
+ // catchall: merging._def.catchall,
+ // shape: () =>
+ // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
+ // typeName: ZodFirstPartyTypeKind.ZodObject,
+ // }) as any;
+ // return merged;
+ // }
+ catchall(index) {
+ return new _ZodObject({
+ ...this._def,
+ catchall: index
+ });
+ }
+ pick(mask) {
+ const shape = {};
+ for (const key of util.objectKeys(mask)) {
+ if (mask[key] && this.shape[key]) {
+ shape[key] = this.shape[key];
}
}
- const getOptions = optionHandler ? (c) => {
- const options2 = optionHandler(c);
- return Array.isArray(options2) ? options2 : [options2];
- } : (c) => {
- let executionContext = void 0;
- try {
- executionContext = c.executionCtx;
- } catch {
- }
- return [c.env, executionContext];
- };
- replaceRequest ||= (() => {
- const mergedPath = mergePath(this._basePath, path5);
- const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
- return (request) => {
- const url = new URL(request.url);
- url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
- return new Request(url, request);
- };
- })();
- const handler = async (c, next) => {
- const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
- if (res) {
- return res;
+ return new _ZodObject({
+ ...this._def,
+ shape: () => shape
+ });
+ }
+ omit(mask) {
+ const shape = {};
+ for (const key of util.objectKeys(this.shape)) {
+ if (!mask[key]) {
+ shape[key] = this.shape[key];
}
- await next();
- };
- this.#addRoute(METHOD_NAME_ALL, mergePath(path5, "*"), handler);
- return this;
+ }
+ return new _ZodObject({
+ ...this._def,
+ shape: () => shape
+ });
}
- #addRoute(method, path5, handler, baseRoutePath) {
- method = method.toUpperCase();
- path5 = mergePath(this._basePath, path5);
- const r = {
- basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
- path: path5,
- method,
- handler
- };
- this.router.add(method, path5, [handler, r]);
- this.routes.push(r);
+ /**
+ * @deprecated
+ */
+ deepPartial() {
+ return deepPartialify(this);
}
- #handleError(err, c) {
- if (err instanceof Error) {
- return this.errorHandler(err, c);
+ partial(mask) {
+ const newShape = {};
+ for (const key of util.objectKeys(this.shape)) {
+ const fieldSchema = this.shape[key];
+ if (mask && !mask[key]) {
+ newShape[key] = fieldSchema;
+ } else {
+ newShape[key] = fieldSchema.optional();
+ }
}
- throw err;
+ return new _ZodObject({
+ ...this._def,
+ shape: () => newShape
+ });
}
- #dispatch(request, executionCtx, env, method) {
- if (method === "HEAD") {
- return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
+ required(mask) {
+ const newShape = {};
+ for (const key of util.objectKeys(this.shape)) {
+ if (mask && !mask[key]) {
+ newShape[key] = this.shape[key];
+ } else {
+ const fieldSchema = this.shape[key];
+ let newField = fieldSchema;
+ while (newField instanceof ZodOptional) {
+ newField = newField._def.innerType;
+ }
+ newShape[key] = newField;
+ }
}
- const path5 = this.getPath(request, { env });
- const matchResult = this.router.match(method, path5);
- const c = new Context(request, {
- path: path5,
- matchResult,
- env,
- executionCtx,
- notFoundHandler: this.#notFoundHandler
+ return new _ZodObject({
+ ...this._def,
+ shape: () => newShape
});
- if (matchResult[0].length === 1) {
- let res;
- try {
- res = matchResult[0][0][0][0](c, async () => {
- c.res = await this.#notFoundHandler(c);
- });
- } catch (err) {
- return this.#handleError(err, c);
+ }
+ keyof() {
+ return createZodEnum(util.objectKeys(this.shape));
+ }
+};
+ZodObject.create = (shape, params) => {
+ return new ZodObject({
+ shape: () => shape,
+ unknownKeys: "strip",
+ catchall: ZodNever.create(),
+ typeName: ZodFirstPartyTypeKind.ZodObject,
+ ...processCreateParams(params)
+ });
+};
+ZodObject.strictCreate = (shape, params) => {
+ return new ZodObject({
+ shape: () => shape,
+ unknownKeys: "strict",
+ catchall: ZodNever.create(),
+ typeName: ZodFirstPartyTypeKind.ZodObject,
+ ...processCreateParams(params)
+ });
+};
+ZodObject.lazycreate = (shape, params) => {
+ return new ZodObject({
+ shape,
+ unknownKeys: "strip",
+ catchall: ZodNever.create(),
+ typeName: ZodFirstPartyTypeKind.ZodObject,
+ ...processCreateParams(params)
+ });
+};
+var ZodUnion = class extends ZodType {
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ const options = this._def.options;
+ function handleResults(results) {
+ for (const result of results) {
+ if (result.result.status === "valid") {
+ return result.result;
+ }
}
- return res instanceof Promise ? res.then(
- (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))
- ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
+ for (const result of results) {
+ if (result.result.status === "dirty") {
+ ctx.common.issues.push(...result.ctx.common.issues);
+ return result.result;
+ }
+ }
+ const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_union,
+ unionErrors
+ });
+ return INVALID;
}
- const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
- return (async () => {
- try {
- const context = await composed(c);
- if (!context.finalized) {
- throw new Error(
- "Context is not finalized. Did you forget to return a Response object or `await next()`?"
- );
+ if (ctx.common.async) {
+ return Promise.all(options.map(async (option) => {
+ const childCtx = {
+ ...ctx,
+ common: {
+ ...ctx.common,
+ issues: []
+ },
+ parent: null
+ };
+ return {
+ result: await option._parseAsync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: childCtx
+ }),
+ ctx: childCtx
+ };
+ })).then(handleResults);
+ } else {
+ let dirty = void 0;
+ const issues = [];
+ for (const option of options) {
+ const childCtx = {
+ ...ctx,
+ common: {
+ ...ctx.common,
+ issues: []
+ },
+ parent: null
+ };
+ const result = option._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: childCtx
+ });
+ if (result.status === "valid") {
+ return result;
+ } else if (result.status === "dirty" && !dirty) {
+ dirty = { result, ctx: childCtx };
+ }
+ if (childCtx.common.issues.length) {
+ issues.push(childCtx.common.issues);
}
- return context.res;
- } catch (err) {
- return this.#handleError(err, c);
}
- })();
- }
- /**
- * `.fetch()` will be entry point of your app.
- *
- * @see {@link https://hono.dev/docs/api/hono#fetch}
- *
- * @param {Request} request - request Object of request
- * @param {Env} Env - env Object
- * @param {ExecutionContext} - context of execution
- * @returns {Response | Promise} response of request
- *
- */
- fetch = (request, ...rest) => {
- return this.#dispatch(request, rest[1], rest[0], request.method);
- };
- /**
- * `.request()` is a useful method for testing.
- * You can pass a URL or pathname to send a GET request.
- * app will return a Response object.
- * ```ts
- * test('GET /hello is ok', async () => {
- * const res = await app.request('/hello')
- * expect(res.status).toBe(200)
- * })
- * ```
- * @see https://hono.dev/docs/api/hono#request
- */
- request = (input, requestInit, Env, executionCtx) => {
- if (input instanceof Request) {
- return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
+ if (dirty) {
+ ctx.common.issues.push(...dirty.ctx.common.issues);
+ return dirty.result;
+ }
+ const unionErrors = issues.map((issues2) => new ZodError(issues2));
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_union,
+ unionErrors
+ });
+ return INVALID;
}
- input = input.toString();
- return this.fetch(
- new Request(
- /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`,
- requestInit
- ),
- Env,
- executionCtx
- );
- };
- /**
- * `.fire()` automatically adds a global fetch event listener.
- * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
- * @deprecated
- * Use `fire` from `hono/service-worker` instead.
- * ```ts
- * import { Hono } from 'hono'
- * import { fire } from 'hono/service-worker'
- *
- * const app = new Hono()
- * // ...
- * fire(app)
- * ```
- * @see https://hono.dev/docs/api/hono#fire
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
- * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
- */
- fire = () => {
- addEventListener("fetch", (event) => {
- event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
- });
- };
+ }
+ get options() {
+ return this._def.options;
+ }
};
-
-// node_modules/hono/dist/router/reg-exp-router/matcher.js
-var emptyParam = [];
-function match(method, path5) {
- const matchers = this.buildAllMatchers();
- const match2 = ((method2, path22) => {
- const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
- const staticMatch = matcher[2][path22];
- if (staticMatch) {
- return staticMatch;
+ZodUnion.create = (types, params) => {
+ return new ZodUnion({
+ options: types,
+ typeName: ZodFirstPartyTypeKind.ZodUnion,
+ ...processCreateParams(params)
+ });
+};
+var getDiscriminator = (type) => {
+ if (type instanceof ZodLazy) {
+ return getDiscriminator(type.schema);
+ } else if (type instanceof ZodEffects) {
+ return getDiscriminator(type.innerType());
+ } else if (type instanceof ZodLiteral) {
+ return [type.value];
+ } else if (type instanceof ZodEnum) {
+ return type.options;
+ } else if (type instanceof ZodNativeEnum) {
+ return util.objectValues(type.enum);
+ } else if (type instanceof ZodDefault) {
+ return getDiscriminator(type._def.innerType);
+ } else if (type instanceof ZodUndefined) {
+ return [void 0];
+ } else if (type instanceof ZodNull) {
+ return [null];
+ } else if (type instanceof ZodOptional) {
+ return [void 0, ...getDiscriminator(type.unwrap())];
+ } else if (type instanceof ZodNullable) {
+ return [null, ...getDiscriminator(type.unwrap())];
+ } else if (type instanceof ZodBranded) {
+ return getDiscriminator(type.unwrap());
+ } else if (type instanceof ZodReadonly) {
+ return getDiscriminator(type.unwrap());
+ } else if (type instanceof ZodCatch) {
+ return getDiscriminator(type._def.innerType);
+ } else {
+ return [];
+ }
+};
+var ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType {
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.object) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.object,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- const match3 = path22.match(matcher[0]);
- if (!match3) {
- return [[], emptyParam];
+ const discriminator = this.discriminator;
+ const discriminatorValue = ctx.data[discriminator];
+ const option = this.optionsMap.get(discriminatorValue);
+ if (!option) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_union_discriminator,
+ options: Array.from(this.optionsMap.keys()),
+ path: [discriminator]
+ });
+ return INVALID;
+ }
+ if (ctx.common.async) {
+ return option._parseAsync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
+ } else {
+ return option._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
}
- const index = match3.indexOf("", 1);
- return [matcher[1][index], match3];
- });
- this.match = match2;
- return match2(method, path5);
-}
-
-// node_modules/hono/dist/router/reg-exp-router/node.js
-var LABEL_REG_EXP_STR = "[^/]+";
-var ONLY_WILDCARD_REG_EXP_STR = ".*";
-var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
-var PATH_ERROR = /* @__PURE__ */ Symbol();
-var regExpMetaChars = new Set(".\\+*[^]$()");
-function compareKey(a, b) {
- if (a.length === 1) {
- return b.length === 1 ? a < b ? -1 : 1 : -1;
}
- if (b.length === 1) {
- return 1;
+ get discriminator() {
+ return this._def.discriminator;
}
- if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
- return 1;
- } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
- return -1;
+ get options() {
+ return this._def.options;
}
- if (a === LABEL_REG_EXP_STR) {
- return 1;
- } else if (b === LABEL_REG_EXP_STR) {
- return -1;
+ get optionsMap() {
+ return this._def.optionsMap;
}
- return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;
-}
-var Node = class _Node {
- #index;
- #varIndex;
- #children = /* @__PURE__ */ Object.create(null);
- insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
- if (tokens.length === 0) {
- if (this.#index !== void 0) {
- throw PATH_ERROR;
- }
- if (pathErrorCheckOnly) {
- return;
- }
- this.#index = index;
- return;
- }
- const [token, ...restTokens] = tokens;
- const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
- let node;
- if (pattern) {
- const name = pattern[1];
- let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
- if (name && pattern[2]) {
- if (regexpStr === ".*") {
- throw PATH_ERROR;
- }
- regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
- if (/\((?!\?:)/.test(regexpStr)) {
- throw PATH_ERROR;
- }
- }
- node = this.#children[regexpStr];
- if (!node) {
- if (Object.keys(this.#children).some(
- (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
- )) {
- throw PATH_ERROR;
- }
- if (pathErrorCheckOnly) {
- return;
- }
- node = this.#children[regexpStr] = new _Node();
- if (name !== "") {
- node.#varIndex = context.varIndex++;
- }
- }
- if (!pathErrorCheckOnly && name !== "") {
- paramMap.push([name, node.#varIndex]);
+ /**
+ * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.
+ * However, it only allows a union of objects, all of which need to share a discriminator property. This property must
+ * have a different value for each object in the union.
+ * @param discriminator the name of the discriminator property
+ * @param types an array of object schemas
+ * @param params
+ */
+ static create(discriminator, options, params) {
+ const optionsMap = /* @__PURE__ */ new Map();
+ for (const type of options) {
+ const discriminatorValues = getDiscriminator(type.shape[discriminator]);
+ if (!discriminatorValues.length) {
+ throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
}
- } else {
- node = this.#children[token];
- if (!node) {
- if (Object.keys(this.#children).some(
- (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR
- )) {
- throw PATH_ERROR;
- }
- if (pathErrorCheckOnly) {
- return;
+ for (const value of discriminatorValues) {
+ if (optionsMap.has(value)) {
+ throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
}
- node = this.#children[token] = new _Node();
+ optionsMap.set(value, type);
}
}
- node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
- }
- buildRegExpStr() {
- const childKeys = Object.keys(this.#children).sort(compareKey);
- const strList = childKeys.map((k) => {
- const c = this.#children[k];
- return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr();
+ return new _ZodDiscriminatedUnion({
+ typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
+ discriminator,
+ options,
+ optionsMap,
+ ...processCreateParams(params)
});
- if (typeof this.#index === "number") {
- strList.unshift(`#${this.#index}`);
- }
- if (strList.length === 0) {
- return "";
- }
- if (strList.length === 1) {
- return strList[0];
- }
- return "(?:" + strList.join("|") + ")";
}
};
-
-// node_modules/hono/dist/router/reg-exp-router/trie.js
-var Trie = class {
- #context = { varIndex: 0 };
- #root = new Node();
- insert(path5, index, pathErrorCheckOnly) {
- const paramAssoc = [];
- const groups = [];
- for (let i = 0; ; ) {
- let replaced = false;
- path5 = path5.replace(/\{[^}]+\}/g, (m) => {
- const mark = `@\\${i}`;
- groups[i] = [mark, m];
- i++;
- replaced = true;
- return mark;
- });
- if (!replaced) {
- break;
+function mergeValues(a, b) {
+ const aType = getParsedType(a);
+ const bType = getParsedType(b);
+ if (a === b) {
+ return { valid: true, data: a };
+ } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
+ const bKeys = util.objectKeys(b);
+ const sharedKeys = util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
+ const newObj = { ...a, ...b };
+ for (const key of sharedKeys) {
+ const sharedValue = mergeValues(a[key], b[key]);
+ if (!sharedValue.valid) {
+ return { valid: false };
}
+ newObj[key] = sharedValue.data;
}
- const tokens = path5.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
- for (let i = groups.length - 1; i >= 0; i--) {
- const [mark] = groups[i];
- for (let j = tokens.length - 1; j >= 0; j--) {
- if (tokens[j].indexOf(mark) !== -1) {
- tokens[j] = tokens[j].replace(mark, groups[i][1]);
- break;
- }
+ return { valid: true, data: newObj };
+ } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
+ if (a.length !== b.length) {
+ return { valid: false };
+ }
+ const newArray = [];
+ for (let index = 0; index < a.length; index++) {
+ const itemA = a[index];
+ const itemB = b[index];
+ const sharedValue = mergeValues(itemA, itemB);
+ if (!sharedValue.valid) {
+ return { valid: false };
}
+ newArray.push(sharedValue.data);
}
- this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
- return paramAssoc;
+ return { valid: true, data: newArray };
+ } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {
+ return { valid: true, data: a };
+ } else {
+ return { valid: false };
}
- buildRegExp() {
- let regexp = this.#root.buildRegExpStr();
- if (regexp === "") {
- return [/^$/, [], []];
- }
- let captureIndex = 0;
- const indexReplacementMap = [];
- const paramReplacementMap = [];
- regexp = regexp.replace(/#(\d+)|@(\d+)|\.\*\$/g, (_, handlerIndex, paramIndex) => {
- if (handlerIndex !== void 0) {
- indexReplacementMap[++captureIndex] = Number(handlerIndex);
- return "$()";
+}
+var ZodIntersection = class extends ZodType {
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ const handleParsed = (parsedLeft, parsedRight) => {
+ if (isAborted(parsedLeft) || isAborted(parsedRight)) {
+ return INVALID;
}
- if (paramIndex !== void 0) {
- paramReplacementMap[Number(paramIndex)] = ++captureIndex;
- return "";
+ const merged = mergeValues(parsedLeft.value, parsedRight.value);
+ if (!merged.valid) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_intersection_types
+ });
+ return INVALID;
}
- return "";
- });
- return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
+ if (isDirty(parsedLeft) || isDirty(parsedRight)) {
+ status.dirty();
+ }
+ return { status: status.value, value: merged.data };
+ };
+ if (ctx.common.async) {
+ return Promise.all([
+ this._def.left._parseAsync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ }),
+ this._def.right._parseAsync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ })
+ ]).then(([left, right]) => handleParsed(left, right));
+ } else {
+ return handleParsed(this._def.left._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ }), this._def.right._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ }));
+ }
}
};
-
-// node_modules/hono/dist/router/reg-exp-router/router.js
-var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
-var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
-function buildWildcardRegExp(path5) {
- return wildcardRegExpCache[path5] ??= new RegExp(
- path5 === "*" ? "" : `^${path5.replace(
- /\/\*$|([.\\+*[^\]$()])/g,
- (_, metaChar) => metaChar ? `\\${metaChar}` : "(?:|/.*)"
- )}$`
- );
-}
-function clearWildcardRegExpCache() {
- wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
-}
-function buildMatcherFromPreprocessedRoutes(routes) {
- const trie = new Trie();
- const handlerData = [];
- if (routes.length === 0) {
- return nullMatcher;
- }
- const routesWithStaticPathFlag = routes.map(
- (route) => [!/\*|\/:/.test(route[0]), ...route]
- ).sort(
- ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
- );
- const staticMap = /* @__PURE__ */ Object.create(null);
- for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
- const [pathErrorCheckOnly, path5, handlers] = routesWithStaticPathFlag[i];
- if (pathErrorCheckOnly) {
- staticMap[path5] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
- } else {
- j++;
+ZodIntersection.create = (left, right, params) => {
+ return new ZodIntersection({
+ left,
+ right,
+ typeName: ZodFirstPartyTypeKind.ZodIntersection,
+ ...processCreateParams(params)
+ });
+};
+var ZodTuple = class _ZodTuple extends ZodType {
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.array) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.array,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- let paramAssoc;
- try {
- paramAssoc = trie.insert(path5, j, pathErrorCheckOnly);
- } catch (e) {
- throw e === PATH_ERROR ? new UnsupportedPathError(path5) : e;
+ if (ctx.data.length < this._def.items.length) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: this._def.items.length,
+ inclusive: true,
+ exact: false,
+ type: "array"
+ });
+ return INVALID;
}
- if (pathErrorCheckOnly) {
- continue;
+ const rest = this._def.rest;
+ if (!rest && ctx.data.length > this._def.items.length) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: this._def.items.length,
+ inclusive: true,
+ exact: false,
+ type: "array"
+ });
+ status.dirty();
+ }
+ const items = [...ctx.data].map((item, itemIndex) => {
+ const schema = this._def.items[itemIndex] || this._def.rest;
+ if (!schema)
+ return null;
+ return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
+ }).filter((x) => !!x);
+ if (ctx.common.async) {
+ return Promise.all(items).then((results) => {
+ return ParseStatus.mergeArray(status, results);
+ });
+ } else {
+ return ParseStatus.mergeArray(status, items);
}
- handlerData[j] = handlers.map(([h, paramCount]) => {
- const paramIndexMap = /* @__PURE__ */ Object.create(null);
- paramCount -= 1;
- for (; paramCount >= 0; paramCount--) {
- const [key, value] = paramAssoc[paramCount];
- paramIndexMap[key] = value;
- }
- return [h, paramIndexMap];
- });
}
- const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
- for (let i = 0, len = handlerData.length; i < len; i++) {
- for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {
- const map = handlerData[i][j]?.[1];
- if (!map) {
- continue;
- }
- const keys = Object.keys(map);
- for (let k = 0, len3 = keys.length; k < len3; k++) {
- map[keys[k]] = paramReplacementMap[map[keys[k]]];
- }
- }
+ get items() {
+ return this._def.items;
}
- const handlerMap = [];
- for (const i in indexReplacementMap) {
- handlerMap[i] = handlerData[indexReplacementMap[i]];
+ rest(rest) {
+ return new _ZodTuple({
+ ...this._def,
+ rest
+ });
}
- return [regexp, handlerMap, staticMap];
-}
-function findMiddleware(middleware, path5) {
- if (!middleware) {
- return void 0;
+};
+ZodTuple.create = (schemas, params) => {
+ if (!Array.isArray(schemas)) {
+ throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
}
- for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
- if (buildWildcardRegExp(k).test(path5)) {
- return [...middleware[k]];
- }
+ return new ZodTuple({
+ items: schemas,
+ typeName: ZodFirstPartyTypeKind.ZodTuple,
+ rest: null,
+ ...processCreateParams(params)
+ });
+};
+var ZodRecord = class _ZodRecord extends ZodType {
+ get keySchema() {
+ return this._def.keyType;
}
- return void 0;
-}
-var RegExpRouter = class {
- name = "RegExpRouter";
- #middleware;
- #routes;
- constructor() {
- this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
- this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
+ get valueSchema() {
+ return this._def.valueType;
}
- add(method, path5, handler) {
- const middleware = this.#middleware;
- const routes = this.#routes;
- if (!middleware || !routes) {
- throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
- }
- if (!middleware[method]) {
- ;
- [middleware, routes].forEach((handlerMap) => {
- handlerMap[method] = /* @__PURE__ */ Object.create(null);
- Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {
- handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];
- });
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.object) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.object,
+ received: ctx.parsedType
});
+ return INVALID;
}
- if (path5 === "/*") {
- path5 = "*";
- }
- const paramCount = (path5.match(/\/:/g) || []).length;
- if (/\*$/.test(path5)) {
- const re = buildWildcardRegExp(path5);
- if (method === METHOD_NAME_ALL) {
- Object.keys(middleware).forEach((m) => {
- middleware[m][path5] ||= findMiddleware(middleware[m], path5) || findMiddleware(middleware[METHOD_NAME_ALL], path5) || [];
- });
- } else {
- middleware[method][path5] ||= findMiddleware(middleware[method], path5) || findMiddleware(middleware[METHOD_NAME_ALL], path5) || [];
- }
- Object.keys(middleware).forEach((m) => {
- if (method === METHOD_NAME_ALL || method === m) {
- Object.keys(middleware[m]).forEach((p) => {
- re.test(p) && middleware[m][p].push([handler, paramCount]);
- });
- }
- });
- Object.keys(routes).forEach((m) => {
- if (method === METHOD_NAME_ALL || method === m) {
- Object.keys(routes[m]).forEach(
- (p) => re.test(p) && routes[m][p].push([handler, paramCount])
- );
- }
+ const pairs = [];
+ const keyType = this._def.keyType;
+ const valueType = this._def.valueType;
+ for (const key in ctx.data) {
+ pairs.push({
+ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
+ value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
+ alwaysSet: key in ctx.data
});
- return;
}
- const paths = checkOptionalParameter(path5) || [path5];
- for (let i = 0, len = paths.length; i < len; i++) {
- const path22 = paths[i];
- Object.keys(routes).forEach((m) => {
- if (method === METHOD_NAME_ALL || method === m) {
- routes[m][path22] ||= [
- ...findMiddleware(middleware[m], path22) || findMiddleware(middleware[METHOD_NAME_ALL], path22) || []
- ];
- routes[m][path22].push([handler, paramCount - len + i + 1]);
- }
- });
+ if (ctx.common.async) {
+ return ParseStatus.mergeObjectAsync(status, pairs);
+ } else {
+ return ParseStatus.mergeObjectSync(status, pairs);
}
}
- match = match;
- buildAllMatchers() {
- const matchers = /* @__PURE__ */ Object.create(null);
- Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
- matchers[method] ||= this.#buildMatcher(method);
- });
- this.#middleware = this.#routes = void 0;
- clearWildcardRegExpCache();
- return matchers;
+ get element() {
+ return this._def.valueType;
}
- #buildMatcher(method) {
- const routes = [];
- let hasOwnRoute = method === METHOD_NAME_ALL;
- [this.#middleware, this.#routes].forEach((r) => {
- const ownRoute = r[method] ? Object.keys(r[method]).map((path5) => [path5, r[method][path5]]) : [];
- if (ownRoute.length !== 0) {
- hasOwnRoute ||= true;
- routes.push(...ownRoute);
- } else if (method !== METHOD_NAME_ALL) {
- routes.push(
- ...Object.keys(r[METHOD_NAME_ALL]).map((path5) => [path5, r[METHOD_NAME_ALL][path5]])
- );
- }
- });
- if (!hasOwnRoute) {
- return null;
- } else {
- return buildMatcherFromPreprocessedRoutes(routes);
+ static create(first, second, third) {
+ if (second instanceof ZodType) {
+ return new _ZodRecord({
+ keyType: first,
+ valueType: second,
+ typeName: ZodFirstPartyTypeKind.ZodRecord,
+ ...processCreateParams(third)
+ });
}
+ return new _ZodRecord({
+ keyType: ZodString.create(),
+ valueType: first,
+ typeName: ZodFirstPartyTypeKind.ZodRecord,
+ ...processCreateParams(second)
+ });
}
};
-
-// node_modules/hono/dist/router/smart-router/router.js
-var SmartRouter = class {
- name = "SmartRouter";
- #routers = [];
- #routes = [];
- constructor(init) {
- this.#routers = init.routers;
+var ZodMap = class extends ZodType {
+ get keySchema() {
+ return this._def.keyType;
}
- add(method, path5, handler) {
- if (!this.#routes) {
- throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
- }
- this.#routes.push([method, path5, handler]);
+ get valueSchema() {
+ return this._def.valueType;
}
- match(method, path5) {
- if (!this.#routes) {
- throw new Error("Fatal error");
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.map) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.map,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- const routers = this.#routers;
- const routes = this.#routes;
- const len = routers.length;
- let i = 0;
- let res;
- for (; i < len; i++) {
- const router = routers[i];
- try {
- for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {
- router.add(...routes[i2]);
+ const keyType = this._def.keyType;
+ const valueType = this._def.valueType;
+ const pairs = [...ctx.data.entries()].map(([key, value], index) => {
+ return {
+ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
+ value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
+ };
+ });
+ if (ctx.common.async) {
+ const finalMap = /* @__PURE__ */ new Map();
+ return Promise.resolve().then(async () => {
+ for (const pair of pairs) {
+ const key = await pair.key;
+ const value = await pair.value;
+ if (key.status === "aborted" || value.status === "aborted") {
+ return INVALID;
+ }
+ if (key.status === "dirty" || value.status === "dirty") {
+ status.dirty();
+ }
+ finalMap.set(key.value, value.value);
+ }
+ return { status: status.value, value: finalMap };
+ });
+ } else {
+ const finalMap = /* @__PURE__ */ new Map();
+ for (const pair of pairs) {
+ const key = pair.key;
+ const value = pair.value;
+ if (key.status === "aborted" || value.status === "aborted") {
+ return INVALID;
}
- res = router.match(method, path5);
- } catch (e) {
- if (e instanceof UnsupportedPathError) {
- continue;
+ if (key.status === "dirty" || value.status === "dirty") {
+ status.dirty();
}
- throw e;
+ finalMap.set(key.value, value.value);
}
- this.match = router.match.bind(router);
- this.#routers = [router];
- this.#routes = void 0;
- break;
- }
- if (i === len) {
- throw new Error("Fatal error");
- }
- this.name = `SmartRouter + ${this.activeRouter.name}`;
- return res;
- }
- get activeRouter() {
- if (this.#routes || this.#routers.length !== 1) {
- throw new Error("No active router has been determined yet.");
+ return { status: status.value, value: finalMap };
}
- return this.#routers[0];
}
};
-
-// node_modules/hono/dist/router/trie-router/node.js
-var emptyParams = /* @__PURE__ */ Object.create(null);
-var hasChildren = (children) => {
- for (const _ in children) {
- return true;
- }
- return false;
+ZodMap.create = (keyType, valueType, params) => {
+ return new ZodMap({
+ valueType,
+ keyType,
+ typeName: ZodFirstPartyTypeKind.ZodMap,
+ ...processCreateParams(params)
+ });
};
-var Node2 = class _Node2 {
- #methods;
- #children;
- #patterns;
- #order = 0;
- #params = emptyParams;
- constructor(method, handler, children) {
- this.#children = children || /* @__PURE__ */ Object.create(null);
- this.#methods = [];
- if (method && handler) {
- const m = /* @__PURE__ */ Object.create(null);
- m[method] = { handler, possibleKeys: [], score: 0 };
- this.#methods = [m];
+var ZodSet = class _ZodSet extends ZodType {
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.set) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.set,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- this.#patterns = [];
- }
- insert(method, path5, handler) {
- this.#order = ++this.#order;
- let curNode = this;
- const parts = splitRoutingPath(path5);
- const possibleKeys = [];
- for (let i = 0, len = parts.length; i < len; i++) {
- const p = parts[i];
- const nextP = parts[i + 1];
- const pattern = getPattern(p, nextP);
- const key = Array.isArray(pattern) ? pattern[0] : p;
- if (key in curNode.#children) {
- curNode = curNode.#children[key];
- if (pattern) {
- possibleKeys.push(pattern[1]);
- }
- continue;
- }
- curNode.#children[key] = new _Node2();
- if (pattern) {
- curNode.#patterns.push(pattern);
- possibleKeys.push(pattern[1]);
+ const def = this._def;
+ if (def.minSize !== null) {
+ if (ctx.data.size < def.minSize.value) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_small,
+ minimum: def.minSize.value,
+ type: "set",
+ inclusive: true,
+ exact: false,
+ message: def.minSize.message
+ });
+ status.dirty();
}
- curNode = curNode.#children[key];
}
- curNode.#methods.push({
- [method]: {
- handler,
- possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),
- score: this.#order
- }
- });
- return curNode;
- }
- #pushHandlerSets(handlerSets, node, method, nodeParams, params) {
- for (let i = 0, len = node.#methods.length; i < len; i++) {
- const m = node.#methods[i];
- const handlerSet = m[method] || m[METHOD_NAME_ALL];
- const processedSet = {};
- if (handlerSet !== void 0) {
- handlerSet.params = /* @__PURE__ */ Object.create(null);
- handlerSets.push(handlerSet);
- if (nodeParams !== emptyParams || params && params !== emptyParams) {
- for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
- const key = handlerSet.possibleKeys[i2];
- const processed = processedSet[handlerSet.score];
- handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
- processedSet[handlerSet.score] = true;
- }
- }
+ if (def.maxSize !== null) {
+ if (ctx.data.size > def.maxSize.value) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.too_big,
+ maximum: def.maxSize.value,
+ type: "set",
+ inclusive: true,
+ exact: false,
+ message: def.maxSize.message
+ });
+ status.dirty();
}
}
- }
- search(method, path5) {
- const handlerSets = [];
- this.#params = emptyParams;
- const curNode = this;
- let curNodes = [curNode];
- const parts = splitPath(path5);
- const curNodesQueue = [];
- const len = parts.length;
- let partOffsets = null;
- for (let i = 0; i < len; i++) {
- const part = parts[i];
- const isLast = i === len - 1;
- const tempNodes = [];
- for (let j = 0, len2 = curNodes.length; j < len2; j++) {
- const node = curNodes[j];
- const nextNode = node.#children[part];
- if (nextNode) {
- nextNode.#params = node.#params;
- if (isLast) {
- if (nextNode.#children["*"]) {
- this.#pushHandlerSets(handlerSets, nextNode.#children["*"], method, node.#params);
- }
- this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);
- } else {
- tempNodes.push(nextNode);
- }
- }
- for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {
- const pattern = node.#patterns[k];
- const params = node.#params === emptyParams ? {} : { ...node.#params };
- if (pattern === "*") {
- const astNode = node.#children["*"];
- if (astNode) {
- this.#pushHandlerSets(handlerSets, astNode, method, node.#params);
- astNode.#params = params;
- tempNodes.push(astNode);
- }
- continue;
- }
- const [key, name, matcher] = pattern;
- if (!part && !(matcher instanceof RegExp)) {
- continue;
- }
- const child = node.#children[key];
- if (matcher instanceof RegExp) {
- if (partOffsets === null) {
- partOffsets = new Array(len);
- let offset = path5[0] === "/" ? 1 : 0;
- for (let p = 0; p < len; p++) {
- partOffsets[p] = offset;
- offset += parts[p].length + 1;
- }
- }
- const restPathString = path5.substring(partOffsets[i]);
- const m = matcher.exec(restPathString);
- if (m) {
- params[name] = m[0];
- this.#pushHandlerSets(handlerSets, child, method, node.#params, params);
- if (hasChildren(child.#children)) {
- child.#params = params;
- const componentCount = m[0].match(/\//)?.length ?? 0;
- const targetCurNodes = curNodesQueue[componentCount] ||= [];
- targetCurNodes.push(child);
- }
- continue;
- }
- }
- if (matcher === true || matcher.test(part)) {
- params[name] = part;
- if (isLast) {
- this.#pushHandlerSets(handlerSets, child, method, params, node.#params);
- if (child.#children["*"]) {
- this.#pushHandlerSets(
- handlerSets,
- child.#children["*"],
- method,
- params,
- node.#params
- );
- }
- } else {
- child.#params = params;
- tempNodes.push(child);
- }
- }
- }
+ const valueType = this._def.valueType;
+ function finalizeSet(elements2) {
+ const parsedSet = /* @__PURE__ */ new Set();
+ for (const element of elements2) {
+ if (element.status === "aborted")
+ return INVALID;
+ if (element.status === "dirty")
+ status.dirty();
+ parsedSet.add(element.value);
}
- const shifted = curNodesQueue.shift();
- curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
- }
- if (handlerSets.length > 1) {
- handlerSets.sort((a, b) => {
- return a.score - b.score;
- });
+ return { status: status.value, value: parsedSet };
}
- return [handlerSets.map(({ handler, params }) => [handler, params])];
- }
-};
-
-// node_modules/hono/dist/router/trie-router/router.js
-var TrieRouter = class {
- name = "TrieRouter";
- #node;
- constructor() {
- this.#node = new Node2();
- }
- add(method, path5, handler) {
- const results = checkOptionalParameter(path5);
- if (results) {
- for (let i = 0, len = results.length; i < len; i++) {
- this.#node.insert(method, results[i], handler);
- }
- return;
+ const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
+ if (ctx.common.async) {
+ return Promise.all(elements).then((elements2) => finalizeSet(elements2));
+ } else {
+ return finalizeSet(elements);
}
- this.#node.insert(method, path5, handler);
}
- match(method, path5) {
- return this.#node.search(method, path5);
+ min(minSize, message) {
+ return new _ZodSet({
+ ...this._def,
+ minSize: { value: minSize, message: errorUtil.toString(message) }
+ });
}
-};
-
-// node_modules/hono/dist/hono.js
-var Hono2 = class extends Hono {
- /**
- * Creates an instance of the Hono class.
- *
- * @param options - Optional configuration options for the Hono instance.
- */
- constructor(options = {}) {
- super(options);
- this.router = options.router ?? new SmartRouter({
- routers: [new RegExpRouter(), new TrieRouter()]
+ max(maxSize, message) {
+ return new _ZodSet({
+ ...this._def,
+ maxSize: { value: maxSize, message: errorUtil.toString(message) }
});
}
+ size(size, message) {
+ return this.min(size, message).max(size, message);
+ }
+ nonempty(message) {
+ return this.min(1, message);
+ }
};
-
-// src/mlclaw-space-runtime/csrf.ts
-import { createHmac as createHmac2, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
-var CSRF_TTL_SECONDS = 60 * 60;
-function createCsrfToken(params) {
- const now = params.now ?? Date.now();
- const body = Buffer.from(JSON.stringify({
- username: params.username,
- nonce: randomBytes2(24).toString("base64url"),
- exp: Math.floor(now / 1e3) + CSRF_TTL_SECONDS
- })).toString("base64url");
- return `${body}.${sign(body, params.sessionSecret)}`;
-}
-function verifyCsrfToken(params) {
- if (!params.token) {
- return false;
+ZodSet.create = (valueType, params) => {
+ return new ZodSet({
+ valueType,
+ minSize: null,
+ maxSize: null,
+ typeName: ZodFirstPartyTypeKind.ZodSet,
+ ...processCreateParams(params)
+ });
+};
+var ZodFunction = class _ZodFunction extends ZodType {
+ constructor() {
+ super(...arguments);
+ this.validate = this.implement;
}
- const [body, signature] = params.token.split(".");
- if (!body || !signature || !signatureMatches(signature, sign(body, params.sessionSecret))) {
- return false;
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.function) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.function,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ function makeArgsIssue(args, error) {
+ return makeIssue({
+ data: args,
+ path: ctx.path,
+ errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), en_default].filter((x) => !!x),
+ issueData: {
+ code: ZodIssueCode.invalid_arguments,
+ argumentsError: error
+ }
+ });
+ }
+ function makeReturnsIssue(returns, error) {
+ return makeIssue({
+ data: returns,
+ path: ctx.path,
+ errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, getErrorMap(), en_default].filter((x) => !!x),
+ issueData: {
+ code: ZodIssueCode.invalid_return_type,
+ returnTypeError: error
+ }
+ });
+ }
+ const params = { errorMap: ctx.common.contextualErrorMap };
+ const fn = ctx.data;
+ if (this._def.returns instanceof ZodPromise) {
+ const me = this;
+ return OK(async function(...args) {
+ const error = new ZodError([]);
+ const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
+ error.addIssue(makeArgsIssue(args, e));
+ throw error;
+ });
+ const result = await Reflect.apply(fn, this, parsedArgs);
+ const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
+ error.addIssue(makeReturnsIssue(result, e));
+ throw error;
+ });
+ return parsedReturns;
+ });
+ } else {
+ const me = this;
+ return OK(function(...args) {
+ const parsedArgs = me._def.args.safeParse(args, params);
+ if (!parsedArgs.success) {
+ throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
+ }
+ const result = Reflect.apply(fn, this, parsedArgs.data);
+ const parsedReturns = me._def.returns.safeParse(result, params);
+ if (!parsedReturns.success) {
+ throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
+ }
+ return parsedReturns.data;
+ });
+ }
}
- let parsed;
- try {
- parsed = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
- } catch {
- return false;
+ parameters() {
+ return this._def.args;
}
- if (!parsed || typeof parsed !== "object") {
- return false;
+ returnType() {
+ return this._def.returns;
}
- const payload = parsed;
- const now = Math.floor((params.now ?? Date.now()) / 1e3);
- return payload.username === params.username && typeof payload.exp === "number" && payload.exp > now && typeof payload.nonce === "string" && payload.nonce.length > 0;
-}
-function sign(value, secret) {
- return createHmac2("sha256", secret).update(value).digest("base64url");
-}
-function signatureMatches(a, b) {
- const left = Buffer.from(a);
- const right = Buffer.from(b);
- return left.length === right.length && timingSafeEqual2(left, right);
-}
-
-// src/mlclaw-space-runtime/delegated-brokerkit.ts
-import { createHash as createHash2, createHmac as createHmac3, randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual3 } from "node:crypto";
-
-// src/mlclaw-space-runtime/delegated-revisions.ts
-import { randomBytes as randomBytes3 } from "node:crypto";
-var DelegatedRevisions = class {
- epoch = randomBytes3(16).toString("base64url");
- revision = 0;
- material = "";
- current;
- waiters = /* @__PURE__ */ new Set();
- publish(material, value) {
- if (this.current && material === this.material) return this.current;
- this.material = material;
- this.revision += 1;
- this.current = value(this.cursor());
- for (const waiter of [...this.waiters])
- this.finish(waiter, { api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: true });
- return this.current;
+ args(...items) {
+ return new _ZodFunction({
+ ...this._def,
+ args: ZodTuple.create(items).rest(ZodUnknown.create())
+ });
}
- wait(cursor, waitSeconds, signal) {
- const observed = this.parse(cursor);
- if (observed === void 0) return Promise.reject(revisionError("cursor_expired"));
- if (observed !== this.revision) {
- return Promise.resolve({ api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: true });
- }
- if (this.waiters.size >= 256) return Promise.reject(revisionError("source_unavailable"));
- if (signal?.aborted) return Promise.reject(abortError());
- return new Promise((resolve, reject) => {
- const waiter = {
- resolve,
- reject,
- timer: setTimeout(() => {
- this.finish(waiter, { api_version: "brokerkit.io/operator-ui/v1", cursor: this.cursor(), changed: false });
- }, waitSeconds * 1e3),
- ...signal ? { signal } : {}
- };
- waiter.timer.unref();
- if (signal) {
- waiter.abort = () => this.fail(waiter, abortError());
- signal.addEventListener("abort", waiter.abort, { once: true });
- }
- this.waiters.add(waiter);
+ returns(returnType) {
+ return new _ZodFunction({
+ ...this._def,
+ returns: returnType
});
}
- cursor() {
- return `${this.epoch}.${this.revision.toString(36)}`;
+ implement(func) {
+ const validatedFunc = this.parse(func);
+ return validatedFunc;
}
- parse(value) {
- const match2 = /^([A-Za-z0-9_-]{22})\.([0-9a-z]{1,13})$/u.exec(value);
- if (!match2 || match2[1] !== this.epoch) return void 0;
- const revision = Number.parseInt(match2[2] ?? "", 36);
- return Number.isSafeInteger(revision) && revision <= this.revision ? revision : void 0;
+ strictImplement(func) {
+ const validatedFunc = this.parse(func);
+ return validatedFunc;
}
- finish(waiter, value) {
- this.cleanup(waiter);
- waiter.resolve(value);
+ static create(args, returns, params) {
+ return new _ZodFunction({
+ args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()),
+ returns: returns || ZodUnknown.create(),
+ typeName: ZodFirstPartyTypeKind.ZodFunction,
+ ...processCreateParams(params)
+ });
}
- fail(waiter, error) {
- this.cleanup(waiter);
- waiter.reject(error);
+};
+var ZodLazy = class extends ZodType {
+ get schema() {
+ return this._def.getter();
+ }
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ const lazySchema = this._def.getter();
+ return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
+ }
+};
+ZodLazy.create = (getter, params) => {
+ return new ZodLazy({
+ getter,
+ typeName: ZodFirstPartyTypeKind.ZodLazy,
+ ...processCreateParams(params)
+ });
+};
+var ZodLiteral = class extends ZodType {
+ _parse(input) {
+ if (input.data !== this._def.value) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ received: ctx.data,
+ code: ZodIssueCode.invalid_literal,
+ expected: this._def.value
+ });
+ return INVALID;
+ }
+ return { status: "valid", value: input.data };
}
- cleanup(waiter) {
- if (!this.waiters.delete(waiter)) return;
- clearTimeout(waiter.timer);
- if (waiter.signal && waiter.abort) waiter.signal.removeEventListener("abort", waiter.abort);
+ get value() {
+ return this._def.value;
}
};
-function revisionError(code) {
- return Object.assign(new Error(code), { code });
-}
-function abortError() {
- return new DOMException("The operation was aborted", "AbortError");
+ZodLiteral.create = (value, params) => {
+ return new ZodLiteral({
+ value,
+ typeName: ZodFirstPartyTypeKind.ZodLiteral,
+ ...processCreateParams(params)
+ });
+};
+function createZodEnum(values, params) {
+ return new ZodEnum({
+ values,
+ typeName: ZodFirstPartyTypeKind.ZodEnum,
+ ...processCreateParams(params)
+ });
}
-
-// src/mlclaw-space-runtime/delegated-brokerkit.ts
-var API_VERSION = "brokerkit.io/delegated-web/v1";
-var TOKEN_LIFETIME_SECONDS = 4 * 60;
-var MAX_PAGES_PER_SOURCE = 32;
-var MAX_HANDLES = 4096;
-var SOURCE_DEADLINE_MS = 15e3;
-var DelegatedBrokerKit = class {
- constructor(registry, sessionSecret, now = () => /* @__PURE__ */ new Date(), sourceDeadlineMs = SOURCE_DEADLINE_MS) {
- this.registry = registry;
- this.now = now;
- this.sourceDeadlineMs = sourceDeadlineMs;
- this.key = createHmac3("sha256", sessionSecret).update("mlclaw/brokerkit-delegated-web/v1", "utf8").digest();
- }
- key;
- handles = /* @__PURE__ */ new Map();
- handlesByIdentity = /* @__PURE__ */ new Map();
- snapshotInFlight;
- revisions = new DelegatedRevisions();
- issueSession(actor, access) {
- const issuedAt = Math.floor(this.now().getTime() / 1e3);
- const expiresAt = issuedAt + TOKEN_LIFETIME_SECONDS;
- const payload = {
- version: 1,
- audience: "brokerkit-delegated-web",
- subject: actor,
- issuedAt,
- expiresAt,
- nonce: randomBytes4(16).toString("base64url"),
- access
- };
- const encoded = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
- const signature = this.sign(encoded);
- return {
- api_version: API_VERSION,
- token: `${encoded}.${signature}`,
- expires_at: new Date(expiresAt * 1e3).toISOString(),
- access,
- renewal_transport: "direct"
- };
- }
- authorize(token) {
- return this.authorizeSession(token)?.actor;
+var ZodEnum = class _ZodEnum extends ZodType {
+ _parse(input) {
+ if (typeof input.data !== "string") {
+ const ctx = this._getOrReturnCtx(input);
+ const expectedValues = this._def.values;
+ addIssueToContext(ctx, {
+ expected: util.joinValues(expectedValues),
+ received: ctx.parsedType,
+ code: ZodIssueCode.invalid_type
+ });
+ return INVALID;
+ }
+ if (!this._cache) {
+ this._cache = new Set(this._def.values);
+ }
+ if (!this._cache.has(input.data)) {
+ const ctx = this._getOrReturnCtx(input);
+ const expectedValues = this._def.values;
+ addIssueToContext(ctx, {
+ received: ctx.data,
+ code: ZodIssueCode.invalid_enum_value,
+ options: expectedValues
+ });
+ return INVALID;
+ }
+ return OK(input.data);
}
- authorizeSession(token) {
- const encoded = authenticatedTokenPayload(token, (value) => this.sign(value));
- if (!encoded) return void 0;
- const payload = parseTokenPayload(encoded);
- return payload && tokenIsCurrent(payload, this.now()) ? { actor: payload.subject, sessionId: payload.nonce, access: payload.access } : void 0;
+ get options() {
+ return this._def.values;
}
- async snapshot() {
- if (this.snapshotInFlight) return this.snapshotInFlight;
- const pending = this.buildSnapshot();
- this.snapshotInFlight = pending;
- try {
- return await pending;
- } finally {
- if (this.snapshotInFlight === pending) this.snapshotInFlight = void 0;
+ get enum() {
+ const enumValues = {};
+ for (const val of this._def.values) {
+ enumValues[val] = val;
}
+ return enumValues;
}
- async buildSnapshot() {
- this.pruneHandles();
- const synchronizedAt = this.now().toISOString();
- const results = await Promise.all(
- this.registry.entries().map(async ([summary, client]) => this.sourceSnapshot(summary, client, synchronizedAt))
- );
- const selected = selectSnapshotRequests(results, MAX_HANDLES);
- const reservedHandles = this.selectedExistingHandles(selected);
- const sources = results.map((result) => result.source);
- const requests = selected.map(
- ({ source, request }) => project(source, request, this.handle(source.id, request, reservedHandles))
- );
- const material = JSON.stringify({
- sources: sources.map((source) => ({
- id: source.id,
- label: source.label,
- healthy: source.healthy,
- ...source.error ? { error: source.error } : {}
- })),
- requests
- });
- return this.revisions.publish(material, (cursor) => ({
- api_version: "brokerkit.io/operator-ui/v1",
- cursor,
- sources,
- requests,
- synchronized_at: synchronizedAt
- }));
+ get Values() {
+ const enumValues = {};
+ for (const val of this._def.values) {
+ enumValues[val] = val;
+ }
+ return enumValues;
}
- async events(cursor, waitSeconds, signal) {
- await this.snapshot();
- const waiting = this.revisions.wait(cursor, waitSeconds, signal);
- const refresh = setInterval(() => void this.snapshot().catch(() => void 0), 1e3);
- refresh.unref();
- try {
- return await waiting;
- } catch (error) {
- if (error instanceof Error && "code" in error && (error.code === "cursor_expired" || error.code === "source_unavailable")) {
- throw delegatedError(error.code);
- }
- throw error;
- } finally {
- clearInterval(refresh);
+ get Enum() {
+ const enumValues = {};
+ for (const val of this._def.values) {
+ enumValues[val] = val;
}
+ return enumValues;
}
- async summary() {
- const snapshot = await this.snapshot();
- return {
- api_version: snapshot.api_version,
- cursor: snapshot.cursor,
- pending: snapshot.requests.filter((value) => value.request.status === "pending").length,
- healthy: snapshot.sources.every((source) => source.healthy)
- };
+ extract(values, newDef = this._def) {
+ return _ZodEnum.create(values, {
+ ...this._def,
+ ...newDef
+ });
}
- async detail(handle) {
- const record = this.resolveHandle(handle);
- const source = this.registry.get(record.sourceId);
- if (!source) throw delegatedError("source_unavailable");
- const request = await source.get(record.requestId);
- if (request.revision !== record.revision) throw delegatedError("revision_stale");
- return project(source.summary(), request, handle);
+ exclude(values, newDef = this._def) {
+ return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
+ ...this._def,
+ ...newDef
+ });
}
- async decide(handle, action, expectedRevision, actor, options = {}) {
- const record = this.resolveHandle(handle);
- const source = this.registry.get(record.sourceId);
- if (!source) throw delegatedError("source_unavailable");
- const current = await source.get(record.requestId);
- assertDecisionAllowed(current, record, action, expectedRevision, options);
- const decision = decisionOptions(record, action, expectedRevision, actor, options);
- const updated = await decideWithRecovery(source, record.requestId, action, decision);
- if (updated.status === "pending" || updated.status === "active") {
- this.removeHandle(handle, record);
- return project(source.summary(), updated, this.handle(record.sourceId, updated));
+};
+ZodEnum.create = createZodEnum;
+var ZodNativeEnum = class extends ZodType {
+ _parse(input) {
+ const nativeEnumValues = util.getValidEnumValues(this._def.values);
+ const ctx = this._getOrReturnCtx(input);
+ if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {
+ const expectedValues = util.objectValues(nativeEnumValues);
+ addIssueToContext(ctx, {
+ expected: util.joinValues(expectedValues),
+ received: ctx.parsedType,
+ code: ZodIssueCode.invalid_type
+ });
+ return INVALID;
}
- this.removeHandle(handle, record);
- return project(source.summary(), updated, handle);
- }
- async sourceSnapshot(summary, client, synchronizedAt) {
- const deadline = new AbortController();
- const timer = setTimeout(() => deadline.abort(), this.sourceDeadlineMs);
- timer.unref?.();
- try {
- await client.discover(deadline.signal);
- const pages = await Promise.all([
- this.sourceRequests(client, "pending", deadline.signal),
- this.sourceRequests(client, "active", deadline.signal)
- ]);
- const requests = reconcileRequests(pages.map((page2) => page2.requests));
- return {
- source: deadline.signal.aborted ? { ...summary, healthy: false, error: "broker_timeout" } : pages.some((page2) => page2.truncated) ? { ...summary, healthy: false, error: "source_truncated" } : { ...summary, healthy: true, last_sync_at: synchronizedAt },
- requests
- };
- } catch (error) {
- return {
- source: { ...summary, healthy: false, error: safeSourceError(error) },
- requests: []
- };
- } finally {
- clearTimeout(timer);
+ if (!this._cache) {
+ this._cache = new Set(util.getValidEnumValues(this._def.values));
+ }
+ if (!this._cache.has(input.data)) {
+ const expectedValues = util.objectValues(nativeEnumValues);
+ addIssueToContext(ctx, {
+ received: ctx.data,
+ code: ZodIssueCode.invalid_enum_value,
+ options: expectedValues
+ });
+ return INVALID;
}
+ return OK(input.data);
}
- async sourceRequests(client, status, signal) {
- const requests = [];
- let cursor;
- try {
- for (let pageNumber = 0; pageNumber < MAX_PAGES_PER_SOURCE; pageNumber += 1) {
- const page2 = await client.list({ status, ...cursor ? { cursor } : {}, limit: 100 }, signal);
- requests.push(...page2.requests);
- cursor = page2.next_cursor;
- if (!cursor) return { requests, truncated: false };
- }
- } catch (error) {
- if (!signal.aborted) throw error;
- }
- return { requests, truncated: Boolean(cursor) };
+ get enum() {
+ return this._def.values;
}
- selectedExistingHandles(selected) {
- const handles = /* @__PURE__ */ new Set();
- for (const { source, request } of selected) {
- const handle = this.handlesByIdentity.get(requestIdentity(source.id, request.id, request.revision));
- if (handle && this.handles.has(handle)) handles.add(handle);
+};
+ZodNativeEnum.create = (values, params) => {
+ return new ZodNativeEnum({
+ values,
+ typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
+ ...processCreateParams(params)
+ });
+};
+var ZodPromise = class extends ZodType {
+ unwrap() {
+ return this._def.type;
+ }
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.promise,
+ received: ctx.parsedType
+ });
+ return INVALID;
}
- return handles;
+ const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
+ return OK(promisified.then((data) => {
+ return this._def.type.parseAsync(data, {
+ path: ctx.path,
+ errorMap: ctx.common.contextualErrorMap
+ });
+ }));
}
- handle(sourceId, request, reservedHandles = /* @__PURE__ */ new Set()) {
- const identity = requestIdentity(sourceId, request.id, request.revision);
- const existing = this.handlesByIdentity.get(identity);
- if (existing && this.handles.has(existing)) {
- reservedHandles.add(existing);
- return existing;
+};
+ZodPromise.create = (schema, params) => {
+ return new ZodPromise({
+ type: schema,
+ typeName: ZodFirstPartyTypeKind.ZodPromise,
+ ...processCreateParams(params)
+ });
+};
+var ZodEffects = class extends ZodType {
+ innerType() {
+ return this._def.schema;
+ }
+ sourceType() {
+ return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
+ }
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ const effect = this._def.effect || null;
+ const checkCtx = {
+ addIssue: (arg) => {
+ addIssueToContext(ctx, arg);
+ if (arg.fatal) {
+ status.abort();
+ } else {
+ status.dirty();
+ }
+ },
+ get path() {
+ return ctx.path;
+ }
+ };
+ checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
+ if (effect.type === "preprocess") {
+ const processed = effect.transform(ctx.data, checkCtx);
+ if (ctx.common.async) {
+ return Promise.resolve(processed).then(async (processed2) => {
+ if (status.value === "aborted")
+ return INVALID;
+ const result = await this._def.schema._parseAsync({
+ data: processed2,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (result.status === "aborted")
+ return INVALID;
+ if (result.status === "dirty")
+ return DIRTY(result.value);
+ if (status.value === "dirty")
+ return DIRTY(result.value);
+ return result;
+ });
+ } else {
+ if (status.value === "aborted")
+ return INVALID;
+ const result = this._def.schema._parseSync({
+ data: processed,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (result.status === "aborted")
+ return INVALID;
+ if (result.status === "dirty")
+ return DIRTY(result.value);
+ if (status.value === "dirty")
+ return DIRTY(result.value);
+ return result;
+ }
}
- if (this.handles.size >= MAX_HANDLES && !this.pruneOldestHandle(reservedHandles)) {
- throw delegatedError("source_unavailable");
+ if (effect.type === "refinement") {
+ const executeRefinement = (acc) => {
+ const result = effect.refinement(acc, checkCtx);
+ if (ctx.common.async) {
+ return Promise.resolve(result);
+ }
+ if (result instanceof Promise) {
+ throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
+ }
+ return acc;
+ };
+ if (ctx.common.async === false) {
+ const inner = this._def.schema._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (inner.status === "aborted")
+ return INVALID;
+ if (inner.status === "dirty")
+ status.dirty();
+ executeRefinement(inner.value);
+ return { status: status.value, value: inner.value };
+ } else {
+ return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
+ if (inner.status === "aborted")
+ return INVALID;
+ if (inner.status === "dirty")
+ status.dirty();
+ return executeRefinement(inner.value).then(() => {
+ return { status: status.value, value: inner.value };
+ });
+ });
+ }
}
- const handle = randomBytes4(18).toString("base64url");
- const requestExpiry = Date.parse(handleExpiry(request));
- const expiresAtMs = Number.isFinite(requestExpiry) ? Math.min(requestExpiry, this.now().getTime() + 24 * 60 * 6e4) : this.now().getTime() + 5 * 6e4;
- this.handles.set(handle, { sourceId, requestId: request.id, revision: request.revision, expiresAtMs });
- this.handlesByIdentity.set(identity, handle);
- reservedHandles.add(handle);
- return handle;
- }
- resolveHandle(handle) {
- if (!/^[A-Za-z0-9_-]{24}$/u.test(handle)) throw delegatedError("request_not_found");
- const record = this.handles.get(handle);
- if (!record || record.expiresAtMs <= this.now().getTime()) {
- if (record) this.removeHandle(handle, record);
- throw delegatedError("request_not_found");
+ if (effect.type === "transform") {
+ if (ctx.common.async === false) {
+ const base = this._def.schema._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (!isValid(base))
+ return INVALID;
+ const result = effect.transform(base.value, checkCtx);
+ if (result instanceof Promise) {
+ throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
+ }
+ return { status: status.value, value: result };
+ } else {
+ return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
+ if (!isValid(base))
+ return INVALID;
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
+ status: status.value,
+ value: result
+ }));
+ });
+ }
}
- return record;
+ util.assertNever(effect);
}
- pruneHandles() {
- for (const [handle, record] of this.handles) {
- if (record.expiresAtMs <= this.now().getTime()) this.removeHandle(handle, record);
+};
+ZodEffects.create = (schema, effect, params) => {
+ return new ZodEffects({
+ schema,
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
+ effect,
+ ...processCreateParams(params)
+ });
+};
+ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
+ return new ZodEffects({
+ schema,
+ effect: { type: "preprocess", transform: preprocess },
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
+ ...processCreateParams(params)
+ });
+};
+var ZodOptional = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType === ZodParsedType.undefined) {
+ return OK(void 0);
}
+ return this._def.innerType._parse(input);
}
- pruneOldestHandle(reservedHandles) {
- for (const [handle, record] of this.handles) {
- if (reservedHandles.has(handle)) continue;
- this.removeHandle(handle, record);
- return true;
- }
- return false;
+ unwrap() {
+ return this._def.innerType;
}
- removeHandle(handle, record) {
- this.handles.delete(handle);
- this.handlesByIdentity.delete(requestIdentity(record.sourceId, record.requestId, record.revision));
+};
+ZodOptional.create = (type, params) => {
+ return new ZodOptional({
+ innerType: type,
+ typeName: ZodFirstPartyTypeKind.ZodOptional,
+ ...processCreateParams(params)
+ });
+};
+var ZodNullable = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType === ZodParsedType.null) {
+ return OK(null);
+ }
+ return this._def.innerType._parse(input);
}
- sign(encoded) {
- return createHmac3("sha256", this.key).update(encoded, "utf8").digest("base64url");
+ unwrap() {
+ return this._def.innerType;
}
};
-async function decideWithRecovery(source, requestId, action, decision) {
- try {
- return await source.decide(requestId, action, decision);
- } catch (error) {
- if (error instanceof BrokerOperatorError) throw error;
- try {
- await source.get(requestId);
- } catch {
- throw delegatedError("source_unavailable");
- }
- try {
- return await source.decide(requestId, action, decision);
- } catch (retryError) {
- if (retryError instanceof BrokerOperatorError) throw retryError;
- throw delegatedError("source_unavailable");
+ZodNullable.create = (type, params) => {
+ return new ZodNullable({
+ innerType: type,
+ typeName: ZodFirstPartyTypeKind.ZodNullable,
+ ...processCreateParams(params)
+ });
+};
+var ZodDefault = class extends ZodType {
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ let data = ctx.data;
+ if (ctx.parsedType === ZodParsedType.undefined) {
+ data = this._def.defaultValue();
}
+ return this._def.innerType._parse({
+ data,
+ path: ctx.path,
+ parent: ctx
+ });
}
-}
-function selectSnapshotRequests(results, limit) {
- const buckets = results.flatMap(
- (result) => ["pending", "active"].map((status) => ({
- source: result.source,
- requests: result.requests.filter((request) => request.status === status),
- index: 0
- }))
- );
- const selected = [];
- while (selected.length < limit) {
- let added = false;
- for (const bucket of buckets) {
- const request = bucket.requests[bucket.index];
- if (!request) continue;
- selected.push({ source: bucket.source, request });
- bucket.index += 1;
- added = true;
- if (selected.length === limit) break;
- }
- if (!added) break;
+ removeDefault() {
+ return this._def.innerType;
}
- return selected;
-}
-function reconcileRequests(pages) {
- const requests = /* @__PURE__ */ new Map();
- for (const request of pages.flat()) {
- const current = requests.get(request.id);
- if (!current || request.revision > current.revision || request.revision === current.revision && request.status === "active" && current.status !== "active") {
- requests.set(request.id, request);
+};
+ZodDefault.create = (type, params) => {
+ return new ZodDefault({
+ innerType: type,
+ typeName: ZodFirstPartyTypeKind.ZodDefault,
+ defaultValue: typeof params.default === "function" ? params.default : () => params.default,
+ ...processCreateParams(params)
+ });
+};
+var ZodCatch = class extends ZodType {
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ const newCtx = {
+ ...ctx,
+ common: {
+ ...ctx.common,
+ issues: []
+ }
+ };
+ const result = this._def.innerType._parse({
+ data: newCtx.data,
+ path: newCtx.path,
+ parent: {
+ ...newCtx
+ }
+ });
+ if (isAsync(result)) {
+ return result.then((result2) => {
+ return {
+ status: "valid",
+ value: result2.status === "valid" ? result2.value : this._def.catchValue({
+ get error() {
+ return new ZodError(newCtx.common.issues);
+ },
+ input: newCtx.data
+ })
+ };
+ });
+ } else {
+ return {
+ status: "valid",
+ value: result.status === "valid" ? result.value : this._def.catchValue({
+ get error() {
+ return new ZodError(newCtx.common.issues);
+ },
+ input: newCtx.data
+ })
+ };
}
}
- return [...requests.values()];
-}
-var DelegatedBrokerKitError = class extends Error {
- constructor(code) {
- super(code);
- this.code = code;
+ removeCatch() {
+ return this._def.innerType;
}
};
-function delegatedError(code) {
- return new DelegatedBrokerKitError(code);
-}
-function project(source, request, handle) {
- return { source_id: source.id, source_label: source.label, handle, request };
-}
-function requestIdentity(sourceId, requestId, revision) {
- return `${sourceId}\0${requestId}\0${revision}`;
-}
-function handleExpiry(request) {
- if (request.status === "active") return request.active_expires_at ?? "";
- return request.pending_expires_at ?? request.active_expires_at ?? "";
-}
-function decisionKey(record, action, actor) {
- return createHash2("sha256").update(
- ["mlclaw-brokerkit-decision-v1", record.sourceId, record.requestId, String(record.revision), action, actor].join(
- "\0"
- ),
- "utf8"
- ).digest("base64url");
-}
-function decisionOptions(record, action, expectedRevision, actor, options) {
- return {
- expectedRevision,
- idempotencyKey: decisionKey(record, action, actor),
- onBehalfOf: `mlclaw:${actor}`,
- ...options.durationSeconds ? { durationSeconds: options.durationSeconds } : {},
- ...options.maxUses !== void 0 ? { maxUses: options.maxUses } : {}
- };
-}
-function decisionWithinBounds(action, request, options) {
- if (options.durationSeconds === void 0 && options.maxUses === void 0) return true;
- const bounds = request.approval_bounds;
- return Boolean(
- action === "approve" && bounds && options.durationSeconds !== void 0 && options.durationSeconds <= bounds.max_duration_seconds && useLimitWithinBounds(options.maxUses, bounds.max_uses)
- );
-}
-function useLimitWithinBounds(requested, maximum) {
- if (requested === void 0) return false;
- if (requested === null) return maximum === null;
- return maximum === null || requested <= maximum;
-}
-function assertDecisionAllowed(request, record, action, expectedRevision, options) {
- if (request.revision !== record.revision || request.revision !== expectedRevision) {
- throw delegatedError("revision_stale");
- }
- if (!request.allowed_actions.includes(action) || !decisionWithinBounds(action, request, options)) {
- throw delegatedError("action_not_allowed");
- }
-}
-function authenticatedTokenPayload(token, sign3) {
- if (!token || token.length > 4096 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/u.test(token)) return void 0;
- const [encoded, signature, extra] = token.split(".");
- return encoded && signature && extra === void 0 && safeEqual(signature, sign3(encoded)) ? encoded : void 0;
-}
-function parseTokenPayload(encoded) {
- try {
- const payload = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
- return validTokenPayload(payload) ? payload : void 0;
- } catch {
- return void 0;
- }
-}
-function tokenIsCurrent(payload, now) {
- const current = Math.floor(now.getTime() / 1e3);
- return payload.issuedAt <= current + 5 && payload.expiresAt > current && payload.expiresAt - payload.issuedAt <= TOKEN_LIFETIME_SECONDS;
-}
-function validTokenPayload(value) {
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
- const record = value;
- return hasExactTokenFields(record) && validTokenIdentity(record) && validTokenTimes(record) && validTokenNonce(record);
-}
-function hasExactTokenFields(record) {
- return Object.keys(record).sort().join(",") === "access,audience,expiresAt,issuedAt,nonce,subject,version";
-}
-function validTokenIdentity(record) {
- return record.version === 1 && record.audience === "brokerkit-delegated-web" && (record.access === "read" || record.access === "decide") && typeof record.subject === "string" && record.subject.length >= 1 && record.subject.length <= 200;
-}
-function validTokenTimes(record) {
- return typeof record.issuedAt === "number" && Number.isSafeInteger(record.issuedAt) && typeof record.expiresAt === "number" && Number.isSafeInteger(record.expiresAt);
-}
-function validTokenNonce(record) {
- return typeof record.nonce === "string" && /^[A-Za-z0-9_-]{22}$/u.test(record.nonce);
-}
-function safeEqual(left, right) {
- const a = Buffer.from(left, "utf8");
- const b = Buffer.from(right, "utf8");
- return a.length === b.length && timingSafeEqual3(a, b);
-}
-function safeSourceError(error) {
- const code = error instanceof BrokerOperatorError ? error.code : error instanceof DelegatedBrokerKitError ? error.code : void 0;
- if (code === "broker_timeout" || code === "unavailable" || code === "source_unavailable") return code;
- return "source_unavailable";
-}
-
-// src/mlclaw-space-runtime/hub-settings.ts
-function runtimeSettings(config2) {
- return {
- agentName: config2.agentName ?? null,
- model: config2.model,
- stateBucket: config2.stateBucket ?? null,
- stateMountDir: config2.stateMountDir ?? null,
- statePrefix: config2.statePrefix ?? null,
- gatewayLocation: config2.gatewayLocation ?? null,
- runtimeImage: config2.runtimeImage ?? null,
- runtimeId: config2.runtimeId ?? null,
- templateRev: config2.templateRev ?? null,
- allowedUsers: config2.allowedUsers,
- adminUsers: config2.adminUsers,
- modelChoices: config2.modelChoices,
- presetModels: PRESET_MODEL_CHOICES,
- branding: publicBranding(config2.branding)
- };
-}
-function normalizeModel(value) {
- return normalizeModelRef(value);
-}
-async function setCurrentSpaceVariable(config2, key, value) {
- if (!config2.spaceId || !config2.hfToken) {
- throw new Error("Space mutation requires SPACE_ID and HF_TOKEN");
+ZodCatch.create = (type, params) => {
+ return new ZodCatch({
+ innerType: type,
+ typeName: ZodFirstPartyTypeKind.ZodCatch,
+ catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
+ ...processCreateParams(params)
+ });
+};
+var ZodNaN = class extends ZodType {
+ _parse(input) {
+ const parsedType = this._getType(input);
+ if (parsedType !== ZodParsedType.nan) {
+ const ctx = this._getOrReturnCtx(input);
+ addIssueToContext(ctx, {
+ code: ZodIssueCode.invalid_type,
+ expected: ZodParsedType.nan,
+ received: ctx.parsedType
+ });
+ return INVALID;
+ }
+ return { status: "valid", value: input.data };
}
- await hubRequest(config2, `/api/spaces/${config2.spaceId}/variables`, {
- method: "POST",
- body: JSON.stringify({ key, value }),
- headers: { "content-type": "application/json" }
+};
+ZodNaN.create = (params) => {
+ return new ZodNaN({
+ typeName: ZodFirstPartyTypeKind.ZodNaN,
+ ...processCreateParams(params)
});
-}
-async function setCurrentSpaceSecret(config2, key, value) {
- if (!config2.spaceId || !config2.hfToken) {
- throw new Error("Space mutation requires SPACE_ID and HF_TOKEN");
+};
+var BRAND = Symbol("zod_brand");
+var ZodBranded = class extends ZodType {
+ _parse(input) {
+ const { ctx } = this._processInputParams(input);
+ const data = ctx.data;
+ return this._def.type._parse({
+ data,
+ path: ctx.path,
+ parent: ctx
+ });
}
- await hubRequest(config2, `/api/spaces/${config2.spaceId}/secrets`, {
- method: "POST",
- body: JSON.stringify({ key, value }),
- headers: { "content-type": "application/json" }
- });
-}
-async function restartCurrentSpace(config2) {
- if (!config2.spaceId || !config2.hfToken) {
- return false;
+ unwrap() {
+ return this._def.type;
}
- await hubRequest(config2, `/api/spaces/${config2.spaceId}/restart`, {
- method: "POST",
- body: JSON.stringify({ factoryReboot: false }),
- headers: { "content-type": "application/json" }
- });
- return true;
-}
-async function hubRequest(config2, path5, init) {
- const response = await fetch(`${config2.hubUrl.replace(/\/+$/, "")}${path5}`, {
- ...init,
- headers: {
- authorization: `Bearer ${config2.hfToken}`,
- ...init.headers
+};
+var ZodPipeline = class _ZodPipeline extends ZodType {
+ _parse(input) {
+ const { status, ctx } = this._processInputParams(input);
+ if (ctx.common.async) {
+ const handleAsync = async () => {
+ const inResult = await this._def.in._parseAsync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (inResult.status === "aborted")
+ return INVALID;
+ if (inResult.status === "dirty") {
+ status.dirty();
+ return DIRTY(inResult.value);
+ } else {
+ return this._def.out._parseAsync({
+ data: inResult.value,
+ path: ctx.path,
+ parent: ctx
+ });
+ }
+ };
+ return handleAsync();
+ } else {
+ const inResult = this._def.in._parseSync({
+ data: ctx.data,
+ path: ctx.path,
+ parent: ctx
+ });
+ if (inResult.status === "aborted")
+ return INVALID;
+ if (inResult.status === "dirty") {
+ status.dirty();
+ return {
+ status: "dirty",
+ value: inResult.value
+ };
+ } else {
+ return this._def.out._parseSync({
+ data: inResult.value,
+ path: ctx.path,
+ parent: ctx
+ });
+ }
}
- });
- if (!response.ok) {
- throw new Error(`Hub request failed: ${response.status} ${await response.text()}`);
}
- return response;
+ static create(a, b) {
+ return new _ZodPipeline({
+ in: a,
+ out: b,
+ typeName: ZodFirstPartyTypeKind.ZodPipeline
+ });
+ }
+};
+var ZodReadonly = class extends ZodType {
+ _parse(input) {
+ const result = this._def.innerType._parse(input);
+ const freeze = (data) => {
+ if (isValid(data)) {
+ data.value = Object.freeze(data.value);
+ }
+ return data;
+ };
+ return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
+ }
+ unwrap() {
+ return this._def.innerType;
+ }
+};
+ZodReadonly.create = (type, params) => {
+ return new ZodReadonly({
+ innerType: type,
+ typeName: ZodFirstPartyTypeKind.ZodReadonly,
+ ...processCreateParams(params)
+ });
+};
+function cleanParams(params, data) {
+ const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
+ const p2 = typeof p === "string" ? { message: p } : p;
+ return p2;
+}
+function custom(check, _params = {}, fatal) {
+ if (check)
+ return ZodAny.create().superRefine((data, ctx) => {
+ const r = check(data);
+ if (r instanceof Promise) {
+ return r.then((r2) => {
+ if (!r2) {
+ const params = cleanParams(_params, data);
+ const _fatal = params.fatal ?? fatal ?? true;
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
+ }
+ });
+ }
+ if (!r) {
+ const params = cleanParams(_params, data);
+ const _fatal = params.fatal ?? fatal ?? true;
+ ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
+ }
+ return;
+ });
+ return ZodAny.create();
}
+var late = {
+ object: ZodObject.lazycreate
+};
+var ZodFirstPartyTypeKind;
+(function(ZodFirstPartyTypeKind2) {
+ ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
+ ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
+ ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
+ ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
+ ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
+ ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
+ ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
+ ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
+ ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
+ ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
+ ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
+ ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
+ ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
+ ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
+ ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
+ ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
+ ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
+ ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
+ ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
+ ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
+ ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
+ ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
+ ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
+ ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
+ ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
+ ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
+ ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
+ ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
+ ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
+ ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
+ ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
+ ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
+ ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
+ ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
+ ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
+ ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
+})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
+var instanceOfType = (cls, params = {
+ message: `Input not instance of ${cls.name}`
+}) => custom((data) => data instanceof cls, params);
+var stringType = ZodString.create;
+var numberType = ZodNumber.create;
+var nanType = ZodNaN.create;
+var bigIntType = ZodBigInt.create;
+var booleanType = ZodBoolean.create;
+var dateType = ZodDate.create;
+var symbolType = ZodSymbol.create;
+var undefinedType = ZodUndefined.create;
+var nullType = ZodNull.create;
+var anyType = ZodAny.create;
+var unknownType = ZodUnknown.create;
+var neverType = ZodNever.create;
+var voidType = ZodVoid.create;
+var arrayType = ZodArray.create;
+var objectType = ZodObject.create;
+var strictObjectType = ZodObject.strictCreate;
+var unionType = ZodUnion.create;
+var discriminatedUnionType = ZodDiscriminatedUnion.create;
+var intersectionType = ZodIntersection.create;
+var tupleType = ZodTuple.create;
+var recordType = ZodRecord.create;
+var mapType = ZodMap.create;
+var setType = ZodSet.create;
+var functionType = ZodFunction.create;
+var lazyType = ZodLazy.create;
+var literalType = ZodLiteral.create;
+var enumType = ZodEnum.create;
+var nativeEnumType = ZodNativeEnum.create;
+var promiseType = ZodPromise.create;
+var effectsType = ZodEffects.create;
+var optionalType = ZodOptional.create;
+var nullableType = ZodNullable.create;
+var preprocessType = ZodEffects.createWithPreprocess;
+var pipelineType = ZodPipeline.create;
+var ostring = () => stringType().optional();
+var onumber = () => numberType().optional();
+var oboolean = () => booleanType().optional();
+var coerce = {
+ string: ((arg) => ZodString.create({ ...arg, coerce: true })),
+ number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
+ boolean: ((arg) => ZodBoolean.create({
+ ...arg,
+ coerce: true
+ })),
+ bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
+ date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
+};
+var NEVER = INVALID;
// src/mlclaw-space-runtime/oauth.ts
var HF_MCP_OAUTH_SCOPES = [
diff --git a/dist/mlclaw.mjs b/dist/mlclaw.mjs
index da36733..59b57ff 100755
--- a/dist/mlclaw.mjs
+++ b/dist/mlclaw.mjs
@@ -1202,8 +1202,8 @@ var require_command = __commonJS({
"node_modules/commander/lib/command.js"(exports) {
var EventEmitter = __require("node:events").EventEmitter;
var childProcess = __require("node:child_process");
- var path17 = __require("node:path");
- var fs17 = __require("node:fs");
+ var path16 = __require("node:path");
+ var fs16 = __require("node:fs");
var process5 = __require("node:process");
var { Argument: Argument2, humanReadableArgName } = require_argument();
var { CommanderError: CommanderError2 } = require_error();
@@ -2197,7 +2197,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
* @param {string} subcommandName
*/
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
- if (fs17.existsSync(executableFile)) return;
+ if (fs16.existsSync(executableFile)) return;
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
const executableMissing = `'${executableFile}' does not exist
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2215,11 +2215,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
let launchWithNode = false;
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
function findFile(baseDir, baseName) {
- const localBin = path17.resolve(baseDir, baseName);
- if (fs17.existsSync(localBin)) return localBin;
- if (sourceExt.includes(path17.extname(baseName))) return void 0;
+ const localBin = path16.resolve(baseDir, baseName);
+ if (fs16.existsSync(localBin)) return localBin;
+ if (sourceExt.includes(path16.extname(baseName))) return void 0;
const foundExt = sourceExt.find(
- (ext) => fs17.existsSync(`${localBin}${ext}`)
+ (ext) => fs16.existsSync(`${localBin}${ext}`)
);
if (foundExt) return `${localBin}${foundExt}`;
return void 0;
@@ -2231,21 +2231,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
if (this._scriptPath) {
let resolvedScriptPath;
try {
- resolvedScriptPath = fs17.realpathSync(this._scriptPath);
+ resolvedScriptPath = fs16.realpathSync(this._scriptPath);
} catch {
resolvedScriptPath = this._scriptPath;
}
- executableDir = path17.resolve(
- path17.dirname(resolvedScriptPath),
+ executableDir = path16.resolve(
+ path16.dirname(resolvedScriptPath),
executableDir
);
}
if (executableDir) {
let localFile = findFile(executableDir, executableFile);
if (!localFile && !subcommand._executableFile && this._scriptPath) {
- const legacyName = path17.basename(
+ const legacyName = path16.basename(
this._scriptPath,
- path17.extname(this._scriptPath)
+ path16.extname(this._scriptPath)
);
if (legacyName !== this._name) {
localFile = findFile(
@@ -2256,7 +2256,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
}
executableFile = localFile || executableFile;
}
- launchWithNode = sourceExt.includes(path17.extname(executableFile));
+ launchWithNode = sourceExt.includes(path16.extname(executableFile));
let proc;
if (process5.platform !== "win32") {
if (launchWithNode) {
@@ -3171,7 +3171,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
* @return {Command}
*/
nameFromFilename(filename) {
- this._name = path17.basename(filename, path17.extname(filename));
+ this._name = path16.basename(filename, path16.extname(filename));
return this;
}
/**
@@ -3185,9 +3185,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
* @param {string} [path]
* @return {(string|null|Command)}
*/
- executableDir(path18) {
- if (path18 === void 0) return this._executableDir;
- this._executableDir = path18;
+ executableDir(path17) {
+ if (path17 === void 0) return this._executableDir;
+ this._executableDir = path17;
return this;
}
/**
@@ -8952,7 +8952,7 @@ var init_cli = __esm({
});
// src/mlclaw/cli.ts
-import fs16 from "node:fs/promises";
+import fs15 from "node:fs/promises";
import { realpathSync } from "node:fs";
import os8 from "node:os";
import process4 from "node:process";
@@ -10124,10 +10124,10 @@ function parseGatewayLocation(value) {
// src/mlclaw/git.ts
import { execFile as execFile2 } from "node:child_process";
-import fs13 from "node:fs/promises";
+import fs12 from "node:fs/promises";
import os5 from "node:os";
-import path14 from "node:path";
-import { fileURLToPath as fileURLToPath3 } from "node:url";
+import path13 from "node:path";
+import { fileURLToPath as fileURLToPath2 } from "node:url";
import { promisify as promisify2 } from "node:util";
// src/vendor/hfjs-xet/error.ts
@@ -13950,10 +13950,10 @@ var CurrentXorbInfo = class {
hash: computeXorbHash(xorbChunksCleaned),
chunks: xorbChunksCleaned,
id: this.id,
- files: Object.entries(this.fileProcessedBytes).map(([path17, processedBytes]) => ({
- path: path17,
- progress: processedBytes / this.fileSize[path17],
- lastSentProgress: ((this.fileUploadedBytes[path17] ?? 0) + (processedBytes - (this.fileUploadedBytes[path17] ?? 0)) * PROCESSING_PROGRESS_RATIO) / this.fileSize[path17]
+ files: Object.entries(this.fileProcessedBytes).map(([path16, processedBytes]) => ({
+ path: path16,
+ progress: processedBytes / this.fileSize[path16],
+ lastSentProgress: ((this.fileUploadedBytes[path16] ?? 0) + (processedBytes - (this.fileUploadedBytes[path16] ?? 0)) * PROCESSING_PROGRESS_RATIO) / this.fileSize[path16]
}))
};
}
@@ -14826,7 +14826,7 @@ var BucketClient = class {
if (paths.length === 0) {
return;
}
- await this.batch(paths.map((path17) => ({ type: "deleteFile", path: path17 })));
+ await this.batch(paths.map((path16) => ({ type: "deleteFile", path: path16 })));
}
async batch(operations) {
const body = `${operations.map((op) => JSON.stringify(op)).join("\n")}
@@ -14842,8 +14842,8 @@ var BucketClient = class {
* any other failure (including bucket/auth errors), so a missing object is
* never conflated with an unreachable bucket.
*/
- async downloadFile(path17) {
- const url = `${this.hubUrl}/buckets/${this.bucket}/resolve/${encodeURIComponent(path17)}`;
+ async downloadFile(path16) {
+ const url = `${this.hubUrl}/buckets/${this.bucket}/resolve/${encodeURIComponent(path16)}`;
const response = await this.fetchWithRetry(url);
if (response.status === 404) {
await this.assertBucketAccessible();
@@ -14945,19 +14945,19 @@ var HubApi = class {
async deploymentControlStore(owner, deploymentId) {
const repoId = `${owner}/mlclaw-control-${deploymentId.replaceAll("-", "")}`;
await this.ensurePrivateModelRepo(repoId);
- const path17 = "control-lease.json";
+ const path16 = "control-lease.json";
return {
- read: async () => await this.readModelDocument(repoId, path17),
- compareAndSwap: async (expectedRevision, value) => await this.commitModelDocument(repoId, path17, expectedRevision, value)
+ read: async () => await this.readModelDocument(repoId, path16),
+ compareAndSwap: async (expectedRevision, value) => await this.commitModelDocument(repoId, path16, expectedRevision, value)
};
}
async deploymentClaimStore(owner) {
const repoId = `${owner}/mlclaw-control-claims`;
await this.ensurePrivateModelRepo(repoId);
- const path17 = "control-lease.json";
+ const path16 = "control-lease.json";
return {
- read: async () => await this.readModelDocument(repoId, path17),
- compareAndSwap: async (expectedRevision, value) => await this.commitModelDocument(repoId, path17, expectedRevision, value)
+ read: async () => await this.readModelDocument(repoId, path16),
+ compareAndSwap: async (expectedRevision, value) => await this.commitModelDocument(repoId, path16, expectedRevision, value)
};
}
async createDockerSpace(repoId, options) {
@@ -15185,9 +15185,9 @@ var HubApi = class {
encoding: "base64"
}
})),
- ...(params.deletePaths ?? []).map((path17) => ({
+ ...(params.deletePaths ?? []).map((path16) => ({
key: "deletedFile",
- value: { path: path17 }
+ value: { path: path16 }
}))
].map((entry) => JSON.stringify(entry)).join("\n");
await this.request(`/api/spaces/${repoId}/commit/${encodeURIComponent(params.branch ?? "main")}`, {
@@ -15217,10 +15217,10 @@ var HubApi = class {
if (info.sha) return;
await this.commitModelDocument(repoId, "README.md", "", "# ML Claw deployment control\n");
}
- async readModelDocument(repoId, path17) {
+ async readModelDocument(repoId, path16) {
const info = await this.requestJson(`/api/models/${repoId}`);
if (!info.sha) throw new Error(`control repository ${repoId} has no revision`);
- const url = `${this.hubUrl}/${repoId}/resolve/${info.sha}/${path17.split("/").map(encodeURIComponent).join("/")}`;
+ const url = `${this.hubUrl}/${repoId}/resolve/${info.sha}/${path16.split("/").map(encodeURIComponent).join("/")}`;
const response = await this.fetchImpl(url, {
headers: { Authorization: `Bearer ${this.token}` }
});
@@ -15228,16 +15228,16 @@ var HubApi = class {
if (!response.ok) throw new HubApiError2(response.status, url, await response.text());
return { value: JSON.parse(await response.text()), revision: info.sha };
}
- async commitModelDocument(repoId, path17, parentCommit, value) {
+ async commitModelDocument(repoId, path16, parentCommit, value) {
const header = {
summary: value === null ? "Release deployment control" : "Update deployment control",
description: "ML Claw deployment reconciliation state"
};
if (parentCommit) header.parentCommit = parentCommit;
- const operation = value === null ? { key: "deletedFile", value: { path: path17 } } : {
+ const operation = value === null ? { key: "deletedFile", value: { path: path16 } } : {
key: "file",
value: {
- path: path17,
+ path: path16,
content: Buffer.from(typeof value === "string" ? value : `${JSON.stringify(value, null, 2)}
`).toString(
"base64"
@@ -15381,21 +15381,22 @@ function nextLink(header) {
return null;
}
+// src/mlclaw/release-config.generated.ts
+var RELEASE_CONFIG = {
+ "packageVersion": "0.4.8",
+ "openclawVersion": "2026.7.1",
+ "brokerkitVersion": "hf-broker/v0.4.2",
+ "brokerkitPluginVersion": "0.3.4",
+ "runtimeImageRepository": "ghcr.io/huggingface/mlclaw"
+};
+
// src/mlclaw/runtime-image.ts
-import fs12 from "node:fs";
-import path13 from "node:path";
-import { fileURLToPath as fileURLToPath2 } from "node:url";
-var DEFAULT_OPENCLAW_VERSION = "2026.7.1";
-var DEFAULT_BROKERKIT_PLUGIN_VERSION = "0.3.3";
-var DEFAULT_BROKERKIT_VERSION = "hf-broker/v0.4.0";
-var DEFAULT_RUNTIME_IMAGE_REPOSITORY = "ghcr.io/huggingface/mlclaw";
-var PACKAGE_METADATA = readPackageMetadata();
-var PACKAGE_VERSION = packageString("version", "unknown");
-var OPENCLAW_VERSION = packageConfigString("openclawVersion", DEFAULT_OPENCLAW_VERSION);
+var PACKAGE_VERSION = RELEASE_CONFIG.packageVersion;
+var OPENCLAW_VERSION = RELEASE_CONFIG.openclawVersion;
var OPENCLAW_BASE_IMAGE = `ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}`;
-var BROKERKIT_PLUGIN_VERSION = packageConfigString("brokerkitPluginVersion", DEFAULT_BROKERKIT_PLUGIN_VERSION);
-var BROKERKIT_VERSION = packageConfigString("brokerkitVersion", DEFAULT_BROKERKIT_VERSION);
-var RUNTIME_IMAGE_REPOSITORY = packageConfigString("runtimeImageRepository", DEFAULT_RUNTIME_IMAGE_REPOSITORY);
+var BROKERKIT_PLUGIN_VERSION = RELEASE_CONFIG.brokerkitPluginVersion;
+var BROKERKIT_VERSION = RELEASE_CONFIG.brokerkitVersion;
+var RUNTIME_IMAGE_REPOSITORY = RELEASE_CONFIG.runtimeImageRepository;
var DEFAULT_RUNTIME_IMAGE_TAG = `${PACKAGE_VERSION}-openclaw-${OPENCLAW_VERSION}`;
var DEFAULT_RUNTIME_IMAGE = `${RUNTIME_IMAGE_REPOSITORY}:${DEFAULT_RUNTIME_IMAGE_TAG}`;
function resolveRuntimeImage(value, env = process.env) {
@@ -15413,45 +15414,16 @@ function resolveSpaceRuntimeImage(opts, env = process.env) {
function bundledSpaceRuntimeRef(templateRev) {
return `bundled:${templateRev}`;
}
-function packageString(key, fallback) {
- const value = PACKAGE_METADATA[key];
- return typeof value === "string" && value.trim() ? value.trim() : fallback;
-}
-function packageConfigString(key, fallback) {
- const value = PACKAGE_METADATA.config?.[key];
- return typeof value === "string" && value.trim() ? value.trim() : fallback;
-}
-function readPackageMetadata() {
- let dir = path13.dirname(fileURLToPath2(import.meta.url));
- while (true) {
- const candidate = path13.join(dir, "package.json");
- try {
- return JSON.parse(fs12.readFileSync(candidate, "utf8"));
- } catch (err) {
- if (!isMissingFileError(err)) {
- throw err;
- }
- }
- const parent = path13.dirname(dir);
- if (parent === dir) {
- throw new Error("could not find package.json while resolving default runtime image");
- }
- dir = parent;
- }
-}
-function isMissingFileError(err) {
- return err instanceof Error && "code" in err && err.code === "ENOENT";
-}
// src/mlclaw/git.ts
var execFileAsync2 = promisify2(execFile2);
async function pushTemplateToSpace(params) {
- const tempRoot = await fs13.mkdtemp(path14.join(os5.tmpdir(), "mlclaw-space-"));
+ const tempRoot = await fs12.mkdtemp(path13.join(os5.tmpdir(), "mlclaw-space-"));
try {
const sourceDir = params.sourceDir ?? process.env.MLCLAW_SOURCE_DIR ?? await findPackagedSourceRoot();
const templateRev = await currentTemplateRev(sourceDir);
- const outDir = path14.join(tempRoot, "space");
- await fs13.mkdir(outDir, { recursive: true });
+ const outDir = path13.join(tempRoot, "space");
+ await fs12.mkdir(outDir, { recursive: true });
await generateSpaceRepo(sourceDir, outDir, {
...params.runtimeImage ? { runtimeImage: params.runtimeImage } : {}
});
@@ -15469,7 +15441,7 @@ async function pushTemplateToSpace(params) {
});
return { templateRev };
} finally {
- await fs13.rm(tempRoot, { recursive: true, force: true });
+ await fs12.rm(tempRoot, { recursive: true, force: true });
}
}
async function currentTemplateRev(sourceDir) {
@@ -15482,7 +15454,7 @@ async function currentTemplateRev(sourceDir) {
}
} catch {
}
- const pkg = JSON.parse(await fs13.readFile(path14.join(sourceDir, "package.json"), "utf8"));
+ const pkg = JSON.parse(await fs12.readFile(path13.join(sourceDir, "package.json"), "utf8"));
return `npm:${pkg.name ?? "mlclaw"}@${pkg.version ?? "unknown"}`;
}
async function generateSpaceRepo(sourceDir, outDir, options = {}) {
@@ -15508,13 +15480,13 @@ async function generateSpaceRepo(sourceDir, outDir, options = {}) {
);
}
for (const [from, to] of copies) {
- await copyExisting(path14.join(sourceDir, from), path14.join(outDir, to));
+ await copyExisting(path13.join(sourceDir, from), path13.join(outDir, to));
}
- const hfLogoPng = await fs13.readFile(path14.join(sourceDir, "assets/hf-logo.png"));
- await fs13.writeFile(path14.join(outDir, "assets/hf-logo.png.base64"), `${hfLogoPng.toString("base64")}
+ const hfLogoPng = await fs12.readFile(path13.join(sourceDir, "assets/hf-logo.png"));
+ await fs12.writeFile(path13.join(outDir, "assets/hf-logo.png.base64"), `${hfLogoPng.toString("base64")}
`, "utf8");
- await fs13.writeFile(
- path14.join(outDir, "Dockerfile"),
+ await fs12.writeFile(
+ path13.join(outDir, "Dockerfile"),
options.runtimeImage ? imageDockerfile(options.runtimeImage) : bundledDockerfile(),
"utf8"
);
@@ -15602,13 +15574,13 @@ CMD ["/app/entrypoint.sh"]
`;
}
async function findPackagedSourceRoot() {
- const start = path14.dirname(fileURLToPath3(import.meta.url));
+ const start = path13.dirname(fileURLToPath2(import.meta.url));
let dir = start;
while (true) {
if (await hasPackagedSourceFiles(dir)) {
return dir;
}
- const parent = path14.dirname(dir);
+ const parent = path13.dirname(dir);
if (parent === dir) {
throw new Error("Could not find packaged ML Claw source files. Reinstall the mlclaw npm package.");
}
@@ -15625,20 +15597,20 @@ async function hasPackagedSourceFiles(dir) {
"src/hf-bucket-client/client.ts"
];
try {
- await Promise.all(required.map((file) => fs13.access(path14.join(dir, file))));
+ await Promise.all(required.map((file) => fs12.access(path13.join(dir, file))));
return true;
} catch {
return false;
}
}
async function copyExisting(from, to) {
- const stat = await fs13.stat(from);
- await fs13.mkdir(path14.dirname(to), { recursive: true });
+ const stat = await fs12.stat(from);
+ await fs12.mkdir(path13.dirname(to), { recursive: true });
if (stat.isDirectory()) {
- await fs13.cp(from, to, { recursive: true });
+ await fs12.cp(from, to, { recursive: true });
} else {
- await fs13.copyFile(from, to);
- await fs13.chmod(to, stat.mode);
+ await fs12.copyFile(from, to);
+ await fs12.chmod(to, stat.mode);
}
}
async function readFilesForCommit(root) {
@@ -15646,24 +15618,24 @@ async function readFilesForCommit(root) {
for (const relativePath of await listFiles(root)) {
files.push({
path: relativePath,
- content: await fs13.readFile(path14.join(root, relativePath))
+ content: await fs12.readFile(path13.join(root, relativePath))
});
}
return files;
}
async function listFiles(root, dir = "") {
- const absoluteDir = path14.join(root, dir);
- const entries = await fs13.readdir(absoluteDir, { withFileTypes: true });
+ const absoluteDir = path13.join(root, dir);
+ const entries = await fs12.readdir(absoluteDir, { withFileTypes: true });
const files = [];
for (const entry of entries) {
- const relativePath = path14.posix.join(dir.split(path14.sep).join(path14.posix.sep), entry.name);
- const absolutePath = path14.join(root, relativePath);
+ const relativePath = path13.posix.join(dir.split(path13.sep).join(path13.posix.sep), entry.name);
+ const absolutePath = path13.join(root, relativePath);
if (entry.isDirectory()) {
files.push(...await listFiles(root, relativePath));
} else if (entry.isFile()) {
files.push(relativePath);
} else {
- const stat = await fs13.stat(absolutePath);
+ const stat = await fs12.stat(absolutePath);
if (stat.isFile()) {
files.push(relativePath);
}
@@ -15742,9 +15714,9 @@ function deriveLocalAccessToken(sessionSecret) {
}
// src/mlclaw/local-config.ts
-import fs14 from "node:fs/promises";
+import fs13 from "node:fs/promises";
import os6 from "node:os";
-import path15 from "node:path";
+import path14 from "node:path";
import { createHash as createHash2 } from "node:crypto";
// node_modules/zod/v3/external.js
@@ -16225,8 +16197,8 @@ function getErrorMap() {
// node_modules/zod/v3/helpers/parseUtil.js
var makeIssue = (params) => {
- const { data, path: path17, errorMaps, issueData } = params;
- const fullPath = [...path17, ...issueData.path || []];
+ const { data, path: path16, errorMaps, issueData } = params;
+ const fullPath = [...path16, ...issueData.path || []];
const fullIssue = {
...issueData,
path: fullPath
@@ -16342,11 +16314,11 @@ var errorUtil;
// node_modules/zod/v3/types.js
var ParseInputLazyPath = class {
- constructor(parent, value, path17, key) {
+ constructor(parent, value, path16, key) {
this._cachedPath = [];
this.parent = parent;
this.data = value;
- this._path = path17;
+ this._path = path16;
this._key = key;
}
get path() {
@@ -19852,7 +19824,7 @@ var manifestFields = {
model: external_exports.string().min(1).max(512),
runtimeImage: external_exports.string().min(1).max(1024),
brokerCredential: external_exports.object({
- profileId: external_exports.literal("hf-broker-complete-v1"),
+ credentialKind: external_exports.literal("fine_grained_user_token"),
account: external_exports.string().min(1).max(128),
fingerprintSha256: external_exports.string().regex(/^[a-f0-9]{64}$/),
verifiedAt: external_exports.string().datetime()
@@ -19884,24 +19856,24 @@ function defaultConfigRoot(env = process.env) {
}
const xdg = env.XDG_CONFIG_HOME?.trim();
if (xdg) {
- return path15.join(xdg, "mlclaw");
+ return path14.join(xdg, "mlclaw");
}
- return path15.join(os6.homedir(), ".config", "mlclaw");
+ return path14.join(os6.homedir(), ".config", "mlclaw");
}
function localConfigPaths(root) {
return {
root,
- deploymentsDir: path15.join(root, "deployments"),
- secretsDir: path15.join(root, "secrets"),
- operationsDir: path15.join(root, "operations"),
- locksDir: path15.join(root, "locks")
+ deploymentsDir: path14.join(root, "deployments"),
+ secretsDir: path14.join(root, "secrets"),
+ operationsDir: path14.join(root, "operations"),
+ locksDir: path14.join(root, "locks")
};
}
function manifestPath(root, agent) {
- return path15.join(localConfigPaths(root).deploymentsDir, `${assertAgentName(agent)}.json`);
+ return path14.join(localConfigPaths(root).deploymentsDir, `${assertAgentName(agent)}.json`);
}
function secretEnvPath(root, agent) {
- return path15.join(localConfigPaths(root).secretsDir, `${assertAgentName(agent)}.env`);
+ return path14.join(localConfigPaths(root).secretsDir, `${assertAgentName(agent)}.env`);
}
async function writeManifest(root, input) {
const manifest = input.version === 1 ? importLegacyManifest(legacyManifestSchema.parse(input)) : manifestSchema.parse(input);
@@ -19911,7 +19883,7 @@ async function writeManifest(root, input) {
}
async function readManifest(root, agent) {
const file = manifestPath(root, agent);
- const raw = JSON.parse(await fs14.readFile(file, "utf8"));
+ const raw = JSON.parse(await fs13.readFile(file, "utf8"));
const version = raw && typeof raw === "object" && "version" in raw ? raw.version : void 0;
const parsed = version === 1 ? legacyManifestSchema.parse(raw) : manifestSchema.parse(raw);
if (parsed.version === 1) {
@@ -19924,7 +19896,7 @@ async function readManifest(root, agent) {
}
async function listManifests(root) {
const dir = localConfigPaths(root).deploymentsDir;
- const entries = await fs14.readdir(dir, { withFileTypes: true }).catch((error) => {
+ const entries = await fs13.readdir(dir, { withFileTypes: true }).catch((error) => {
if (error.code === "ENOENT") return [];
throw error;
});
@@ -19935,7 +19907,7 @@ async function listManifests(root) {
}
async function manifestExists(root, agent) {
try {
- await fs14.access(manifestPath(root, agent));
+ await fs13.access(manifestPath(root, agent));
return true;
} catch {
return false;
@@ -19950,7 +19922,7 @@ async function writeSecretEnv(root, agent, values) {
await writePrivateFile(file, renderSecretEnv(values));
}
async function readSecretEnv(root, agent) {
- return parseSecretEnv(await fs14.readFile(secretEnvPath(root, agent), "utf8"));
+ return parseSecretEnv(await fs13.readFile(secretEnvPath(root, agent), "utf8"));
}
function parseSecretEnv(raw) {
const out = {};
@@ -19982,17 +19954,17 @@ function importLegacyManifest(manifest) {
return { ...manifest, version: 2, deploymentId, desiredGeneration: 0 };
}
async function writePrivateFile(file, content) {
- await fs14.mkdir(path15.dirname(file), { recursive: true, mode: 448 });
+ await fs13.mkdir(path14.dirname(file), { recursive: true, mode: 448 });
const temporary = `${file}.${process.pid}.${Date.now()}.tmp`;
- await fs14.writeFile(temporary, content, { encoding: "utf8", mode: 384, flag: "wx" });
- await fs14.rename(temporary, file);
- await fs14.chmod(file, 384);
+ await fs13.writeFile(temporary, content, { encoding: "utf8", mode: 384, flag: "wx" });
+ await fs13.rename(temporary, file);
+ await fs13.chmod(file, 384);
}
// src/mlclaw/deployment-state.ts
-import fs15 from "node:fs/promises";
+import fs14 from "node:fs/promises";
import os7 from "node:os";
-import path16 from "node:path";
+import path15 from "node:path";
import { randomUUID } from "node:crypto";
var DEPLOYMENT_PATH = ".mlclaw/deployment.json";
var DESIRED_STATE_PATH = ".mlclaw/desired-state.json";
@@ -20139,7 +20111,7 @@ function newOperation(manifest, now) {
}
async function writeOperation(root, client, operation) {
const parsed = operationSchema.parse(operation);
- const local = path16.join(localConfigPaths(root).operationsDir, `${parsed.operationId}.json`);
+ const local = path15.join(localConfigPaths(root).operationsDir, `${parsed.operationId}.json`);
await atomicPrivateWrite(local, stringify(parsed));
await client.uploadFiles([jsonBlob(`.mlclaw/operations/${parsed.operationId}.json`, parsed)]);
}
@@ -20155,13 +20127,13 @@ async function updateOperation(root, client, operation, state, now, detail) {
}
async function readResumableOperation(root, deploymentId, targetGeneration) {
const directory = localConfigPaths(root).operationsDir;
- const entries = await fs15.readdir(directory, { withFileTypes: true }).catch((error) => {
+ const entries = await fs14.readdir(directory, { withFileTypes: true }).catch((error) => {
if (error.code === "ENOENT") return [];
throw error;
});
const operations = await Promise.all(
entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => {
- const raw = await fs15.readFile(path16.join(directory, entry.name), "utf8");
+ const raw = await fs14.readFile(path15.join(directory, entry.name), "utf8");
return operationSchema.parse(JSON.parse(raw));
})
);
@@ -20170,12 +20142,12 @@ async function readResumableOperation(root, deploymentId, targetGeneration) {
).sort((a, b2) => b2.updatedAt.localeCompare(a.updatedAt))[0] ?? null;
}
async function withDeploymentLock(root, deploymentId, task) {
- const file = path16.join(localConfigPaths(root).locksDir, `${deploymentId}.lock`);
- await fs15.mkdir(path16.dirname(file), { recursive: true, mode: 448 });
+ const file = path15.join(localConfigPaths(root).locksDir, `${deploymentId}.lock`);
+ await fs14.mkdir(path15.dirname(file), { recursive: true, mode: 448 });
const token = randomUUID();
const lock = stringify({ pid: process.pid, host: os7.hostname(), token, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
try {
- await fs15.writeFile(file, lock, { flag: "wx", mode: 384 });
+ await fs14.writeFile(file, lock, { flag: "wx", mode: 384 });
} catch (error) {
if (error.code !== "EEXIST") throw error;
if (!await replaceStaleLocalLock(file, lock)) {
@@ -20198,38 +20170,38 @@ async function withDeploymentLock(root, deploymentId, task) {
async function replaceStaleLocalLock(file, replacement) {
const guard = `${file}.reclaim`;
try {
- await fs15.mkdir(guard);
+ await fs14.mkdir(guard);
} catch (error) {
if (error.code === "EEXIST") return false;
throw error;
}
try {
- const [raw, stat] = await Promise.all([fs15.readFile(file, "utf8"), fs15.stat(file)]);
+ const [raw, stat] = await Promise.all([fs14.readFile(file, "utf8"), fs14.stat(file)]);
const value = JSON.parse(raw);
if (value.host !== os7.hostname() || typeof value.pid !== "number") return false;
const createdAt = typeof value.createdAt === "string" ? Date.parse(value.createdAt) : Number.NaN;
const lastRefresh = Number.isFinite(createdAt) ? Math.max(createdAt, stat.mtimeMs) : stat.mtimeMs;
if (processIsAlive(value.pid) && Date.now() - lastRefresh <= LOCAL_LOCK_STALE_MS) return false;
- await fs15.rm(file);
- await fs15.writeFile(file, replacement, { flag: "wx", mode: 384 });
+ await fs14.rm(file);
+ await fs14.writeFile(file, replacement, { flag: "wx", mode: 384 });
return true;
} catch {
return false;
} finally {
- await fs15.rm(guard, { recursive: true, force: true });
+ await fs14.rm(guard, { recursive: true, force: true });
}
}
async function refreshOwnedLocalLock(file, token) {
if (!await localLockHasToken(file, token)) return;
const now = /* @__PURE__ */ new Date();
- await fs15.utimes(file, now, now);
+ await fs14.utimes(file, now, now);
}
async function removeOwnedLocalLock(file, token) {
- if (await localLockHasToken(file, token)) await fs15.rm(file, { force: true });
+ if (await localLockHasToken(file, token)) await fs14.rm(file, { force: true });
}
async function localLockHasToken(file, token) {
try {
- const value = JSON.parse(await fs15.readFile(file, "utf8"));
+ const value = JSON.parse(await fs14.readFile(file, "utf8"));
return value.token === token;
} catch {
return false;
@@ -20295,19 +20267,19 @@ async function readDocument(client, file, schema) {
if (blob.size > MAX_CONTROL_BYTES) throw new Error(`${file} exceeds ${MAX_CONTROL_BYTES} bytes`);
return schema.parse(JSON.parse(await blob.text()));
}
-function jsonBlob(path17, value) {
- return { path: path17, content: new Blob([stringify(value)], { type: "application/json" }) };
+function jsonBlob(path16, value) {
+ return { path: path16, content: new Blob([stringify(value)], { type: "application/json" }) };
}
function stringify(value) {
return `${JSON.stringify(value, null, 2)}
`;
}
async function atomicPrivateWrite(file, content) {
- await fs15.mkdir(path16.dirname(file), { recursive: true, mode: 448 });
+ await fs14.mkdir(path15.dirname(file), { recursive: true, mode: 448 });
const temporary = `${file}.${process.pid}.tmp`;
- await fs15.writeFile(temporary, content, { mode: 384, flag: "wx" });
- await fs15.rename(temporary, file);
- await fs15.chmod(file, 384);
+ await fs14.writeFile(temporary, content, { mode: 384, flag: "wx" });
+ await fs14.rename(temporary, file);
+ await fs14.chmod(file, 384);
}
// src/mlclaw/telegram.ts
@@ -20347,116 +20319,13 @@ function delay(ms) {
// src/mlclaw/hf-broker-credential.ts
import { createHash as createHash3 } from "node:crypto";
-
-// src/mlclaw/hf-broker-credential-requirements.json
-var hf_broker_credential_requirements_default = {
- version: 1,
- profile_id: "hf-broker-complete-v1",
- token_form_url: "https://huggingface.co/settings/tokens/new",
- token_type: "fineGrained",
- requires_gated_repositories: true,
- personal_permissions: [
- "collection.read",
- "collection.write",
- "discussion.write",
- "inference.endpoints.infer.write",
- "inference.endpoints.write",
- "inference.serverless.write",
- "job.write",
- "repo.access.read",
- "repo.content.read",
- "repo.write",
- "sql-console.embed.write",
- "user.billing.read",
- "user.mcp.read",
- "user.notifications.read",
- "user.notifications.write",
- "user.papers.write",
- "user.preferences.write",
- "user.settings.notifications.write",
- "user.social.likes.write",
- "user.webhooks.read",
- "user.webhooks.write"
- ],
- global_permissions: [
- "discussion.write",
- "post.write"
- ],
- organization_permissions: [
- "collection.read",
- "collection.write",
- "discussion.write",
- "inference.endpoints.infer.write",
- "inference.endpoints.write",
- "inference.serverless.write",
- "job.write",
- "org.auditLog.write",
- "org.billing.read",
- "org.members.read",
- "org.members.write",
- "org.networkSecurity.read",
- "org.networkSecurity.write",
- "org.read",
- "org.repos.read",
- "org.serviceAccounts.read",
- "org.serviceAccounts.write",
- "org.write",
- "repo.access.read",
- "repo.content.read",
- "repo.write",
- "resourceGroup.write",
- "sql-console.embed.write"
- ]
-};
-
-// src/mlclaw/hf-broker-credential.ts
-var permissionListSchema = external_exports.array(external_exports.string().min(1)).min(1).superRefine((permissions, context) => {
- if (permissions.some((permission) => permission !== permission.trim())) {
- context.addIssue({ code: external_exports.ZodIssueCode.custom, message: "permissions must not contain outer whitespace" });
- }
- if (new Set(permissions).size !== permissions.length) {
- context.addIssue({ code: external_exports.ZodIssueCode.custom, message: "permissions must be unique" });
- }
- if (permissions.some((permission, index) => index > 0 && permission < permissions[index - 1])) {
- context.addIssue({ code: external_exports.ZodIssueCode.custom, message: "permissions must be sorted" });
- }
-});
-var profileSchema = external_exports.object({
- version: external_exports.literal(1),
- profile_id: external_exports.literal("hf-broker-complete-v1"),
- token_form_url: external_exports.literal("https://huggingface.co/settings/tokens/new"),
- token_type: external_exports.literal("fineGrained"),
- requires_gated_repositories: external_exports.literal(true),
- personal_permissions: permissionListSchema,
- global_permissions: permissionListSchema,
- organization_permissions: permissionListSchema
-}).strict();
-var BROKER_CREDENTIAL_PROFILE = Object.freeze(profileSchema.parse(hf_broker_credential_requirements_default));
-var HF_TOKEN_CREATE_URL = BROKER_CREDENTIAL_PROFILE.token_form_url;
-var BROKER_PERSONAL_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.personal_permissions;
-var BROKER_GLOBAL_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.global_permissions;
-var BROKER_ORGANIZATION_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.organization_permissions;
-function buildBrokerTokenUrl(owner, accountName) {
- const url = new URL(HF_TOKEN_CREATE_URL);
- url.searchParams.set("tokenType", BROKER_CREDENTIAL_PROFILE.token_type);
- for (const permission of BROKER_PERSONAL_PERMISSIONS) {
- url.searchParams.append("ownUserPermissions", permission);
- }
- for (const permission of BROKER_GLOBAL_PERMISSIONS) {
- url.searchParams.append("globalPermissions", permission);
- }
- url.searchParams.set("canReadGatedRepos", String(BROKER_CREDENTIAL_PROFILE.requires_gated_repositories));
- if (owner !== accountName) {
- url.searchParams.append("orgs", owner);
- for (const permission of BROKER_ORGANIZATION_PERMISSIONS) {
- url.searchParams.append("orgPermissions", permission);
- }
- }
- return url.toString();
-}
-function assessBrokerCredential(identity, owner) {
+var HF_TOKEN_CREATE_URL = "https://huggingface.co/settings/tokens/new?tokenType=fineGrained";
+function buildBrokerTokenUrl() {
+ return HF_TOKEN_CREATE_URL;
+}
+function assessBrokerCredential(identity) {
const accessToken = identity.auth?.accessToken;
- if (accessToken?.role !== BROKER_CREDENTIAL_PROFILE.token_type) {
+ if (accessToken?.role !== "fineGrained") {
return {
status: "unsupported",
reason: "HF Broker requires a dedicated fine-grained Hugging Face token"
@@ -20468,40 +20337,16 @@ function assessBrokerCredential(identity, owner) {
reason: "Hugging Face omitted this fine-grained token's permission details"
};
}
- const personalAvailable = new Set(scopedPermissions(accessToken.fineGrained.scoped, "user", identity.name));
- const globalAvailable = new Set(accessToken.fineGrained.global);
- const missing = BROKER_PERSONAL_PERMISSIONS.filter((permission) => !personalAvailable.has(permission));
- missing.push(
- ...BROKER_GLOBAL_PERMISSIONS.filter((permission) => !globalAvailable.has(permission)).map(
- (permission) => `global:${permission}`
- )
- );
- if (!accessToken.fineGrained.canReadGatedRepos) {
- missing.push("canReadGatedRepos");
- }
- if (owner !== identity.name) {
- const organizationAvailable = new Set(scopedPermissions(accessToken.fineGrained.scoped, "org", owner));
- missing.push(
- ...BROKER_ORGANIZATION_PERMISSIONS.filter((permission) => !organizationAvailable.has(permission)).map(
- (permission) => `org:${permission}`
- )
- );
- }
- missing.sort();
- return missing.length === 0 ? { status: "sufficient" } : { status: "insufficient", missing };
+ return { status: "sufficient" };
}
function brokerCredentialMetadata(token, identity, verifiedAt) {
return {
- profileId: BROKER_CREDENTIAL_PROFILE.profile_id,
+ credentialKind: "fine_grained_user_token",
account: identity.name,
fingerprintSha256: createHash3("sha256").update(token).digest("hex"),
verifiedAt: verifiedAt.toISOString()
};
}
-function scopedPermissions(scopes, type, name) {
- if (!Array.isArray(scopes)) return [];
- return scopes.filter((scope) => scope.entity.type === type && (!scope.entity.name || scope.entity.name === name)).flatMap((scope) => scope.permissions);
-}
// src/mlclaw/tailscale.ts
import { execFile as execFile3 } from "node:child_process";
@@ -21492,7 +21337,6 @@ async function resolveBootstrapPlan(params) {
const existingSecrets = await readSecretEnv(runtime.configRoot, agentName).catch(() => ({}));
const brokerCredential = await resolveBrokerHfToken({
opts,
- owner,
hfIdentity,
...providedBrokerHfToken ? { preferredToken: providedBrokerHfToken } : {},
existingSecrets,
@@ -22236,7 +22080,7 @@ async function deployLocalBootstrap(plan, opts, runtime, desiredChanged = true,
await writeSecretEnv(runtime.configRoot, plan.agentName, previousSecrets);
} else {
await assertLease();
- await fs16.rm(secretEnvPath(runtime.configRoot, plan.agentName), { force: true });
+ await fs15.rm(secretEnvPath(runtime.configRoot, plan.agentName), { force: true });
}
if (previousContainer?.running && previousManifest) {
await startLocalGateway({ manifest: previousManifest, runtime, pull: false, refresh: true, assertLease });
@@ -22265,7 +22109,7 @@ async function deployLocalBootstrap(plan, opts, runtime, desiredChanged = true,
}
if (!previousManifest) {
await assertLease();
- await fs16.rm(manifestPath(runtime.configRoot, plan.agentName), { force: true });
+ await fs15.rm(manifestPath(runtime.configRoot, plan.agentName), { force: true });
}
} catch (rollbackError) {
throw new AggregateError([error, rollbackError], "local bootstrap and rollback both failed");
@@ -24015,7 +23859,7 @@ async function readOptionalTelegramToken(opts, runtime) {
return direct;
}
if (opts.telegramTokenFile) {
- const raw = await fs16.readFile(opts.telegramTokenFile, "utf8");
+ const raw = await fs15.readFile(opts.telegramTokenFile, "utf8");
const match = raw.match(/(?:^|\n)\s*TELEGRAM_BOT_TOKEN\s*=\s*['"]?([^'"\n]+)['"]?/);
return (match?.[1] ?? raw.trim()).trim();
}
@@ -24037,7 +23881,7 @@ async function readOptionalRouterTokenFile(file) {
if (!file) {
return void 0;
}
- const raw = await fs16.readFile(file, "utf8");
+ const raw = await fs15.readFile(file, "utf8");
const parsed = parseSecretEnv(raw);
return nonEmpty(parsed.MLCLAW_ROUTER_TOKEN) ?? nonEmpty(parsed.HF_ROUTER_TOKEN) ?? nonEmpty(raw);
}
@@ -24048,7 +23892,7 @@ async function credentialsStatus(requestedAgent, runtime) {
if (!metadata) throw new Error("verified HF Broker credential metadata is missing");
runtime.stdout.log(`Agent: ${manifest.agent}`);
runtime.stdout.log(`Status: healthy`);
- runtime.stdout.log(`Profile: ${metadata.profileId}`);
+ runtime.stdout.log(`Credential kind: ${metadata.credentialKind}`);
runtime.stdout.log(`Account: ${metadata.account}`);
runtime.stdout.log(`Fingerprint: ${metadata.fingerprintSha256.slice(0, 12)}`);
runtime.stdout.log(`Verified: ${metadata.verifiedAt}`);
@@ -24062,7 +23906,7 @@ async function verifiedStoredBrokerCredential(manifest, runtime) {
`HF Broker credential metadata is missing; run \`mlclaw credentials repair ${manifest.agent}\` to complete the cutover`
);
}
- const verified = await verifyBrokerHfToken(token, manifest.owner, manifest.brokerCredential.account, runtime);
+ const verified = await verifyBrokerHfToken(token, manifest.brokerCredential.account, runtime);
const observed = brokerCredentialMetadata(token, verified.identity, runtime.now());
if (observed.fingerprintSha256 !== manifest.brokerCredential.fingerprintSha256) {
throw new Error(
@@ -24082,14 +23926,14 @@ async function credentialsRepair(requestedAgent, opts, runtime) {
const suppliedToken = fileToken ?? nonEmpty(runtime.env.MLCLAW_BROKER_HF_TOKEN);
let replacement;
if (suppliedToken) {
- replacement = await verifyBrokerHfToken(suppliedToken, manifest.owner, account, runtime);
+ replacement = await verifyBrokerHfToken(suppliedToken, account, runtime);
} else {
if (!runtime.prompt.isInteractive()) {
throw new Error(
"credential repair requires --broker-hf-token-file, MLCLAW_BROKER_HF_TOKEN, or an interactive terminal"
);
}
- replacement = await promptForBrokerHfToken(manifest.owner, account, runtime);
+ replacement = await promptForBrokerHfToken(account, runtime);
}
const updatedManifest = {
...manifest,
@@ -24260,7 +24104,7 @@ async function resolveBrokerHfToken(params) {
const configuredToken = fileToken ?? environmentToken ?? nonEmpty(params.preferredToken) ?? nonEmpty(params.existingSecrets.MLCLAW_BROKER_HF_TOKEN);
if (configuredToken) {
try {
- return await verifyBrokerHfToken(configuredToken, params.owner, params.hfIdentity.name, params.runtime);
+ return await verifyBrokerHfToken(configuredToken, params.hfIdentity.name, params.runtime);
} catch (error) {
if (fileToken || environmentToken || params.preferredToken) throw error;
if (params.runtime.prompt.isInteractive()) {
@@ -24280,19 +24124,19 @@ async function resolveBrokerHfToken(params) {
"a dedicated HF Broker credential is required; set MLCLAW_BROKER_HF_TOKEN, pass --broker-hf-token-file, or run bootstrap interactively"
);
}
- return await promptForBrokerHfToken(params.owner, params.hfIdentity.name, params.runtime);
+ return await promptForBrokerHfToken(params.hfIdentity.name, params.runtime);
}
-async function promptForBrokerHfToken(owner, account, runtime) {
+async function promptForBrokerHfToken(account, runtime) {
runtime.prompt.note(
- "ML Claw will open a Hugging Face token form with BrokerKit's permissions preselected. Create a dedicated token and paste it here. Your current HF CLI login will not be changed.",
+ "ML Claw will open a Hugging Face fine-grained token form. Choose the permissions and resources this broker may use, create a dedicated token, and paste it here. Your current HF CLI login will not be changed.",
"HF Broker credential"
);
- const url = buildBrokerTokenUrl(owner, account);
+ const url = buildBrokerTokenUrl();
const opened = await runtime.hfCli.openUrl(url);
runtime.prompt.note(
`${opened ? "The token form was opened in your browser." : "Open this token form in your browser."}
-Name and create the token, then copy it. The URL contains permission names only; it contains no credential. The exact URL is printed below.`,
+Choose the permissions and resources, name and create the token, then copy it. The URL contains no credential. The exact URL is printed below.`,
"Create the broker token"
);
runtime.stdout.log(url);
@@ -24302,7 +24146,7 @@ Name and create the token, then copy it. The URL contains permission names only;
"Hugging Face broker token"
);
try {
- const verified = await verifyBrokerHfToken(replacement, owner, account, runtime);
+ const verified = await verifyBrokerHfToken(replacement, account, runtime);
runtime.prompt.note(
"The dedicated broker token was verified. It will be stored only in ML Claw's trusted broker configuration.",
"HF Broker credential ready"
@@ -24316,12 +24160,12 @@ Name and create the token, then copy it. The URL contains permission names only;
}
}
}
-async function verifyBrokerHfToken(token, owner, expectedAccount, runtime) {
+async function verifyBrokerHfToken(token, expectedAccount, runtime) {
const identity = await runtime.hubFactory(token).whoami();
if (identity.name !== expectedAccount) {
throw new Error(`broker token belongs to ${identity.name}, not ${expectedAccount}`);
}
- const assessment = assessBrokerCredential(identity, owner);
+ const assessment = assessBrokerCredential(identity);
if (assessment.status !== "sufficient") {
throw new Error(brokerCredentialAssessmentDetail(assessment));
}
@@ -24329,17 +24173,14 @@ async function verifyBrokerHfToken(token, owner, expectedAccount, runtime) {
}
async function readOptionalBrokerHfTokenFile(file) {
if (!file) return void 0;
- const raw = await fs16.readFile(file, "utf8");
+ const raw = await fs15.readFile(file, "utf8");
const parsed = parseSecretEnv(raw);
const token = nonEmpty(parsed.MLCLAW_BROKER_HF_TOKEN) ?? nonEmpty(raw);
if (!token) throw new Error("HF Broker token file is empty");
return token;
}
function brokerCredentialAssessmentDetail(assessment) {
- if (assessment.status === "unsupported") return assessment.reason;
- const shown = assessment.missing.slice(0, 8);
- const remaining = assessment.missing.length - shown.length;
- return `The HF Broker credential is missing ${assessment.missing.length} required permission${assessment.missing.length === 1 ? "" : "s"}: ${shown.join(", ")}${remaining > 0 ? `, and ${remaining} more` : ""}`;
+ return assessment.reason;
}
function errorMessage(error) {
return error instanceof Error ? error.message : String(error);
diff --git a/package-lock.json b/package-lock.json
index eb04b12..46d3ab7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "mlclaw",
- "version": "0.4.7",
+ "version": "0.4.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mlclaw",
- "version": "0.4.7",
+ "version": "0.4.8",
"license": "MIT",
"dependencies": {
"@clack/prompts": "^1.4.0",
@@ -15,6 +15,7 @@
"commander": "^14.0.3",
"hono": "^4.12.28",
"lucide-react": "^0.468.0",
+ "openclaw-brokerkit": "0.3.4",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"skillflag": "^0.2.0",
@@ -2062,6 +2063,337 @@
"node": ">=14"
}
},
+ "node_modules/@radix-ui/primitive": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz",
+ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz",
+ "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-dismissable-layer": "1.1.10",
+ "@radix-ui/react-focus-guards": "1.1.2",
+ "@radix-ui/react-focus-scope": "1.1.7",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-portal": "1.1.9",
+ "@radix-ui/react-presence": "1.1.4",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-slot": "1.2.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz",
+ "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-escape-keydown": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz",
+ "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
+ "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
+ "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz",
+ "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
+ "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
@@ -2780,7 +3112,7 @@
"version": "19.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
"integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -2790,7 +3122,7 @@
"version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^19.2.0"
@@ -3249,7 +3581,6 @@
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
@@ -3262,6 +3593,23 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
"node_modules/angular-html-parser": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-10.4.0.tgz",
@@ -3305,6 +3653,18 @@
"dev": true,
"license": "Python-2.0"
},
+ "node_modules/aria-hidden": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
+ "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/aria-query": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
@@ -3643,6 +4003,18 @@
"node": ">= 16"
}
},
+ "node_modules/class-variance-authority": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
+ "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "clsx": "^2.1.1"
+ },
+ "funding": {
+ "url": "https://polar.sh/cva"
+ }
+ },
"node_modules/cli-width": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
@@ -3653,6 +4025,15 @@
"node": ">= 12"
}
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -3729,7 +4110,7 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
+ "devOptional": true,
"license": "MIT"
},
"node_modules/data-urls": {
@@ -3810,6 +4191,12 @@
"minimalistic-assert": "^1.0.0"
}
},
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
+ "license": "MIT"
+ },
"node_modules/diff-match-patch": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
@@ -4281,7 +4668,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
"license": "MIT"
},
"node_modules/fast-fifo": {
@@ -4323,7 +4709,6 @@
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.3.tgz",
"integrity": "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -4513,6 +4898,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
@@ -5049,7 +5443,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
"license": "MIT"
},
"node_modules/json-stable-stringify-without-jsonify": {
@@ -5407,6 +5800,95 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/openclaw-brokerkit": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/openclaw-brokerkit/-/openclaw-brokerkit-0.3.4.tgz",
+ "integrity": "sha512-bR1mH5acLm5BWTZITqjqmIj8Eh2bh1bqbIwU7c2yWawOG7TPZhqdwIKDG6v27dU/Gwb44XxxTITKAtSprNxWGw==",
+ "dependencies": {
+ "@radix-ui/react-dialog": "1.1.14",
+ "ajv": "8.17.1",
+ "ajv-formats": "3.0.1",
+ "class-variance-authority": "0.7.1",
+ "clsx": "2.1.1",
+ "lucide-react": "0.525.0",
+ "react": "19.1.0",
+ "react-dom": "19.1.0",
+ "tailwind-merge": "3.3.0",
+ "zod": "4.0.5"
+ },
+ "engines": {
+ "node": ">=24.18.0 <25"
+ },
+ "peerDependencies": {
+ "openclaw": ">=2026.7.1"
+ },
+ "peerDependenciesMeta": {
+ "openclaw": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/openclaw-brokerkit/node_modules/ajv": {
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/openclaw-brokerkit/node_modules/lucide-react": {
+ "version": "0.525.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.525.0.tgz",
+ "integrity": "sha512-Tm1txJ2OkymCGkvwoHt33Y2JpN5xucVq1slHcgE6Lk0WjDfjgKWor5CdVER8U6DvcfMwh4M8XxmpTiyzfmfDYQ==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/openclaw-brokerkit/node_modules/react": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+ "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/openclaw-brokerkit/node_modules/react-dom": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.26.0"
+ },
+ "peerDependencies": {
+ "react": "^19.1.0"
+ }
+ },
+ "node_modules/openclaw-brokerkit/node_modules/scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
+ },
+ "node_modules/openclaw-brokerkit/node_modules/zod": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.0.5.tgz",
+ "integrity": "sha512-/5UuuRPStvHXu7RS+gmvRf4NXrNxpSllGwDnCBcJZtQsKrviYXm54yDGV2KYNLT5kq0lHGcl7lqWJLgSaG+tgA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -5771,11 +6253,79 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-remove-scroll": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
+ "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
+ "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
+ "license": "MIT",
+ "dependencies": {
+ "react-style-singleton": "^2.2.2",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
+ "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -6263,6 +6813,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/tailwind-merge": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.0.tgz",
+ "integrity": "sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
"node_modules/tar-stream": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz",
@@ -6442,7 +7002,6 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "dev": true,
"license": "0BSD"
},
"node_modules/tunnel": {
@@ -6611,6 +7170,49 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/use-callback-ref": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
+ "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
+ "license": "MIT",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-sidecar": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+ "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/vite": {
"version": "7.3.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
diff --git a/package.json b/package.json
index 6413290..c0ee614 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
{
"name": "mlclaw",
- "version": "0.4.7",
+ "version": "0.4.8",
"license": "MIT",
"config": {
"openclawVersion": "2026.7.1",
- "brokerkitVersion": "hf-broker/v0.4.0",
- "brokerkitPluginVersion": "0.3.3",
+ "brokerkitVersion": "hf-broker/v0.4.2",
+ "brokerkitPluginVersion": "0.3.4",
"runtimeImageRepository": "ghcr.io/huggingface/mlclaw"
},
"repository": {
@@ -55,16 +55,19 @@
"pack:check": "node scripts/check-package.mjs",
"prepack": "npm run build",
"check:secrets": "node scripts/check-secrets.mjs",
- "format": "prettier --check eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw/auth.ts src/mlclaw/cli.ts src/mlclaw/deployment-state.ts src/mlclaw/docker.ts src/mlclaw/hf-broker-credential.ts src/mlclaw/hf-cli.ts src/mlclaw/hub-api.ts src/mlclaw/local-config.ts src/mlclaw/tailscale.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/local-access.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/proxy.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/session.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.auth.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.cli.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.deployment-state.test.ts test/mlclaw.docker.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.hf-broker-credential.test.ts test/mlclaw.hub-api.test.ts test/mlclaw.local-config.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts test/mlclaw.tailscale.test.ts docs/operator-brokers-config.md",
- "format:write": "prettier --write eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw/auth.ts src/mlclaw/cli.ts src/mlclaw/deployment-state.ts src/mlclaw/docker.ts src/mlclaw/hf-broker-credential.ts src/mlclaw/hf-cli.ts src/mlclaw/hub-api.ts src/mlclaw/local-config.ts src/mlclaw/tailscale.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/local-access.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/proxy.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/session.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.auth.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.cli.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.deployment-state.test.ts test/mlclaw.docker.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.hf-broker-credential.test.ts test/mlclaw.hub-api.test.ts test/mlclaw.local-config.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts test/mlclaw.tailscale.test.ts docs/operator-brokers-config.md",
+ "format": "prettier --check eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md scripts/sync-release-config.mjs src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw/auth.ts src/mlclaw/cli.ts src/mlclaw/deployment-state.ts src/mlclaw/docker.ts src/mlclaw/hf-broker-credential.ts src/mlclaw/hf-cli.ts src/mlclaw/hub-api.ts src/mlclaw/local-config.ts src/mlclaw/tailscale.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/local-access.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/proxy.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/session.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.auth.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.cli.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.deployment-state.test.ts test/mlclaw.docker.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.hf-broker-credential.test.ts test/mlclaw.hub-api.test.ts test/mlclaw.local-config.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts test/mlclaw.tailscale.test.ts docs/operator-brokers-config.md",
+ "format:write": "prettier --write eslint.config.mjs vitest.config.ts vitest.stryker.config.ts package.json README.md scripts/sync-release-config.mjs src/hf-state-sync/archive.ts src/hf-state-sync/cli.ts src/hf-state-sync/paths.ts src/hf-state-sync/prepare.ts src/hf-state-sync/stage-worker.ts src/hf-state-sync/supervise.ts src/mlclaw/auth.ts src/mlclaw/cli.ts src/mlclaw/deployment-state.ts src/mlclaw/docker.ts src/mlclaw/hf-broker-credential.ts src/mlclaw/hf-cli.ts src/mlclaw/hub-api.ts src/mlclaw/local-config.ts src/mlclaw/tailscale.ts src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts src/mlclaw-space-runtime/app.ts src/mlclaw-space-runtime/config.ts src/mlclaw-space-runtime/local-access.ts src/mlclaw-space-runtime/openai-credentials.ts src/mlclaw-space-runtime/proxy.ts src/mlclaw-space-runtime/server.ts src/mlclaw-space-runtime/session.ts src/mlclaw-space-runtime/shell.ts src/mlclaw-control-ui/src/main.tsx src/mlclaw-control-ui/src/styles.css src/mlclaw-control-ui/src/components/ui/utils.ts src/mlclaw/git.ts test/hf-state-sync.archive.test.ts test/hf-state-sync.roundtrip.test.ts test/hf-state-sync.supervise.test.ts test/mlclaw.auth.test.ts test/mlclaw.brokerkit-agent-tools.test.ts test/mlclaw.bundle.test.ts test/mlclaw.cli.test.ts test/mlclaw.delegated-brokerkit.test.ts test/mlclaw.deployment-state.test.ts test/mlclaw.docker.test.ts test/mlclaw.generate-space.test.ts test/mlclaw.hf-broker-credential.test.ts test/mlclaw.hub-api.test.ts test/mlclaw.local-config.test.ts test/mlclaw.operator-brokers.test.ts test/mlclaw.runtime-image.test.ts test/mlclaw.space-runtime.test.ts test/mlclaw.tailscale.test.ts docs/operator-brokers-config.md",
"lint": "eslint --max-warnings 0 src/mlclaw-space-runtime/delegated-brokerkit.ts src/mlclaw-space-runtime/delegated-revisions.ts src/mlclaw-space-runtime/operator-brokers.ts src/mlclaw-space-runtime/openclaw-config.ts",
"coverage": "vitest run --coverage",
"dry": "slophammer-ts dry .",
"mutate": "stryker run --dryRunOnly",
"slophammer": "slophammer-ts check .",
- "check": "npm run format && npm run lint && npm run typecheck && npm test && npm run coverage && npm run build && npm run check:secrets && npm run pack:check && npm run dry && npm run slophammer",
+ "check": "npm run release:check && npm run format && npm run lint && npm run typecheck && npm test && npm run coverage && npm run build && npm run check:secrets && npm run pack:check && npm run dry && npm run slophammer",
"test": "vitest run",
- "typecheck": "tsc --noEmit"
+ "typecheck": "tsc --noEmit",
+ "release:check": "node scripts/sync-release-config.mjs --check",
+ "release:sync": "node scripts/sync-release-config.mjs",
+ "version": "npm run release:sync"
},
"dependencies": {
"@clack/prompts": "^1.4.0",
@@ -73,6 +76,7 @@
"commander": "^14.0.3",
"hono": "^4.12.28",
"lucide-react": "^0.468.0",
+ "openclaw-brokerkit": "0.3.4",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"skillflag": "^0.2.0",
diff --git a/scripts/sync-release-config.mjs b/scripts/sync-release-config.mjs
new file mode 100644
index 0000000..3bb4301
--- /dev/null
+++ b/scripts/sync-release-config.mjs
@@ -0,0 +1,82 @@
+import fs from "node:fs";
+import path from "node:path";
+import process from "node:process";
+import { fileURLToPath } from "node:url";
+
+const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
+const packageFile = path.join(root, "package.json");
+const packageLockFile = path.join(root, "package-lock.json");
+const dockerfile = path.join(root, "Dockerfile");
+const generatedFile = path.join(root, "src/mlclaw/release-config.generated.ts");
+const check = process.argv.includes("--check");
+const pkg = JSON.parse(fs.readFileSync(packageFile, "utf8"));
+const packageLock = JSON.parse(fs.readFileSync(packageLockFile, "utf8"));
+
+const releaseConfig = {
+ packageVersion: requiredString(pkg.version, "package version"),
+ openclawVersion: requiredString(pkg.config?.openclawVersion, "OpenClaw version"),
+ brokerkitVersion: requiredString(pkg.config?.brokerkitVersion, "BrokerKit version"),
+ brokerkitPluginVersion: requiredString(pkg.config?.brokerkitPluginVersion, "BrokerKit plugin version"),
+ runtimeImageRepository: requiredString(pkg.config?.runtimeImageRepository, "runtime image repository"),
+};
+if (pkg.dependencies?.["openclaw-brokerkit"] !== releaseConfig.brokerkitPluginVersion) {
+ throw new Error("openclaw-brokerkit dependency must exactly match config.brokerkitPluginVersion");
+}
+if (
+ packageLock.version !== releaseConfig.packageVersion ||
+ packageLock.packages?.[""]?.version !== releaseConfig.packageVersion ||
+ packageLock.packages?.[""]?.dependencies?.["openclaw-brokerkit"] !== releaseConfig.brokerkitPluginVersion
+) {
+ throw new Error("package-lock.json release metadata is stale; run npm install --package-lock-only");
+}
+
+const generated = `// Generated from package.json by scripts/sync-release-config.mjs. Do not edit.\nexport const RELEASE_CONFIG = ${JSON.stringify(releaseConfig, null, 2)} as const;\n`;
+const runtimeImage = `${releaseConfig.runtimeImageRepository}:${releaseConfig.packageVersion}-openclaw-${releaseConfig.openclawVersion}`;
+const dockerValues = new Map([
+ ["OPENCLAW_VERSION", releaseConfig.openclawVersion],
+ ["OPENCLAW_BASE_IMAGE", "ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}"],
+ ["BROKERKIT_PLUGIN_VERSION", releaseConfig.brokerkitPluginVersion],
+ ["BROKERKIT_VERSION", releaseConfig.brokerkitVersion],
+ ["MLCLAW_RUNTIME_IMAGE", runtimeImage],
+]);
+const currentDockerfile = fs.readFileSync(dockerfile, "utf8");
+let synchronizedDockerfile = currentDockerfile;
+for (const [name, value] of dockerValues) {
+ const pattern = new RegExp(`^ARG ${name}=.*$`, "mu");
+ if (!pattern.test(synchronizedDockerfile)) {
+ throw new Error(`Dockerfile is missing ARG ${name}`);
+ }
+ synchronizedDockerfile = synchronizedDockerfile.replace(pattern, `ARG ${name}=${value}`);
+}
+
+if (check) {
+ let stale = false;
+ if (readOptional(generatedFile) !== generated) {
+ process.stderr.write("src/mlclaw/release-config.generated.ts is stale\n");
+ stale = true;
+ }
+ if (currentDockerfile !== synchronizedDockerfile) {
+ process.stderr.write("Dockerfile release defaults are stale\n");
+ stale = true;
+ }
+ if (stale) process.exit(1);
+} else {
+ fs.writeFileSync(generatedFile, generated);
+ fs.writeFileSync(dockerfile, synchronizedDockerfile);
+}
+
+function requiredString(value, label) {
+ if (typeof value !== "string" || !value.trim() || value !== value.trim()) {
+ throw new Error(`${label} must be a non-empty trimmed string`);
+ }
+ return value;
+}
+
+function readOptional(file) {
+ try {
+ return fs.readFileSync(file, "utf8");
+ } catch (error) {
+ if (error && typeof error === "object" && error.code === "ENOENT") return "";
+ throw error;
+ }
+}
diff --git a/src/mlclaw-space-runtime/operator-brokers.ts b/src/mlclaw-space-runtime/operator-brokers.ts
index 84b1718..cc7879e 100644
--- a/src/mlclaw-space-runtime/operator-brokers.ts
+++ b/src/mlclaw-space-runtime/operator-brokers.ts
@@ -1,6 +1,13 @@
import { isAbsolute } from "node:path";
import { readFileSync } from "node:fs";
-import { z } from "zod";
+import {
+ parseDescriptor,
+ parseErrorEnvelope,
+ parseRequest,
+ parseRequestPage,
+ type BrokerRequest,
+ type RequestPage,
+} from "openclaw-brokerkit/operator-v1";
const MAX_CONFIG_BYTES = 64 * 1024;
const MAX_TOKEN_BYTES = 4096;
@@ -18,44 +25,8 @@ export type OperatorBrokerConfig = OperatorBrokerSummary & {
token: string;
};
-export type BrokerDisplayField = {
- label: string;
- value: string;
-};
-
-export type BrokerApproval = {
- id: string;
- revision: number;
- requester: string;
- operation: string;
- status: "pending" | "active" | "denied" | "canceled" | "expired" | "consumed" | "revoked";
- requested_at: string;
- pending_expires_at?: string;
- active_expires_at?: string;
- requested_duration_seconds: number;
- requested_max_uses: number | null;
- granted_max_uses: number | null;
- used_count: number;
- request_reason?: string;
- decided_at?: string;
- decided_by?: string;
- decided_on_behalf_of?: string;
- presentation: {
- risk: "unknown" | "low" | "medium" | "high" | "critical";
- title: string;
- summary?: string;
- facts?: BrokerDisplayField[];
- };
- presentation_unavailable?: boolean;
- allowed_actions: Array<"approve" | "deny" | "revoke">;
- approval_bounds?: { max_duration_seconds: number; max_uses: number | null };
-};
-
-export type BrokerApprovalPage = {
- requests: BrokerApproval[];
- next_cursor?: string;
- event_cursor?: string;
-};
+export type BrokerApproval = BrokerRequest;
+export type BrokerApprovalPage = RequestPage;
export type BrokerDecision = {
expectedRevision: number;
@@ -70,70 +41,6 @@ export type BrokerOperatorClientOptions = OperatorBrokerConfig & {
requestTimeoutMs?: number;
};
-const displayFieldSchema = z
- .object({
- label: z.string().min(1).max(80),
- value: z.string().min(1).max(500),
- })
- .strict();
-
-const approvalSchema = z
- .object({
- id: z.string().min(1).max(128),
- revision: z.number().int().positive().safe(),
- requester: z.string().min(1).max(80),
- operation: z.string().min(1).max(500),
- status: z.enum(["pending", "active", "denied", "canceled", "expired", "consumed", "revoked"]),
- requested_at: z.string().datetime({ offset: true }),
- pending_expires_at: z.string().datetime({ offset: true }).optional(),
- active_expires_at: z.string().datetime({ offset: true }).optional(),
- requested_duration_seconds: z.number().int().positive().safe(),
- requested_max_uses: z.number().int().positive().safe().nullable(),
- granted_max_uses: z.number().int().positive().safe().nullable(),
- used_count: z.number().int().nonnegative().safe(),
- request_reason: z.string().max(2_000).optional(),
- decided_at: z.string().datetime({ offset: true }).optional(),
- decided_by: z.string().max(200).optional(),
- decided_on_behalf_of: z.string().max(200).optional(),
- presentation: z
- .object({
- risk: z.enum(["unknown", "low", "medium", "high", "critical"]),
- title: z.string().min(1).max(200),
- summary: z.string().max(2_000).optional(),
- facts: z.array(displayFieldSchema).max(20).optional(),
- })
- .strict(),
- presentation_unavailable: z.boolean().optional(),
- allowed_actions: z.array(z.enum(["approve", "deny", "revoke"])).max(3),
- approval_bounds: z
- .object({
- max_duration_seconds: z.number().int().positive().safe(),
- max_uses: z.number().int().positive().safe().nullable(),
- })
- .strict()
- .optional(),
- })
- .strict();
-
-const approvalPageSchema = z
- .object({
- requests: z.array(approvalSchema).max(100),
- next_cursor: z.string().min(1).max(1_024).optional(),
- event_cursor: z.string().min(1).max(1_024).optional(),
- })
- .strict();
-
-const operatorErrorSchema = z
- .object({
- error: z
- .object({
- code: z.string().min(1).max(200).optional(),
- message: z.string().min(1).max(2_000).optional(),
- })
- .optional(),
- })
- .passthrough();
-
export class BrokerOperatorError extends Error {
constructor(
readonly broker: OperatorBrokerSummary,
@@ -178,7 +85,7 @@ export class BrokerOperatorClient {
return this.request(
"/.well-known/brokerkit-operator",
signal ? { signal } : undefined,
- z.object({ api_version: z.literal("brokerkit.io/operator/v1") }).passthrough(),
+ parseDescriptor,
"discovery",
);
}
@@ -201,7 +108,7 @@ export class BrokerOperatorClient {
return this.request(
`/api/operator/v1/requests${suffix}`,
signal ? { signal } : undefined,
- approvalPageSchema,
+ parseRequestPage,
"request list",
);
}
@@ -210,7 +117,7 @@ export class BrokerOperatorClient {
return this.request(
`/api/operator/v1/requests/${approvalId(id)}`,
undefined,
- approvalSchema,
+ parseRequest,
"request",
);
}
@@ -235,7 +142,7 @@ export class BrokerOperatorClient {
: {}),
}),
},
- approvalSchema,
+ parseRequest,
"request",
);
}
@@ -269,7 +176,7 @@ export class BrokerOperatorClient {
private async request(
pathname: string,
init: RequestInit | undefined,
- schema: z.ZodTypeAny,
+ parser: (value: unknown) => T,
label: string,
): Promise {
const headers = new Headers(init?.headers);
@@ -286,7 +193,7 @@ export class BrokerOperatorClient {
if (!response.ok) {
throw await this.operatorError(response);
}
- return validatedBrokerPayload(await boundedJson(response), schema, label);
+ return validatedBrokerPayload(await boundedJson(response), parser, label);
} catch (err) {
if (deadline.timedOut()) {
throw new BrokerOperatorError(
@@ -305,13 +212,9 @@ export class BrokerOperatorClient {
private async operatorError(response: Response): Promise {
const fallback = `${this.options.label} operator request failed`;
try {
- const value = validatedBrokerPayload>(
- await boundedJson(response),
- operatorErrorSchema,
- "error",
- );
- const message = value.error?.message?.trim() || fallback;
- const code = value.error?.code?.trim();
+ const value = validatedBrokerPayload(await boundedJson(response), parseErrorEnvelope, "error");
+ const message = value?.error.message.trim() || fallback;
+ const code = value?.error.code.trim();
return new BrokerOperatorError(this.summary(), response.status, code, message);
} catch {
return new BrokerOperatorError(this.summary(), response.status, undefined, fallback);
@@ -468,10 +371,10 @@ async function boundedJson(response: Response): Promise {
return JSON.parse(Buffer.concat(chunks).toString("utf8")) as unknown;
}
-function validatedBrokerPayload(value: unknown, schema: z.ZodTypeAny, label: string): T {
- const parsed = schema.safeParse(value);
- if (!parsed.success) {
+function validatedBrokerPayload(value: unknown, parser: (value: unknown) => T, label: string): T {
+ try {
+ return parser(value);
+ } catch {
throw new Error(`broker ${label} response is invalid`);
}
- return parsed.data as T;
}
diff --git a/src/mlclaw/cli.ts b/src/mlclaw/cli.ts
index f46d24c..aa1910a 100644
--- a/src/mlclaw/cli.ts
+++ b/src/mlclaw/cli.ts
@@ -1351,7 +1351,6 @@ async function resolveBootstrapPlan(params: {
const existingSecrets: Record = await readSecretEnv(runtime.configRoot, agentName).catch(() => ({}));
const brokerCredential = await resolveBrokerHfToken({
opts,
- owner,
hfIdentity,
...(providedBrokerHfToken ? { preferredToken: providedBrokerHfToken } : {}),
existingSecrets,
@@ -4438,7 +4437,7 @@ async function credentialsStatus(requestedAgent: string | undefined, runtime: Re
runtime.stdout.log(`Agent: ${manifest.agent}`);
runtime.stdout.log(`Status: healthy`);
- runtime.stdout.log(`Profile: ${metadata.profileId}`);
+ runtime.stdout.log(`Credential kind: ${metadata.credentialKind}`);
runtime.stdout.log(`Account: ${metadata.account}`);
runtime.stdout.log(`Fingerprint: ${metadata.fingerprintSha256.slice(0, 12)}`);
runtime.stdout.log(`Verified: ${metadata.verifiedAt}`);
@@ -4456,7 +4455,7 @@ async function verifiedStoredBrokerCredential(
`HF Broker credential metadata is missing; run \`mlclaw credentials repair ${manifest.agent}\` to complete the cutover`,
);
}
- const verified = await verifyBrokerHfToken(token, manifest.owner, manifest.brokerCredential.account, runtime);
+ const verified = await verifyBrokerHfToken(token, manifest.brokerCredential.account, runtime);
const observed = brokerCredentialMetadata(token, verified.identity, runtime.now());
if (observed.fingerprintSha256 !== manifest.brokerCredential.fingerprintSha256) {
throw new Error(
@@ -4481,14 +4480,14 @@ async function credentialsRepair(
const suppliedToken = fileToken ?? nonEmpty(runtime.env.MLCLAW_BROKER_HF_TOKEN);
let replacement: { token: string; identity: HubIdentity };
if (suppliedToken) {
- replacement = await verifyBrokerHfToken(suppliedToken, manifest.owner, account, runtime);
+ replacement = await verifyBrokerHfToken(suppliedToken, account, runtime);
} else {
if (!runtime.prompt.isInteractive()) {
throw new Error(
"credential repair requires --broker-hf-token-file, MLCLAW_BROKER_HF_TOKEN, or an interactive terminal",
);
}
- replacement = await promptForBrokerHfToken(manifest.owner, account, runtime);
+ replacement = await promptForBrokerHfToken(account, runtime);
}
const updatedManifest: DeploymentManifest = {
@@ -4695,7 +4694,6 @@ function deploymentLockKey(manifest: Pick
async function resolveBrokerHfToken(params: {
opts: Pick;
- owner: string;
hfIdentity: HubIdentity;
preferredToken?: string;
existingSecrets: Record;
@@ -4710,7 +4708,7 @@ async function resolveBrokerHfToken(params: {
nonEmpty(params.existingSecrets.MLCLAW_BROKER_HF_TOKEN);
if (configuredToken) {
try {
- return await verifyBrokerHfToken(configuredToken, params.owner, params.hfIdentity.name, params.runtime);
+ return await verifyBrokerHfToken(configuredToken, params.hfIdentity.name, params.runtime);
} catch (error) {
if (fileToken || environmentToken || params.preferredToken) throw error;
if (params.runtime.prompt.isInteractive()) {
@@ -4731,24 +4729,23 @@ async function resolveBrokerHfToken(params: {
"a dedicated HF Broker credential is required; set MLCLAW_BROKER_HF_TOKEN, pass --broker-hf-token-file, or run bootstrap interactively",
);
}
- return await promptForBrokerHfToken(params.owner, params.hfIdentity.name, params.runtime);
+ return await promptForBrokerHfToken(params.hfIdentity.name, params.runtime);
}
async function promptForBrokerHfToken(
- owner: string,
account: string,
runtime: Required,
): Promise<{ token: string; identity: HubIdentity }> {
runtime.prompt.note(
- "ML Claw will open a Hugging Face token form with BrokerKit's permissions preselected. Create a dedicated token and paste it here. Your current HF CLI login will not be changed.",
+ "ML Claw will open a Hugging Face fine-grained token form. Choose the permissions and resources this broker may use, create a dedicated token, and paste it here. Your current HF CLI login will not be changed.",
"HF Broker credential",
);
- const url = buildBrokerTokenUrl(owner, account);
+ const url = buildBrokerTokenUrl();
const opened = await runtime.hfCli.openUrl(url);
runtime.prompt.note(
`${opened ? "The token form was opened in your browser." : "Open this token form in your browser."}
-Name and create the token, then copy it. The URL contains permission names only; it contains no credential. The exact URL is printed below.`,
+Choose the permissions and resources, name and create the token, then copy it. The URL contains no credential. The exact URL is printed below.`,
"Create the broker token",
);
runtime.stdout.log(url);
@@ -4758,7 +4755,7 @@ Name and create the token, then copy it. The URL contains permission names only;
"Hugging Face broker token",
);
try {
- const verified = await verifyBrokerHfToken(replacement, owner, account, runtime);
+ const verified = await verifyBrokerHfToken(replacement, account, runtime);
runtime.prompt.note(
"The dedicated broker token was verified. It will be stored only in ML Claw's trusted broker configuration.",
"HF Broker credential ready",
@@ -4775,7 +4772,6 @@ Name and create the token, then copy it. The URL contains permission names only;
async function verifyBrokerHfToken(
token: string,
- owner: string,
expectedAccount: string,
runtime: Required,
): Promise<{ token: string; identity: HubIdentity }> {
@@ -4783,7 +4779,7 @@ async function verifyBrokerHfToken(
if (identity.name !== expectedAccount) {
throw new Error(`broker token belongs to ${identity.name}, not ${expectedAccount}`);
}
- const assessment = assessBrokerCredential(identity, owner);
+ const assessment = assessBrokerCredential(identity);
if (assessment.status !== "sufficient") {
throw new Error(brokerCredentialAssessmentDetail(assessment));
}
@@ -4802,10 +4798,7 @@ async function readOptionalBrokerHfTokenFile(file: string | undefined): Promise<
function brokerCredentialAssessmentDetail(
assessment: Exclude,
): string {
- if (assessment.status === "unsupported") return assessment.reason;
- const shown = assessment.missing.slice(0, 8);
- const remaining = assessment.missing.length - shown.length;
- return `The HF Broker credential is missing ${assessment.missing.length} required permission${assessment.missing.length === 1 ? "" : "s"}: ${shown.join(", ")}${remaining > 0 ? `, and ${remaining} more` : ""}`;
+ return assessment.reason;
}
function errorMessage(error: unknown): string {
diff --git a/src/mlclaw/hf-broker-credential-requirements.json b/src/mlclaw/hf-broker-credential-requirements.json
deleted file mode 100644
index 90574b6..0000000
--- a/src/mlclaw/hf-broker-credential-requirements.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
- "version": 1,
- "profile_id": "hf-broker-complete-v1",
- "token_form_url": "https://huggingface.co/settings/tokens/new",
- "token_type": "fineGrained",
- "requires_gated_repositories": true,
- "personal_permissions": [
- "collection.read",
- "collection.write",
- "discussion.write",
- "inference.endpoints.infer.write",
- "inference.endpoints.write",
- "inference.serverless.write",
- "job.write",
- "repo.access.read",
- "repo.content.read",
- "repo.write",
- "sql-console.embed.write",
- "user.billing.read",
- "user.mcp.read",
- "user.notifications.read",
- "user.notifications.write",
- "user.papers.write",
- "user.preferences.write",
- "user.settings.notifications.write",
- "user.social.likes.write",
- "user.webhooks.read",
- "user.webhooks.write"
- ],
- "global_permissions": [
- "discussion.write",
- "post.write"
- ],
- "organization_permissions": [
- "collection.read",
- "collection.write",
- "discussion.write",
- "inference.endpoints.infer.write",
- "inference.endpoints.write",
- "inference.serverless.write",
- "job.write",
- "org.auditLog.write",
- "org.billing.read",
- "org.members.read",
- "org.members.write",
- "org.networkSecurity.read",
- "org.networkSecurity.write",
- "org.read",
- "org.repos.read",
- "org.serviceAccounts.read",
- "org.serviceAccounts.write",
- "org.write",
- "repo.access.read",
- "repo.content.read",
- "repo.write",
- "resourceGroup.write",
- "sql-console.embed.write"
- ]
-}
diff --git a/src/mlclaw/hf-broker-credential.ts b/src/mlclaw/hf-broker-credential.ts
index 603096a..ad24952 100644
--- a/src/mlclaw/hf-broker-credential.ts
+++ b/src/mlclaw/hf-broker-credential.ts
@@ -1,74 +1,24 @@
import { createHash } from "node:crypto";
-import { z } from "zod";
-import rawProfile from "./hf-broker-credential-requirements.json" with { type: "json" };
-import type { HubFineGrainedScope, HubIdentity } from "./hub-api.js";
+import type { HubIdentity } from "./hub-api.js";
-const permissionListSchema = z
- .array(z.string().min(1))
- .min(1)
- .superRefine((permissions, context) => {
- if (permissions.some((permission) => permission !== permission.trim())) {
- context.addIssue({ code: z.ZodIssueCode.custom, message: "permissions must not contain outer whitespace" });
- }
- if (new Set(permissions).size !== permissions.length) {
- context.addIssue({ code: z.ZodIssueCode.custom, message: "permissions must be unique" });
- }
- if (permissions.some((permission, index) => index > 0 && permission < (permissions[index - 1] as string))) {
- context.addIssue({ code: z.ZodIssueCode.custom, message: "permissions must be sorted" });
- }
- });
-
-const profileSchema = z
- .object({
- version: z.literal(1),
- profile_id: z.literal("hf-broker-complete-v1"),
- token_form_url: z.literal("https://huggingface.co/settings/tokens/new"),
- token_type: z.literal("fineGrained"),
- requires_gated_repositories: z.literal(true),
- personal_permissions: permissionListSchema,
- global_permissions: permissionListSchema,
- organization_permissions: permissionListSchema,
- })
- .strict();
-
-export const BROKER_CREDENTIAL_PROFILE = Object.freeze(profileSchema.parse(rawProfile));
-export const HF_TOKEN_CREATE_URL = BROKER_CREDENTIAL_PROFILE.token_form_url;
-export const BROKER_PERSONAL_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.personal_permissions;
-export const BROKER_GLOBAL_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.global_permissions;
-export const BROKER_ORGANIZATION_PERMISSIONS = BROKER_CREDENTIAL_PROFILE.organization_permissions;
+export const HF_TOKEN_CREATE_URL = "https://huggingface.co/settings/tokens/new?tokenType=fineGrained";
export type BrokerCredentialMetadata = {
- profileId: typeof BROKER_CREDENTIAL_PROFILE.profile_id;
+ credentialKind: "fine_grained_user_token";
account: string;
fingerprintSha256: string;
verifiedAt: string;
};
-export type BrokerCredentialAssessment =
- { status: "sufficient" } | { status: "insufficient"; missing: string[] } | { status: "unsupported"; reason: string };
+export type BrokerCredentialAssessment = { status: "sufficient" } | { status: "unsupported"; reason: string };
-export function buildBrokerTokenUrl(owner: string, accountName: string): string {
- const url = new URL(HF_TOKEN_CREATE_URL);
- url.searchParams.set("tokenType", BROKER_CREDENTIAL_PROFILE.token_type);
- for (const permission of BROKER_PERSONAL_PERMISSIONS) {
- url.searchParams.append("ownUserPermissions", permission);
- }
- for (const permission of BROKER_GLOBAL_PERMISSIONS) {
- url.searchParams.append("globalPermissions", permission);
- }
- url.searchParams.set("canReadGatedRepos", String(BROKER_CREDENTIAL_PROFILE.requires_gated_repositories));
- if (owner !== accountName) {
- url.searchParams.append("orgs", owner);
- for (const permission of BROKER_ORGANIZATION_PERMISSIONS) {
- url.searchParams.append("orgPermissions", permission);
- }
- }
- return url.toString();
+export function buildBrokerTokenUrl(): string {
+ return HF_TOKEN_CREATE_URL;
}
-export function assessBrokerCredential(identity: HubIdentity, owner: string): BrokerCredentialAssessment {
+export function assessBrokerCredential(identity: HubIdentity): BrokerCredentialAssessment {
const accessToken = identity.auth?.accessToken;
- if (accessToken?.role !== BROKER_CREDENTIAL_PROFILE.token_type) {
+ if (accessToken?.role !== "fineGrained") {
return {
status: "unsupported",
reason: "HF Broker requires a dedicated fine-grained Hugging Face token",
@@ -80,28 +30,7 @@ export function assessBrokerCredential(identity: HubIdentity, owner: string): Br
reason: "Hugging Face omitted this fine-grained token's permission details",
};
}
-
- const personalAvailable = new Set(scopedPermissions(accessToken.fineGrained.scoped, "user", identity.name));
- const globalAvailable = new Set(accessToken.fineGrained.global);
- const missing = BROKER_PERSONAL_PERMISSIONS.filter((permission) => !personalAvailable.has(permission));
- missing.push(
- ...BROKER_GLOBAL_PERMISSIONS.filter((permission) => !globalAvailable.has(permission)).map(
- (permission) => `global:${permission}`,
- ),
- );
- if (!accessToken.fineGrained.canReadGatedRepos) {
- missing.push("canReadGatedRepos");
- }
- if (owner !== identity.name) {
- const organizationAvailable = new Set(scopedPermissions(accessToken.fineGrained.scoped, "org", owner));
- missing.push(
- ...BROKER_ORGANIZATION_PERMISSIONS.filter((permission) => !organizationAvailable.has(permission)).map(
- (permission) => `org:${permission}`,
- ),
- );
- }
- missing.sort();
- return missing.length === 0 ? { status: "sufficient" } : { status: "insufficient", missing };
+ return { status: "sufficient" };
}
export function brokerCredentialMetadata(
@@ -110,16 +39,9 @@ export function brokerCredentialMetadata(
verifiedAt: Date,
): BrokerCredentialMetadata {
return {
- profileId: BROKER_CREDENTIAL_PROFILE.profile_id,
+ credentialKind: "fine_grained_user_token",
account: identity.name,
fingerprintSha256: createHash("sha256").update(token).digest("hex"),
verifiedAt: verifiedAt.toISOString(),
};
}
-
-function scopedPermissions(scopes: HubFineGrainedScope[], type: string, name: string): string[] {
- if (!Array.isArray(scopes)) return [];
- return scopes
- .filter((scope) => scope.entity.type === type && (!scope.entity.name || scope.entity.name === name))
- .flatMap((scope) => scope.permissions);
-}
diff --git a/src/mlclaw/local-config.ts b/src/mlclaw/local-config.ts
index d573759..9608a27 100644
--- a/src/mlclaw/local-config.ts
+++ b/src/mlclaw/local-config.ts
@@ -125,7 +125,7 @@ const manifestFields = {
runtimeImage: z.string().min(1).max(1024),
brokerCredential: z
.object({
- profileId: z.literal("hf-broker-complete-v1"),
+ credentialKind: z.literal("fine_grained_user_token"),
account: z.string().min(1).max(128),
fingerprintSha256: z.string().regex(/^[a-f0-9]{64}$/),
verifiedAt: z.string().datetime(),
diff --git a/src/mlclaw/release-config.generated.ts b/src/mlclaw/release-config.generated.ts
new file mode 100644
index 0000000..fddd538
--- /dev/null
+++ b/src/mlclaw/release-config.generated.ts
@@ -0,0 +1,8 @@
+// Generated from package.json by scripts/sync-release-config.mjs. Do not edit.
+export const RELEASE_CONFIG = {
+ "packageVersion": "0.4.8",
+ "openclawVersion": "2026.7.1",
+ "brokerkitVersion": "hf-broker/v0.4.2",
+ "brokerkitPluginVersion": "0.3.4",
+ "runtimeImageRepository": "ghcr.io/huggingface/mlclaw"
+} as const;
diff --git a/src/mlclaw/runtime-image.ts b/src/mlclaw/runtime-image.ts
index ed7f95d..b5c5844 100644
--- a/src/mlclaw/runtime-image.ts
+++ b/src/mlclaw/runtime-image.ts
@@ -1,20 +1,12 @@
-import fs from "node:fs";
-import path from "node:path";
-import { fileURLToPath } from "node:url";
+import { RELEASE_CONFIG } from "./release-config.generated.js";
-const DEFAULT_OPENCLAW_VERSION = "2026.7.1";
-const DEFAULT_BROKERKIT_PLUGIN_VERSION = "0.3.3";
-export const DEFAULT_BROKERKIT_VERSION = "hf-broker/v0.4.0";
-const DEFAULT_RUNTIME_IMAGE_REPOSITORY = "ghcr.io/huggingface/mlclaw";
-
-const PACKAGE_METADATA = readPackageMetadata();
-
-export const PACKAGE_VERSION = packageString("version", "unknown");
-export const OPENCLAW_VERSION = packageConfigString("openclawVersion", DEFAULT_OPENCLAW_VERSION);
+export const PACKAGE_VERSION = RELEASE_CONFIG.packageVersion;
+export const OPENCLAW_VERSION = RELEASE_CONFIG.openclawVersion;
export const OPENCLAW_BASE_IMAGE = `ghcr.io/openclaw/openclaw:${OPENCLAW_VERSION}`;
-export const BROKERKIT_PLUGIN_VERSION = packageConfigString("brokerkitPluginVersion", DEFAULT_BROKERKIT_PLUGIN_VERSION);
-export const BROKERKIT_VERSION = packageConfigString("brokerkitVersion", DEFAULT_BROKERKIT_VERSION);
-export const RUNTIME_IMAGE_REPOSITORY = packageConfigString("runtimeImageRepository", DEFAULT_RUNTIME_IMAGE_REPOSITORY);
+export const BROKERKIT_PLUGIN_VERSION = RELEASE_CONFIG.brokerkitPluginVersion;
+export const BROKERKIT_VERSION = RELEASE_CONFIG.brokerkitVersion;
+export const DEFAULT_BROKERKIT_VERSION = BROKERKIT_VERSION;
+export const RUNTIME_IMAGE_REPOSITORY = RELEASE_CONFIG.runtimeImageRepository;
export const DEFAULT_RUNTIME_IMAGE_TAG = `${PACKAGE_VERSION}-openclaw-${OPENCLAW_VERSION}`;
export const DEFAULT_RUNTIME_IMAGE = `${RUNTIME_IMAGE_REPOSITORY}:${DEFAULT_RUNTIME_IMAGE_TAG}`;
@@ -42,41 +34,3 @@ export function resolveSpaceRuntimeImage(
export function bundledSpaceRuntimeRef(templateRev: string): string {
return `bundled:${templateRev}`;
}
-
-type PackageMetadata = {
- version?: unknown;
- config?: Record;
-};
-
-function packageString(key: keyof PackageMetadata, fallback: string): string {
- const value = PACKAGE_METADATA[key];
- return typeof value === "string" && value.trim() ? value.trim() : fallback;
-}
-
-function packageConfigString(key: string, fallback: string): string {
- const value = PACKAGE_METADATA.config?.[key];
- return typeof value === "string" && value.trim() ? value.trim() : fallback;
-}
-
-function readPackageMetadata(): PackageMetadata {
- let dir = path.dirname(fileURLToPath(import.meta.url));
- while (true) {
- const candidate = path.join(dir, "package.json");
- try {
- return JSON.parse(fs.readFileSync(candidate, "utf8")) as PackageMetadata;
- } catch (err) {
- if (!isMissingFileError(err)) {
- throw err;
- }
- }
- const parent = path.dirname(dir);
- if (parent === dir) {
- throw new Error("could not find package.json while resolving default runtime image");
- }
- dir = parent;
- }
-}
-
-function isMissingFileError(err: unknown): boolean {
- return err instanceof Error && "code" in err && (err as NodeJS.ErrnoException).code === "ENOENT";
-}
diff --git a/test/mlclaw.brokerkit-agent-tools.test.ts b/test/mlclaw.brokerkit-agent-tools.test.ts
index 4a07b19..3fc9466 100644
--- a/test/mlclaw.brokerkit-agent-tools.test.ts
+++ b/test/mlclaw.brokerkit-agent-tools.test.ts
@@ -11,7 +11,9 @@ afterEach(async () => {
describe.runIf(brokerBinary)("pinned BrokerKit agent tools", () => {
it("advertises bounded transcript-safe submission and recovery schemas", async () => {
- const response = await callMcp("http://127.0.0.1:1", "tools/list");
+ const backend = await startAgentBackend();
+ cleanups.push(backend.close);
+ const response = await callMcp(backend.url, "tools/list");
const tools = parseMcpTools(response.result.tools);
const byName = new Map(tools.map((tool) => [tool.name, tool]));
@@ -134,6 +136,22 @@ async function startAgentBackend(): Promise<{
response.writeHead(401).end(JSON.stringify({ error: { code: "unauthorized", message: "unauthorized" } }));
return;
}
+ if (request.method === "GET" && url.pathname === "/.well-known/brokerkit-agent") {
+ response.writeHead(200).end(
+ JSON.stringify({
+ api_version: "brokerkit.io/agent/v1",
+ operations: ["repo.create", "space.secret.set", "space.variable.set"],
+ credential: {
+ ready: true,
+ provider: "huggingface",
+ credential_kind: "fine_grained_user_token",
+ generation: 1,
+ verification_state: "valid",
+ },
+ }),
+ );
+ return;
+ }
if (request.method === "POST" && url.pathname === "/api/agent/v1/operations") {
const submission = JSON.parse(await readBody(request)) as AgentSubmission;
const existing = operations.get(submission.idempotency_key);
diff --git a/test/mlclaw.cli.test.ts b/test/mlclaw.cli.test.ts
index 60c256a..9da5390 100644
--- a/test/mlclaw.cli.test.ts
+++ b/test/mlclaw.cli.test.ts
@@ -29,11 +29,6 @@ import type {
TailscaleServeState,
} from "../src/mlclaw/tailscale.js";
import { TailscaleApprovalRequiredError } from "../src/mlclaw/tailscale.js";
-import {
- BROKER_GLOBAL_PERMISSIONS,
- BROKER_ORGANIZATION_PERMISSIONS,
- BROKER_PERSONAL_PERMISSIONS,
-} from "../src/mlclaw/hf-broker-credential.js";
type PromptAnswer = string | boolean;
@@ -2150,6 +2145,8 @@ describe("mlclaw CLI", () => {
expect(code).toBe(0);
expect(openedUrls).toHaveLength(1);
expect(openedUrls[0]).toContain("tokenType=fineGrained");
+ expect(openedUrls[0]).not.toContain("Permissions");
+ expect(openedUrls[0]).not.toContain("orgs=");
expect(openedUrls[0]).not.toContain("hf_broker_complete");
expect(stdout).toContain(openedUrls[0]);
expect(notes.some((note) => note.message.includes(openedUrls[0] ?? ""))).toBe(false);
@@ -2272,7 +2269,7 @@ describe("mlclaw CLI", () => {
await expect(main(["credentials", "status"], runtime)).resolves.toBe(0);
expect(output).toContain("Status: healthy");
- expect(output).toContain("Profile: hf-broker-complete-v1");
+ expect(output).toContain("Credential kind: fine_grained_user_token");
expect(output.join("\n")).not.toContain("hf_broker_test");
});
@@ -2324,7 +2321,7 @@ describe("mlclaw CLI", () => {
});
await expect(readManifest(runtime.configRoot, "research")).resolves.toMatchObject({
brokerCredential: {
- profileId: "hf-broker-complete-v1",
+ credentialKind: "fine_grained_user_token",
account: "alice",
fingerprintSha256: expect.stringMatching(/^[a-f0-9]{64}$/),
},
@@ -4644,7 +4641,7 @@ async function seedDedicatedCredentialDeployment(runtime: { configRoot: string }
model: DEFAULT_MODEL,
runtimeImage: DEFAULT_RUNTIME_IMAGE,
brokerCredential: {
- profileId: "hf-broker-complete-v1",
+ credentialKind: "fine_grained_user_token",
account: "alice",
fingerprintSha256: createHash("sha256").update(token).digest("hex"),
verifiedAt: "2026-06-16T00:00:00.000Z",
@@ -4664,18 +4661,9 @@ function completeFineGrainedIdentity(): HubIdentity {
accessToken: {
role: "fineGrained",
fineGrained: {
- global: [...BROKER_GLOBAL_PERMISSIONS],
- canReadGatedRepos: true,
- scoped: [
- {
- entity: { type: "user", name: "alice" },
- permissions: [...BROKER_PERSONAL_PERMISSIONS],
- },
- {
- entity: { type: "org", name: "research-org" },
- permissions: [...BROKER_ORGANIZATION_PERMISSIONS],
- },
- ],
+ global: [],
+ canReadGatedRepos: false,
+ scoped: [],
},
},
},
diff --git a/test/mlclaw.delegated-brokerkit.test.ts b/test/mlclaw.delegated-brokerkit.test.ts
index 8936cdc..3d567f1 100644
--- a/test/mlclaw.delegated-brokerkit.test.ts
+++ b/test/mlclaw.delegated-brokerkit.test.ts
@@ -20,7 +20,10 @@ function request(id: string, revision = 1, status = "pending") {
presentation: {
risk: "high",
title: "Update repository",
+ target: "osolmaz/example",
facts: [{ label: "Repository", value: "osolmaz/example" }],
+ warnings: [{ severity: "high", text: "This changes repository metadata." }],
+ plan_hash: "sha256:delegated-contract-test",
},
allowed_actions: status === "pending" ? ["approve", "deny"] : ["revoke"],
approval_bounds: { max_duration_seconds: 300, max_uses: 1 },
diff --git a/test/mlclaw.hf-broker-credential.test.ts b/test/mlclaw.hf-broker-credential.test.ts
index 453f8a9..08d109c 100644
--- a/test/mlclaw.hf-broker-credential.test.ts
+++ b/test/mlclaw.hf-broker-credential.test.ts
@@ -1,134 +1,76 @@
import { describe, expect, it } from "vitest";
import {
assessBrokerCredential,
- BROKER_GLOBAL_PERMISSIONS,
- BROKER_ORGANIZATION_PERMISSIONS,
- BROKER_PERSONAL_PERMISSIONS,
+ brokerCredentialMetadata,
buildBrokerTokenUrl,
HF_TOKEN_CREATE_URL,
} from "../src/mlclaw/hf-broker-credential.js";
import type { HubIdentity } from "../src/mlclaw/hub-api.js";
describe("HF Broker credential policy", () => {
- it("builds a personal fine-grained token form without secret material", () => {
- const url = new URL(buildBrokerTokenUrl("alice", "alice"));
+ it("opens an empty fine-grained token form", () => {
+ const url = new URL(buildBrokerTokenUrl());
- expect(`${url.origin}${url.pathname}`).toBe(HF_TOKEN_CREATE_URL);
+ expect(url.toString()).toBe(HF_TOKEN_CREATE_URL);
expect(url.searchParams.get("tokenType")).toBe("fineGrained");
- expect(url.searchParams.get("canReadGatedRepos")).toBe("true");
- expect(url.searchParams.getAll("ownUserPermissions")).toEqual(BROKER_PERSONAL_PERMISSIONS);
- expect(url.searchParams.getAll("ownUserPermissions")).not.toContain("resourceGroup.write");
- expect(url.searchParams.getAll("globalPermissions")).toEqual(BROKER_GLOBAL_PERMISSIONS);
+ expect(url.searchParams.getAll("ownUserPermissions")).toEqual([]);
+ expect(url.searchParams.getAll("globalPermissions")).toEqual([]);
+ expect(url.searchParams.getAll("orgPermissions")).toEqual([]);
expect(url.searchParams.getAll("orgs")).toEqual([]);
expect(url.toString()).not.toContain("hf_");
});
- it("adds isolated organization permissions for an organization deployment", () => {
- const url = new URL(buildBrokerTokenUrl("research-org", "alice"));
-
- expect(url.searchParams.getAll("orgs")).toEqual(["research-org"]);
- expect(url.searchParams.getAll("orgPermissions")).toEqual(BROKER_ORGANIZATION_PERMISSIONS);
- expect(url.searchParams.getAll("orgPermissions")).toContain("resourceGroup.write");
- expect(url.searchParams.getAll("ownUserPermissions")).toEqual(BROKER_PERSONAL_PERMISSIONS);
+ it("accepts a dedicated fine-grained token without imposing a permission profile", () => {
+ expect(assessBrokerCredential(fineGrainedIdentity())).toEqual({ status: "sufficient" });
});
it("rejects legacy write tokens", () => {
- expect(
- assessBrokerCredential(identity({ type: "access_token", accessToken: { role: "write" } }), "research-org"),
- ).toEqual({ status: "unsupported", reason: "HF Broker requires a dedicated fine-grained Hugging Face token" });
- });
-
- it("accepts a complete personal fine-grained token", () => {
- expect(assessBrokerCredential(fineGrainedIdentity(), "alice")).toEqual({ status: "sufficient" });
- });
-
- it("requires permissions on the selected organization scope", () => {
- const candidate = fineGrainedIdentity([
- {
- entity: { type: "org", name: "other-org" },
- permissions: [...BROKER_ORGANIZATION_PERMISSIONS],
- },
- ]);
-
- const result = assessBrokerCredential(candidate, "research-org");
-
- expect(result.status).toBe("insufficient");
- if (result.status === "insufficient") {
- expect(result.missing).toContain("org:repo.write");
- expect(result.missing).toContain("org:inference.endpoints.write");
- }
- });
-
- it("reports exact missing fine-grained permissions", () => {
- const candidate = fineGrainedIdentity(
- [],
- BROKER_PERSONAL_PERMISSIONS.filter((value) => value !== "job.write"),
- );
-
- expect(assessBrokerCredential(candidate, "alice")).toEqual({ status: "insufficient", missing: ["job.write"] });
- });
-
- it("requires personal and global grants independently", () => {
- const missingPersonal = fineGrainedIdentity(
- [],
- BROKER_PERSONAL_PERMISSIONS.filter((value) => value !== "discussion.write"),
- );
- const missingGlobal = fineGrainedIdentity([], BROKER_PERSONAL_PERMISSIONS, []);
-
- expect(assessBrokerCredential(missingPersonal, "alice")).toEqual({
- status: "insufficient",
- missing: ["discussion.write"],
- });
- expect(assessBrokerCredential(missingGlobal, "alice")).toEqual({
- status: "insufficient",
- missing: ["global:discussion.write", "global:post.write"],
- });
- });
-
- it("requires gated-repository access", () => {
- const candidate = fineGrainedIdentity([], BROKER_PERSONAL_PERMISSIONS, BROKER_GLOBAL_PERMISSIONS, false);
-
- expect(assessBrokerCredential(candidate, "alice")).toEqual({
- status: "insufficient",
- missing: ["canReadGatedRepos"],
+ expect(assessBrokerCredential(identity({ type: "access_token", accessToken: { role: "write" } }))).toEqual({
+ status: "unsupported",
+ reason: "HF Broker requires a dedicated fine-grained Hugging Face token",
});
});
it("rejects opaque OAuth credentials", () => {
- expect(assessBrokerCredential(identity({ type: "oauth" }), "alice")).toEqual({
+ expect(assessBrokerCredential(identity({ type: "oauth" }))).toEqual({
status: "unsupported",
reason: "HF Broker requires a dedicated fine-grained Hugging Face token",
});
});
it("rejects fine-grained credentials whose metadata is omitted", () => {
- expect(
- assessBrokerCredential(identity({ type: "access_token", accessToken: { role: "fineGrained" } }), "alice"),
- ).toEqual({
+ expect(assessBrokerCredential(identity({ type: "access_token", accessToken: { role: "fineGrained" } }))).toEqual({
status: "unsupported",
reason: "Hugging Face omitted this fine-grained token's permission details",
});
});
+
+ it("records only secret-free credential identity metadata", () => {
+ const metadata = brokerCredentialMetadata("hf_secret", fineGrainedIdentity(), new Date("2026-07-19T00:00:00Z"));
+
+ expect(metadata).toEqual({
+ credentialKind: "fine_grained_user_token",
+ account: "alice",
+ fingerprintSha256: "108bb086b4d27560850369270e94c892a27977da0772782a127962c0569b202e",
+ verifiedAt: "2026-07-19T00:00:00.000Z",
+ });
+ expect(JSON.stringify(metadata)).not.toContain("hf_secret");
+ });
});
function identity(auth: NonNullable): HubIdentity {
return { name: "alice", organizations: ["research-org"], auth };
}
-function fineGrainedIdentity(
- extraScopes: NonNullable["accessToken"]>["fineGrained"]>["scoped"] = [],
- personalPermissions: readonly string[] = BROKER_PERSONAL_PERMISSIONS,
- globalPermissions: readonly string[] = BROKER_GLOBAL_PERMISSIONS,
- canReadGatedRepos = true,
-): HubIdentity {
+function fineGrainedIdentity(): HubIdentity {
return identity({
type: "access_token",
accessToken: {
role: "fineGrained",
fineGrained: {
- global: [...globalPermissions],
- scoped: [{ entity: { type: "user", name: "alice" }, permissions: [...personalPermissions] }, ...extraScopes],
- canReadGatedRepos,
+ global: [],
+ scoped: [],
+ canReadGatedRepos: false,
},
},
});
diff --git a/test/mlclaw.operator-brokers.test.ts b/test/mlclaw.operator-brokers.test.ts
index 07d2210..06cd8e3 100644
--- a/test/mlclaw.operator-brokers.test.ts
+++ b/test/mlclaw.operator-brokers.test.ts
@@ -28,7 +28,10 @@ function approval(id: string, status: string, revision: number) {
presentation: {
risk: "medium",
title: "Update repository",
+ target: "osolmaz/example",
facts: [{ label: "Repository", value: "osolmaz/example" }],
+ warnings: [{ severity: "medium", text: "This changes repository metadata." }],
+ plan_hash: "sha256:operator-contract-test",
},
allowed_actions: status === "pending" ? ["approve", "deny"] : ["revoke"],
approval_bounds: { max_duration_seconds: 300, max_uses: 1 },
@@ -156,10 +159,15 @@ describe("Brokerkit operator backends", () => {
});
}
if (request.url.includes("cursor=next")) {
- return new Response(JSON.stringify({ error: { code: "revision_conflict", message: "Request changed" } }), {
- status: 409,
- headers: { "content-type": "application/json" },
- });
+ return new Response(
+ JSON.stringify({
+ error: { code: "revision_conflict", message: "Request changed", correlation_id: "test-correlation" },
+ }),
+ {
+ status: 409,
+ headers: { "content-type": "application/json" },
+ },
+ );
}
return new Response(JSON.stringify(approval("grant-1", "pending", 1)), {
headers: { "content-type": "application/json" },
diff --git a/test/mlclaw.space-runtime.test.ts b/test/mlclaw.space-runtime.test.ts
index f4bda31..3c0d2f6 100644
--- a/test/mlclaw.space-runtime.test.ts
+++ b/test/mlclaw.space-runtime.test.ts
@@ -42,7 +42,10 @@ function brokerApproval(
presentation: {
risk: "medium",
title: "Update repository",
+ target: "osolmaz/example",
facts: [{ label: "Repository", value: "osolmaz/example" }],
+ warnings: [{ severity: "medium", text: "This changes repository metadata." }],
+ plan_hash: "sha256:space-runtime-contract-test",
},
allowed_actions: status === "pending" ? ["approve", "deny"] : ["revoke"],
approval_bounds: approvalBounds,