var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/_internal/utils.mjs
// @__NO_SIDE_EFFECTS__
function createNotImplementedError(name) {
return new Error(`[unenv] ${name} is not implemented yet!`);
}
// @__NO_SIDE_EFFECTS__
function notImplemented(name) {
const fn = /* @__PURE__ */ __name(() => {
throw /* @__PURE__ */ createNotImplementedError(name);
}, "fn");
return Object.assign(fn, { __unenv__: true });
}
// @__NO_SIDE_EFFECTS__
function notImplementedClass(name) {
return class {
__unenv__ = true;
constructor() {
throw new Error(`[unenv] ${name} is not implemented yet!`);
}
};
}
var init_utils = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/_internal/utils.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(createNotImplementedError, "createNotImplementedError");
__name(notImplemented, "notImplemented");
__name(notImplementedClass, "notImplementedClass");
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/perf_hooks/performance.mjs
var _timeOrigin, _performanceNow, nodeTiming, PerformanceEntry, PerformanceMark, PerformanceMeasure, PerformanceResourceTiming, PerformanceObserverEntryList, Performance, PerformanceObserver, performance;
var init_performance = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/perf_hooks/performance.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_utils();
_timeOrigin = globalThis.performance?.timeOrigin ?? Date.now();
_performanceNow = globalThis.performance?.now ? globalThis.performance.now.bind(globalThis.performance) : () => Date.now() - _timeOrigin;
nodeTiming = {
name: "node",
entryType: "node",
startTime: 0,
duration: 0,
nodeStart: 0,
v8Start: 0,
bootstrapComplete: 0,
environment: 0,
loopStart: 0,
loopExit: 0,
idleTime: 0,
uvMetricsInfo: {
loopCount: 0,
events: 0,
eventsWaiting: 0
},
detail: void 0,
toJSON() {
return this;
}
};
PerformanceEntry = class {
static {
__name(this, "PerformanceEntry");
}
__unenv__ = true;
detail;
entryType = "event";
name;
startTime;
constructor(name, options) {
this.name = name;
this.startTime = options?.startTime || _performanceNow();
this.detail = options?.detail;
}
get duration() {
return _performanceNow() - this.startTime;
}
toJSON() {
return {
name: this.name,
entryType: this.entryType,
startTime: this.startTime,
duration: this.duration,
detail: this.detail
};
}
};
PerformanceMark = class PerformanceMark2 extends PerformanceEntry {
static {
__name(this, "PerformanceMark");
}
entryType = "mark";
constructor() {
super(...arguments);
}
get duration() {
return 0;
}
};
PerformanceMeasure = class extends PerformanceEntry {
static {
__name(this, "PerformanceMeasure");
}
entryType = "measure";
};
PerformanceResourceTiming = class extends PerformanceEntry {
static {
__name(this, "PerformanceResourceTiming");
}
entryType = "resource";
serverTiming = [];
connectEnd = 0;
connectStart = 0;
decodedBodySize = 0;
domainLookupEnd = 0;
domainLookupStart = 0;
encodedBodySize = 0;
fetchStart = 0;
initiatorType = "";
name = "";
nextHopProtocol = "";
redirectEnd = 0;
redirectStart = 0;
requestStart = 0;
responseEnd = 0;
responseStart = 0;
secureConnectionStart = 0;
startTime = 0;
transferSize = 0;
workerStart = 0;
responseStatus = 0;
};
PerformanceObserverEntryList = class {
static {
__name(this, "PerformanceObserverEntryList");
}
__unenv__ = true;
getEntries() {
return [];
}
getEntriesByName(_name, _type) {
return [];
}
getEntriesByType(type) {
return [];
}
};
Performance = class {
static {
__name(this, "Performance");
}
__unenv__ = true;
timeOrigin = _timeOrigin;
eventCounts = /* @__PURE__ */ new Map();
_entries = [];
_resourceTimingBufferSize = 0;
navigation = void 0;
timing = void 0;
timerify(_fn, _options) {
throw createNotImplementedError("Performance.timerify");
}
get nodeTiming() {
return nodeTiming;
}
eventLoopUtilization() {
return {};
}
markResourceTiming() {
return new PerformanceResourceTiming("");
}
onresourcetimingbufferfull = null;
now() {
if (this.timeOrigin === _timeOrigin) {
return _performanceNow();
}
return Date.now() - this.timeOrigin;
}
clearMarks(markName) {
this._entries = markName ? this._entries.filter((e) => e.name !== markName) : this._entries.filter((e) => e.entryType !== "mark");
}
clearMeasures(measureName) {
this._entries = measureName ? this._entries.filter((e) => e.name !== measureName) : this._entries.filter((e) => e.entryType !== "measure");
}
clearResourceTimings() {
this._entries = this._entries.filter((e) => e.entryType !== "resource" || e.entryType !== "navigation");
}
getEntries() {
return this._entries;
}
getEntriesByName(name, type) {
return this._entries.filter((e) => e.name === name && (!type || e.entryType === type));
}
getEntriesByType(type) {
return this._entries.filter((e) => e.entryType === type);
}
mark(name, options) {
const entry = new PerformanceMark(name, options);
this._entries.push(entry);
return entry;
}
measure(measureName, startOrMeasureOptions, endMark) {
let start;
let end;
if (typeof startOrMeasureOptions === "string") {
start = this.getEntriesByName(startOrMeasureOptions, "mark")[0]?.startTime;
end = this.getEntriesByName(endMark, "mark")[0]?.startTime;
} else {
start = Number.parseFloat(startOrMeasureOptions?.start) || this.now();
end = Number.parseFloat(startOrMeasureOptions?.end) || this.now();
}
const entry = new PerformanceMeasure(measureName, {
startTime: start,
detail: {
start,
end
}
});
this._entries.push(entry);
return entry;
}
setResourceTimingBufferSize(maxSize) {
this._resourceTimingBufferSize = maxSize;
}
addEventListener(type, listener, options) {
throw createNotImplementedError("Performance.addEventListener");
}
removeEventListener(type, listener, options) {
throw createNotImplementedError("Performance.removeEventListener");
}
dispatchEvent(event) {
throw createNotImplementedError("Performance.dispatchEvent");
}
toJSON() {
return this;
}
};
PerformanceObserver = class {
static {
__name(this, "PerformanceObserver");
}
__unenv__ = true;
static supportedEntryTypes = [];
_callback = null;
constructor(callback) {
this._callback = callback;
}
takeRecords() {
return [];
}
disconnect() {
throw createNotImplementedError("PerformanceObserver.disconnect");
}
observe(options) {
throw createNotImplementedError("PerformanceObserver.observe");
}
bind(fn) {
return fn;
}
runInAsyncScope(fn, thisArg, ...args) {
return fn.call(thisArg, ...args);
}
asyncId() {
return 0;
}
triggerAsyncId() {
return 0;
}
emitDestroy() {
return this;
}
};
performance = globalThis.performance && "addEventListener" in globalThis.performance ? globalThis.performance : new Performance();
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/perf_hooks.mjs
var init_perf_hooks = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/perf_hooks.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_performance();
}
});
// node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/polyfill/performance.mjs
var init_performance2 = __esm({
"node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/polyfill/performance.mjs"() {
init_perf_hooks();
globalThis.performance = performance;
globalThis.Performance = Performance;
globalThis.PerformanceEntry = PerformanceEntry;
globalThis.PerformanceMark = PerformanceMark;
globalThis.PerformanceMeasure = PerformanceMeasure;
globalThis.PerformanceObserver = PerformanceObserver;
globalThis.PerformanceObserverEntryList = PerformanceObserverEntryList;
globalThis.PerformanceResourceTiming = PerformanceResourceTiming;
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/mock/noop.mjs
var noop_default;
var init_noop = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/mock/noop.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
noop_default = Object.assign(() => {
}, { __unenv__: true });
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/console.mjs
import { Writable } from "node:stream";
var _console, _ignoreErrors, _stderr, _stdout, log, info, trace, debug, table, error, warn, createTask, clear, count, countReset, dir, dirxml, group, groupEnd, groupCollapsed, profile, profileEnd, time, timeEnd, timeLog, timeStamp, Console, _times, _stdoutErrorHandler, _stderrErrorHandler;
var init_console = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/console.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_noop();
init_utils();
_console = globalThis.console;
_ignoreErrors = true;
_stderr = new Writable();
_stdout = new Writable();
log = _console?.log ?? noop_default;
info = _console?.info ?? log;
trace = _console?.trace ?? info;
debug = _console?.debug ?? log;
table = _console?.table ?? log;
error = _console?.error ?? log;
warn = _console?.warn ?? error;
createTask = _console?.createTask ?? /* @__PURE__ */ notImplemented("console.createTask");
clear = _console?.clear ?? noop_default;
count = _console?.count ?? noop_default;
countReset = _console?.countReset ?? noop_default;
dir = _console?.dir ?? noop_default;
dirxml = _console?.dirxml ?? noop_default;
group = _console?.group ?? noop_default;
groupEnd = _console?.groupEnd ?? noop_default;
groupCollapsed = _console?.groupCollapsed ?? noop_default;
profile = _console?.profile ?? noop_default;
profileEnd = _console?.profileEnd ?? noop_default;
time = _console?.time ?? noop_default;
timeEnd = _console?.timeEnd ?? noop_default;
timeLog = _console?.timeLog ?? noop_default;
timeStamp = _console?.timeStamp ?? noop_default;
Console = _console?.Console ?? /* @__PURE__ */ notImplementedClass("console.Console");
_times = /* @__PURE__ */ new Map();
_stdoutErrorHandler = noop_default;
_stderrErrorHandler = noop_default;
}
});
// node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/node/console.mjs
var workerdConsole, assert, clear2, context, count2, countReset2, createTask2, debug2, dir2, dirxml2, error2, group2, groupCollapsed2, groupEnd2, info2, log2, profile2, profileEnd2, table2, time2, timeEnd2, timeLog2, timeStamp2, trace2, warn2, console_default;
var init_console2 = __esm({
"node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/node/console.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_console();
workerdConsole = globalThis["console"];
({
assert,
clear: clear2,
context: (
// @ts-expect-error undocumented public API
context
),
count: count2,
countReset: countReset2,
createTask: (
// @ts-expect-error undocumented public API
createTask2
),
debug: debug2,
dir: dir2,
dirxml: dirxml2,
error: error2,
group: group2,
groupCollapsed: groupCollapsed2,
groupEnd: groupEnd2,
info: info2,
log: log2,
profile: profile2,
profileEnd: profileEnd2,
table: table2,
time: time2,
timeEnd: timeEnd2,
timeLog: timeLog2,
timeStamp: timeStamp2,
trace: trace2,
warn: warn2
} = workerdConsole);
Object.assign(workerdConsole, {
Console,
_ignoreErrors,
_stderr,
_stderrErrorHandler,
_stdout,
_stdoutErrorHandler,
_times
});
console_default = workerdConsole;
}
});
// node_modules/.pnpm/wrangler@4.35.0_@cloudflare+workers-types@4.20260404.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-console
var init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console = __esm({
"node_modules/.pnpm/wrangler@4.35.0_@cloudflare+workers-types@4.20260404.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-console"() {
init_console2();
globalThis.console = console_default;
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/hrtime.mjs
var hrtime;
var init_hrtime = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/hrtime.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
hrtime = /* @__PURE__ */ Object.assign(/* @__PURE__ */ __name(function hrtime2(startTime) {
const now2 = Date.now();
const seconds = Math.trunc(now2 / 1e3);
const nanos = now2 % 1e3 * 1e6;
if (startTime) {
let diffSeconds = seconds - startTime[0];
let diffNanos = nanos - startTime[0];
if (diffNanos < 0) {
diffSeconds = diffSeconds - 1;
diffNanos = 1e9 + diffNanos;
}
return [diffSeconds, diffNanos];
}
return [seconds, nanos];
}, "hrtime"), { bigint: /* @__PURE__ */ __name(function bigint() {
return BigInt(Date.now() * 1e6);
}, "bigint") });
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/tty/read-stream.mjs
var ReadStream;
var init_read_stream = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/tty/read-stream.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
ReadStream = class {
static {
__name(this, "ReadStream");
}
fd;
isRaw = false;
isTTY = false;
constructor(fd) {
this.fd = fd;
}
setRawMode(mode) {
this.isRaw = mode;
return this;
}
};
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/tty/write-stream.mjs
var WriteStream;
var init_write_stream = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/tty/write-stream.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
WriteStream = class {
static {
__name(this, "WriteStream");
}
fd;
columns = 80;
rows = 24;
isTTY = false;
constructor(fd) {
this.fd = fd;
}
clearLine(dir3, callback) {
callback && callback();
return false;
}
clearScreenDown(callback) {
callback && callback();
return false;
}
cursorTo(x, y, callback) {
callback && typeof callback === "function" && callback();
return false;
}
moveCursor(dx, dy, callback) {
callback && callback();
return false;
}
getColorDepth(env2) {
return 1;
}
hasColors(count3, env2) {
return false;
}
getWindowSize() {
return [this.columns, this.rows];
}
write(str2, encoding, cb) {
if (str2 instanceof Uint8Array) {
str2 = new TextDecoder().decode(str2);
}
try {
console.log(str2);
} catch {
}
cb && typeof cb === "function" && cb();
return false;
}
};
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/tty.mjs
var init_tty = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/tty.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_read_stream();
init_write_stream();
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/node-version.mjs
var NODE_VERSION;
var init_node_version = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/node-version.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
NODE_VERSION = "22.14.0";
}
});
// node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/process.mjs
import { EventEmitter } from "node:events";
var Process;
var init_process = __esm({
"node_modules/.pnpm/unenv@2.0.0-rc.21/node_modules/unenv/dist/runtime/node/internal/process/process.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_tty();
init_utils();
init_node_version();
Process = class _Process extends EventEmitter {
static {
__name(this, "Process");
}
env;
hrtime;
nextTick;
constructor(impl) {
super();
this.env = impl.env;
this.hrtime = impl.hrtime;
this.nextTick = impl.nextTick;
for (const prop of [...Object.getOwnPropertyNames(_Process.prototype), ...Object.getOwnPropertyNames(EventEmitter.prototype)]) {
const value = this[prop];
if (typeof value === "function") {
this[prop] = value.bind(this);
}
}
}
// --- event emitter ---
emitWarning(warning, type, code) {
console.warn(`${code ? `[${code}] ` : ""}${type ? `${type}: ` : ""}${warning}`);
}
emit(...args) {
return super.emit(...args);
}
listeners(eventName) {
return super.listeners(eventName);
}
// --- stdio (lazy initializers) ---
#stdin;
#stdout;
#stderr;
get stdin() {
return this.#stdin ??= new ReadStream(0);
}
get stdout() {
return this.#stdout ??= new WriteStream(1);
}
get stderr() {
return this.#stderr ??= new WriteStream(2);
}
// --- cwd ---
#cwd = "/";
chdir(cwd2) {
this.#cwd = cwd2;
}
cwd() {
return this.#cwd;
}
// --- dummy props and getters ---
arch = "";
platform = "";
argv = [];
argv0 = "";
execArgv = [];
execPath = "";
title = "";
pid = 200;
ppid = 100;
get version() {
return `v${NODE_VERSION}`;
}
get versions() {
return { node: NODE_VERSION };
}
get allowedNodeEnvironmentFlags() {
return /* @__PURE__ */ new Set();
}
get sourceMapsEnabled() {
return false;
}
get debugPort() {
return 0;
}
get throwDeprecation() {
return false;
}
get traceDeprecation() {
return false;
}
get features() {
return {};
}
get release() {
return {};
}
get connected() {
return false;
}
get config() {
return {};
}
get moduleLoadList() {
return [];
}
constrainedMemory() {
return 0;
}
availableMemory() {
return 0;
}
uptime() {
return 0;
}
resourceUsage() {
return {};
}
// --- noop methods ---
ref() {
}
unref() {
}
// --- unimplemented methods ---
umask() {
throw createNotImplementedError("process.umask");
}
getBuiltinModule() {
return void 0;
}
getActiveResourcesInfo() {
throw createNotImplementedError("process.getActiveResourcesInfo");
}
exit() {
throw createNotImplementedError("process.exit");
}
reallyExit() {
throw createNotImplementedError("process.reallyExit");
}
kill() {
throw createNotImplementedError("process.kill");
}
abort() {
throw createNotImplementedError("process.abort");
}
dlopen() {
throw createNotImplementedError("process.dlopen");
}
setSourceMapsEnabled() {
throw createNotImplementedError("process.setSourceMapsEnabled");
}
loadEnvFile() {
throw createNotImplementedError("process.loadEnvFile");
}
disconnect() {
throw createNotImplementedError("process.disconnect");
}
cpuUsage() {
throw createNotImplementedError("process.cpuUsage");
}
setUncaughtExceptionCaptureCallback() {
throw createNotImplementedError("process.setUncaughtExceptionCaptureCallback");
}
hasUncaughtExceptionCaptureCallback() {
throw createNotImplementedError("process.hasUncaughtExceptionCaptureCallback");
}
initgroups() {
throw createNotImplementedError("process.initgroups");
}
openStdin() {
throw createNotImplementedError("process.openStdin");
}
assert() {
throw createNotImplementedError("process.assert");
}
binding() {
throw createNotImplementedError("process.binding");
}
// --- attached interfaces ---
permission = { has: /* @__PURE__ */ notImplemented("process.permission.has") };
report = {
directory: "",
filename: "",
signal: "SIGUSR2",
compact: false,
reportOnFatalError: false,
reportOnSignal: false,
reportOnUncaughtException: false,
getReport: /* @__PURE__ */ notImplemented("process.report.getReport"),
writeReport: /* @__PURE__ */ notImplemented("process.report.writeReport")
};
finalization = {
register: /* @__PURE__ */ notImplemented("process.finalization.register"),
unregister: /* @__PURE__ */ notImplemented("process.finalization.unregister"),
registerBeforeExit: /* @__PURE__ */ notImplemented("process.finalization.registerBeforeExit")
};
memoryUsage = Object.assign(() => ({
arrayBuffers: 0,
rss: 0,
external: 0,
heapTotal: 0,
heapUsed: 0
}), { rss: /* @__PURE__ */ __name(() => 0, "rss") });
// --- undefined props ---
mainModule = void 0;
domain = void 0;
// optional
send = void 0;
exitCode = void 0;
channel = void 0;
getegid = void 0;
geteuid = void 0;
getgid = void 0;
getgroups = void 0;
getuid = void 0;
setegid = void 0;
seteuid = void 0;
setgid = void 0;
setgroups = void 0;
setuid = void 0;
// internals
_events = void 0;
_eventsCount = void 0;
_exiting = void 0;
_maxListeners = void 0;
_debugEnd = void 0;
_debugProcess = void 0;
_fatalException = void 0;
_getActiveHandles = void 0;
_getActiveRequests = void 0;
_kill = void 0;
_preload_modules = void 0;
_rawDebug = void 0;
_startProfilerIdleNotifier = void 0;
_stopProfilerIdleNotifier = void 0;
_tickCallback = void 0;
_disconnect = void 0;
_handleQueue = void 0;
_pendingMessage = void 0;
_channel = void 0;
_send = void 0;
_linkedBinding = void 0;
};
}
});
// node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/node/process.mjs
var globalProcess, getBuiltinModule, exit, platform, nextTick, unenvProcess, abort, addListener, allowedNodeEnvironmentFlags, hasUncaughtExceptionCaptureCallback, setUncaughtExceptionCaptureCallback, loadEnvFile, sourceMapsEnabled, arch, argv, argv0, chdir, config, connected, constrainedMemory, availableMemory, cpuUsage, cwd, debugPort, dlopen, disconnect, emit, emitWarning, env, eventNames, execArgv, execPath, finalization, features, getActiveResourcesInfo, getMaxListeners, hrtime3, kill, listeners, listenerCount, memoryUsage, on, off, once, pid, ppid, prependListener, prependOnceListener, rawListeners, release, removeAllListeners, removeListener, report, resourceUsage, setMaxListeners, setSourceMapsEnabled, stderr, stdin, stdout, title, throwDeprecation, traceDeprecation, umask, uptime, version, versions, domain, initgroups, moduleLoadList, reallyExit, openStdin, assert2, binding, send, exitCode, channel, getegid, geteuid, getgid, getgroups, getuid, setegid, seteuid, setgid, setgroups, setuid, permission, mainModule, _events, _eventsCount, _exiting, _maxListeners, _debugEnd, _debugProcess, _fatalException, _getActiveHandles, _getActiveRequests, _kill, _preload_modules, _rawDebug, _startProfilerIdleNotifier, _stopProfilerIdleNotifier, _tickCallback, _disconnect, _handleQueue, _pendingMessage, _channel, _send, _linkedBinding, _process, process_default;
var init_process2 = __esm({
"node_modules/.pnpm/@cloudflare+unenv-preset@2.7.3_unenv@2.0.0-rc.21_workerd@1.20250906.0/node_modules/@cloudflare/unenv-preset/dist/runtime/node/process.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_hrtime();
init_process();
globalProcess = globalThis["process"];
getBuiltinModule = globalProcess.getBuiltinModule;
({ exit, platform, nextTick } = getBuiltinModule(
"node:process"
));
unenvProcess = new Process({
env: globalProcess.env,
hrtime,
nextTick
});
({
abort,
addListener,
allowedNodeEnvironmentFlags,
hasUncaughtExceptionCaptureCallback,
setUncaughtExceptionCaptureCallback,
loadEnvFile,
sourceMapsEnabled,
arch,
argv,
argv0,
chdir,
config,
connected,
constrainedMemory,
availableMemory,
cpuUsage,
cwd,
debugPort,
dlopen,
disconnect,
emit,
emitWarning,
env,
eventNames,
execArgv,
execPath,
finalization,
features,
getActiveResourcesInfo,
getMaxListeners,
hrtime: hrtime3,
kill,
listeners,
listenerCount,
memoryUsage,
on,
off,
once,
pid,
ppid,
prependListener,
prependOnceListener,
rawListeners,
release,
removeAllListeners,
removeListener,
report,
resourceUsage,
setMaxListeners,
setSourceMapsEnabled,
stderr,
stdin,
stdout,
title,
throwDeprecation,
traceDeprecation,
umask,
uptime,
version,
versions,
domain,
initgroups,
moduleLoadList,
reallyExit,
openStdin,
assert: assert2,
binding,
send,
exitCode,
channel,
getegid,
geteuid,
getgid,
getgroups,
getuid,
setegid,
seteuid,
setgid,
setgroups,
setuid,
permission,
mainModule,
_events,
_eventsCount,
_exiting,
_maxListeners,
_debugEnd,
_debugProcess,
_fatalException,
_getActiveHandles,
_getActiveRequests,
_kill,
_preload_modules,
_rawDebug,
_startProfilerIdleNotifier,
_stopProfilerIdleNotifier,
_tickCallback,
_disconnect,
_handleQueue,
_pendingMessage,
_channel,
_send,
_linkedBinding
} = unenvProcess);
_process = {
abort,
addListener,
allowedNodeEnvironmentFlags,
hasUncaughtExceptionCaptureCallback,
setUncaughtExceptionCaptureCallback,
loadEnvFile,
sourceMapsEnabled,
arch,
argv,
argv0,
chdir,
config,
connected,
constrainedMemory,
availableMemory,
cpuUsage,
cwd,
debugPort,
dlopen,
disconnect,
emit,
emitWarning,
env,
eventNames,
execArgv,
execPath,
exit,
finalization,
features,
getBuiltinModule,
getActiveResourcesInfo,
getMaxListeners,
hrtime: hrtime3,
kill,
listeners,
listenerCount,
memoryUsage,
nextTick,
on,
off,
once,
pid,
platform,
ppid,
prependListener,
prependOnceListener,
rawListeners,
release,
removeAllListeners,
removeListener,
report,
resourceUsage,
setMaxListeners,
setSourceMapsEnabled,
stderr,
stdin,
stdout,
title,
throwDeprecation,
traceDeprecation,
umask,
uptime,
version,
versions,
// @ts-expect-error old API
domain,
initgroups,
moduleLoadList,
reallyExit,
openStdin,
assert: assert2,
binding,
send,
exitCode,
channel,
getegid,
geteuid,
getgid,
getgroups,
getuid,
setegid,
seteuid,
setgid,
setgroups,
setuid,
permission,
mainModule,
_events,
_eventsCount,
_exiting,
_maxListeners,
_debugEnd,
_debugProcess,
_fatalException,
_getActiveHandles,
_getActiveRequests,
_kill,
_preload_modules,
_rawDebug,
_startProfilerIdleNotifier,
_stopProfilerIdleNotifier,
_tickCallback,
_disconnect,
_handleQueue,
_pendingMessage,
_channel,
_send,
_linkedBinding
};
process_default = _process;
}
});
// node_modules/.pnpm/wrangler@4.35.0_@cloudflare+workers-types@4.20260404.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-process
var init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process = __esm({
"node_modules/.pnpm/wrangler@4.35.0_@cloudflare+workers-types@4.20260404.1/node_modules/wrangler/_virtual_unenv_global_polyfill-@cloudflare-unenv-preset-node-process"() {
init_process2();
globalThis.process = process_default;
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/compose.js
var compose;
var init_compose = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/compose.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
compose = /* @__PURE__ */ __name((middleware, onError, onNotFound) => {
return (context2, 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];
context2.req.routeIndex = i;
} else {
handler = i === middleware.length && next || void 0;
}
if (handler) {
try {
res = await handler(context2, () => dispatch(i + 1));
} catch (err) {
if (err instanceof Error && onError) {
context2.error = err;
res = await onError(err, context2);
isError = true;
} else {
throw err;
}
}
} else {
if (context2.finalized === false && onNotFound) {
res = await onNotFound(context2);
}
}
if (res && (context2.finalized === false || isError)) {
context2.res = res;
}
return context2;
}
__name(dispatch, "dispatch");
};
}, "compose");
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/http-exception.js
var init_http_exception = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/http-exception.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request/constants.js
var GET_MATCH_RESULT;
var init_constants = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request/constants.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
GET_MATCH_RESULT = /* @__PURE__ */ Symbol();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/body.js
async function parseFormData(request, options) {
const formData = await request.formData();
if (formData) {
return convertFormDataToBodyData(formData, 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);
}
});
if (options.dot) {
Object.entries(form).forEach(([key, value]) => {
const shouldParseDotValues = key.includes(".");
if (shouldParseDotValues) {
handleParsingNestedValues(form, key, value);
delete form[key];
}
});
}
return form;
}
var parseBody, handleParsingAllValues, handleParsingNestedValues;
var init_body = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/body.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_request();
parseBody = /* @__PURE__ */ __name(async (request, options = /* @__PURE__ */ Object.create(null)) => {
const { all = false, dot = false } = options;
const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;
const contentType = headers.get("Content-Type");
if (contentType?.startsWith("multipart/form-data") || contentType?.startsWith("application/x-www-form-urlencoded")) {
return parseFormData(request, { all, dot });
}
return {};
}, "parseBody");
__name(parseFormData, "parseFormData");
__name(convertFormDataToBodyData, "convertFormDataToBodyData");
handleParsingAllValues = /* @__PURE__ */ __name((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];
}
}
}, "handleParsingAllValues");
handleParsingNestedValues = /* @__PURE__ */ __name((form, key, value) => {
if (/(?:^|\.)__proto__\./.test(key)) {
return;
}
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];
}
});
}, "handleParsingNestedValues");
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/url.js
var splitPath, splitRoutingPath, extractGroupsFromPath, replaceGroupMarks, patternCache, getPattern, tryDecode, tryDecodeURI, getPath, getPathNoStrict, mergePath, checkOptionalParameter, _decodeURI, _getQueryParam, getQueryParam, getQueryParams, decodeURIComponent_;
var init_url = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/url.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
splitPath = /* @__PURE__ */ __name((path) => {
const paths = path.split("/");
if (paths[0] === "") {
paths.shift();
}
return paths;
}, "splitPath");
splitRoutingPath = /* @__PURE__ */ __name((routePath) => {
const { groups, path } = extractGroupsFromPath(routePath);
const paths = splitPath(path);
return replaceGroupMarks(paths, groups);
}, "splitRoutingPath");
extractGroupsFromPath = /* @__PURE__ */ __name((path) => {
const groups = [];
path = path.replace(/\{[^}]+\}/g, (match2, index) => {
const mark = `@${index}`;
groups.push([mark, match2]);
return mark;
});
return { groups, path };
}, "extractGroupsFromPath");
replaceGroupMarks = /* @__PURE__ */ __name((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;
}
}
}
return paths;
}, "replaceGroupMarks");
patternCache = {};
getPattern = /* @__PURE__ */ __name((label, next) => {
if (label === "*") {
return "*";
}
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];
}
return null;
}, "getPattern");
tryDecode = /* @__PURE__ */ __name((str2, decoder) => {
try {
return decoder(str2);
} catch {
return str2.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => {
try {
return decoder(match2);
} catch {
return match2;
}
});
}
}, "tryDecode");
tryDecodeURI = /* @__PURE__ */ __name((str2) => tryDecode(str2, decodeURI), "tryDecodeURI");
getPath = /* @__PURE__ */ __name((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 path = url.slice(start, end);
return tryDecodeURI(path.includes("%25") ? path.replace(/%25/g, "%2525") : path);
} else if (charCode === 63 || charCode === 35) {
break;
}
}
return url.slice(start, i);
}, "getPath");
getPathNoStrict = /* @__PURE__ */ __name((request) => {
const result = getPath(request);
return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
}, "getPathNoStrict");
mergePath = /* @__PURE__ */ __name((base, sub, ...rest) => {
if (rest.length) {
sub = mergePath(sub, ...rest);
}
return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
}, "mergePath");
checkOptionalParameter = /* @__PURE__ */ __name((path) => {
if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(":")) {
return null;
}
const segments = path.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);
}, "checkOptionalParameter");
_decodeURI = /* @__PURE__ */ __name((value) => {
if (!/[%+]/.test(value)) {
return value;
}
if (value.indexOf("+") !== -1) {
value = value.replace(/\+/g, " ");
}
return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value;
}, "_decodeURI");
_getQueryParam = /* @__PURE__ */ __name((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;
}
}
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;
}
}
return key ? results[key] : results;
}, "_getQueryParam");
getQueryParam = _getQueryParam;
getQueryParams = /* @__PURE__ */ __name((url, key) => {
return _getQueryParam(url, key, true);
}, "getQueryParams");
decodeURIComponent_ = decodeURIComponent;
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request.js
var tryDecodeURIComponent, HonoRequest;
var init_request = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_http_exception();
init_constants();
init_body();
init_url();
tryDecodeURIComponent = /* @__PURE__ */ __name((str2) => tryDecode(str2, decodeURIComponent_), "tryDecodeURIComponent");
HonoRequest = class {
static {
__name(this, "HonoRequest");
}
/**
* `.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, path = "/", matchResult = [[]]) {
this.raw = request;
this.path = path;
this.#matchResult = matchResult;
this.#validatedData = {};
}
param(key) {
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
}
#getDecodedParam(key) {
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
const param = this.#getParamValue(paramKey);
return param && /\%/.test(param) ? tryDecodeURIComponent(param) : param;
}
#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;
}
#getParamValue(paramKey) {
return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
}
query(key) {
return getQueryParam(this.url, key);
}
queries(key) {
return getQueryParams(this.url, key);
}
header(name) {
if (name) {
return this.raw.headers.get(name) ?? void 0;
}
const headerData = {};
this.raw.headers.forEach((value, key) => {
headerData[key] = value;
});
return headerData;
}
async parseBody(options) {
return parseBody(this, options);
}
#cachedBody = /* @__PURE__ */ __name((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]();
}, "#cachedBody");
/**
* `.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));
}
/**
* `.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");
}
/**
* `.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");
}
/**
* 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");
}
/**
* 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;
}
valid(target) {
return this.#validatedData[target];
}
/**
* `.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;
}
/**
* `.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 [GET_MATCH_RESULT]() {
return this.#matchResult;
}
/**
* `.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);
}
/**
* `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;
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/html.js
var HtmlEscapedCallbackPhase, raw, resolveCallback;
var init_html = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/html.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
HtmlEscapedCallbackPhase = {
Stringify: 1,
BeforeStream: 2,
Stream: 3
};
raw = /* @__PURE__ */ __name((value, callbacks) => {
const escapedString = new String(value);
escapedString.isEscaped = true;
escapedString.callbacks = callbacks;
return escapedString;
}, "raw");
resolveCallback = /* @__PURE__ */ __name(async (str2, phase, preserveCallbacks, context2, buffer) => {
if (typeof str2 === "object" && !(str2 instanceof String)) {
if (!(str2 instanceof Promise)) {
str2 = str2.toString();
}
if (str2 instanceof Promise) {
str2 = await str2;
}
}
const callbacks = str2.callbacks;
if (!callbacks?.length) {
return Promise.resolve(str2);
}
if (buffer) {
buffer[0] += str2;
} else {
buffer = [str2];
}
const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context: context2 }))).then(
(res) => Promise.all(
res.filter(Boolean).map((str22) => resolveCallback(str22, phase, false, context2, buffer))
).then(() => buffer[0])
);
if (preserveCallbacks) {
return raw(await resStr, callbacks);
} else {
return resStr;
}
}, "resolveCallback");
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/context.js
var TEXT_PLAIN, setDefaultContentType, createResponseInstance, Context;
var init_context = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/context.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_request();
init_html();
TEXT_PLAIN = "text/plain; charset=UTF-8";
setDefaultContentType = /* @__PURE__ */ __name((contentType, headers) => {
return {
"Content-Type": contentType,
...headers
};
}, "setDefaultContentType");
createResponseInstance = /* @__PURE__ */ __name((body, init) => new Response(body, init), "createResponseInstance");
Context = class {
static {
__name(this, "Context");
}
#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;
}
}
/**
* `.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");
}
}
/**
* @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");
}
}
/**
* @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()
});
}
/**
* 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;
}
/**
* `.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 = /* @__PURE__ */ __name((...args) => {
this.#renderer ??= (content) => this.html(content);
return this.#renderer(...args);
}, "render");
/**
* Sets the layout for the response.
*
* @param layout - The layout to set.
* @returns The layout function.
*/
setLayout = /* @__PURE__ */ __name((layout) => this.#layout = layout, "setLayout");
/**
* Gets the current layout for the response.
*
* @returns The current layout function.
*/
getLayout = /* @__PURE__ */ __name(() => this.#layout, "getLayout");
/**
* `.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 = /* @__PURE__ */ __name((renderer) => {
this.#renderer = renderer;
}, "setRenderer");
/**
* `.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 = /* @__PURE__ */ __name((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);
}
}, "header");
status = /* @__PURE__ */ __name((status) => {
this.#status = 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 = /* @__PURE__ */ __name((key, value) => {
this.#var ??= /* @__PURE__ */ new Map();
this.#var.set(key, value);
}, "set");
/**
* `.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 = /* @__PURE__ */ __name((key) => {
return this.#var ? this.#var.get(key) : void 0;
}, "get");
/**
* `.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);
}
#newResponse(data, arg, headers) {
const responseHeaders = 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") {
responseHeaders.append(key, value);
} else {
responseHeaders.set(key, value);
}
}
}
if (headers) {
for (const [k, v] of Object.entries(headers)) {
if (typeof v === "string") {
responseHeaders.set(k, v);
} else {
responseHeaders.delete(k);
for (const v2 of v) {
responseHeaders.append(k, v2);
}
}
}
}
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
return createResponseInstance(data, { status, headers: responseHeaders });
}
newResponse = /* @__PURE__ */ __name((...args) => this.#newResponse(...args), "newResponse");
/**
* `.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 = /* @__PURE__ */ __name((data, arg, headers) => this.#newResponse(data, arg, headers), "body");
/**
* `.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 = /* @__PURE__ */ __name((text, arg, headers) => {
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(
text,
arg,
setDefaultContentType(TEXT_PLAIN, headers)
);
}, "text");
/**
* `.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 = /* @__PURE__ */ __name((object, arg, headers) => {
return this.#newResponse(
JSON.stringify(object),
arg,
setDefaultContentType("application/json", headers)
);
}, "json");
html = /* @__PURE__ */ __name((html, arg, headers) => {
const res = /* @__PURE__ */ __name((html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers)), "res");
return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);
}, "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 = /* @__PURE__ */ __name((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);
}, "redirect");
/**
* `.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 = /* @__PURE__ */ __name(() => {
this.#notFoundHandler ??= () => createResponseInstance();
return this.#notFoundHandler(this);
}, "notFound");
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router.js
var METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE, METHODS, MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError;
var init_router = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
METHOD_NAME_ALL = "ALL";
METHOD_NAME_ALL_LOWERCASE = "all";
METHODS = ["get", "post", "put", "delete", "options", "patch"];
MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
UnsupportedPathError = class extends Error {
static {
__name(this, "UnsupportedPathError");
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/constants.js
var COMPOSED_HANDLER;
var init_constants2 = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/constants.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
COMPOSED_HANDLER = "__COMPOSED_HANDLER";
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono-base.js
var notFoundHandler, errorHandler, Hono;
var init_hono_base = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono-base.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_compose();
init_context();
init_router();
init_constants2();
init_url();
notFoundHandler = /* @__PURE__ */ __name((c) => {
return c.text("404 Not Found", 404);
}, "notFoundHandler");
errorHandler = /* @__PURE__ */ __name((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);
}, "errorHandler");
Hono = class _Hono {
static {
__name(this, "_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, path, ...handlers) => {
for (const p of [path].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;
}
#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;
}
#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(path, app2) {
const subApp = this.basePath(path);
app2.routes.map((r) => {
let handler;
if (app2.errorHandler === errorHandler) {
handler = r.handler;
} else {
handler = /* @__PURE__ */ __name(async (c, next) => (await compose([], app2.errorHandler)(c, () => r.handler(c, next))).res, "handler");
handler[COMPOSED_HANDLER] = r.handler;
}
subApp.#addRoute(r.method, r.path, handler);
});
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(path) {
const subApp = this.#clone();
subApp._basePath = mergePath(this._basePath, path);
return subApp;
}
/**
* `.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 = /* @__PURE__ */ __name((handler) => {
this.errorHandler = handler;
return this;
}, "onError");
/**
* `.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 = /* @__PURE__ */ __name((handler) => {
this.#notFoundHandler = handler;
return this;
}, "notFound");
/**
* `.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(path, applicationHandler, options) {
let replaceRequest;
let optionHandler;
if (options) {
if (typeof options === "function") {
optionHandler = options;
} else {
optionHandler = options.optionHandler;
if (options.replaceRequest === false) {
replaceRequest = /* @__PURE__ */ __name((request) => request, "replaceRequest");
} 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, path);
const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
return (request) => {
const url = new URL(request.url);
url.pathname = url.pathname.slice(pathPrefixLength) || "/";
return new Request(url, request);
};
})();
const handler = /* @__PURE__ */ __name(async (c, next) => {
const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
if (res) {
return res;
}
await next();
}, "handler");
this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler);
return this;
}
#addRoute(method, path, handler) {
method = method.toUpperCase();
path = mergePath(this._basePath, path);
const r = { basePath: this._basePath, path, method, handler };
this.router.add(method, path, [handler, r]);
this.routes.push(r);
}
#handleError(err, c) {
if (err instanceof Error) {
return this.errorHandler(err, c);
}
throw err;
}
#dispatch(request, executionCtx, env2, method) {
if (method === "HEAD") {
return (async () => new Response(null, await this.#dispatch(request, executionCtx, env2, "GET")))();
}
const path = this.getPath(request, { env: env2 });
const matchResult = this.router.match(method, path);
const c = new Context(request, {
path,
matchResult,
env: env2,
executionCtx,
notFoundHandler: this.#notFoundHandler
});
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);
}
const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
return (async () => {
try {
const context2 = await composed(c);
if (!context2.finalized) {
throw new Error(
"Context is not finalized. Did you forget to return a Response object or `await next()`?"
);
}
return context2.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 = /* @__PURE__ */ __name((request, ...rest) => {
return this.#dispatch(request, rest[1], rest[0], request.method);
}, "fetch");
/**
* `.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 = /* @__PURE__ */ __name((input, requestInit, Env, executionCtx) => {
if (input instanceof Request) {
return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
}
input = input.toString();
return this.fetch(
new Request(
/^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`,
requestInit
),
Env,
executionCtx
);
}, "request");
/**
* `.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 = /* @__PURE__ */ __name(() => {
addEventListener("fetch", (event) => {
event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
});
}, "fire");
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/matcher.js
function match(method, path) {
const matchers = this.buildAllMatchers();
const match2 = /* @__PURE__ */ __name((method2, path2) => {
const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];
const staticMatch = matcher[2][path2];
if (staticMatch) {
return staticMatch;
}
const match3 = path2.match(matcher[0]);
if (!match3) {
return [[], emptyParam];
}
const index = match3.indexOf("", 1);
return [matcher[1][index], match3];
}, "match2");
this.match = match2;
return match2(method, path);
}
var emptyParam;
var init_matcher = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/matcher.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router();
emptyParam = [];
__name(match, "match");
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/node.js
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 LABEL_REG_EXP_STR, ONLY_WILDCARD_REG_EXP_STR, TAIL_WILDCARD_REG_EXP_STR, PATH_ERROR, regExpMetaChars, Node;
var init_node = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/node.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
LABEL_REG_EXP_STR = "[^/]+";
ONLY_WILDCARD_REG_EXP_STR = ".*";
TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)";
PATH_ERROR = /* @__PURE__ */ Symbol();
regExpMetaChars = new Set(".\\+*[^]$()");
__name(compareKey, "compareKey");
Node = class _Node {
static {
__name(this, "_Node");
}
#index;
#varIndex;
#children = /* @__PURE__ */ Object.create(null);
insert(tokens, index, paramMap, context2, 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 = context2.varIndex++;
}
}
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();
}
}
node.insert(restTokens, index, paramMap, context2, 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();
});
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/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/trie.js
var Trie;
var init_trie = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/trie.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_node();
Trie = class {
static {
__name(this, "Trie");
}
#context = { varIndex: 0 };
#root = new Node();
insert(path, index, pathErrorCheckOnly) {
const paramAssoc = [];
const groups = [];
for (let i = 0; ; ) {
let replaced = false;
path = path.replace(/\{[^}]+\}/g, (m) => {
const mark = `@\\${i}`;
groups[i] = [mark, m];
i++;
replaced = true;
return mark;
});
if (!replaced) {
break;
}
}
const tokens = path.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;
}
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 "$()";
}
if (paramIndex !== void 0) {
paramReplacementMap[Number(paramIndex)] = ++captureIndex;
return "";
}
return "";
});
return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/router.js
function buildWildcardRegExp(path) {
return wildcardRegExpCache[path] ??= new RegExp(
path === "*" ? "" : `^${path.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, path, handlers] = routesWithStaticPathFlag[i];
if (pathErrorCheckOnly) {
staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
} else {
j++;
}
let paramAssoc;
try {
paramAssoc = trie.insert(path, j, pathErrorCheckOnly);
} catch (e) {
throw e === PATH_ERROR ? new UnsupportedPathError(path) : 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];
});
}
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]]];
}
}
}
const handlerMap = [];
for (const i in indexReplacementMap) {
handlerMap[i] = handlerData[indexReplacementMap[i]];
}
return [regexp, handlerMap, staticMap];
}
function findMiddleware(middleware, path) {
if (!middleware) {
return void 0;
}
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
if (buildWildcardRegExp(k).test(path)) {
return [...middleware[k]];
}
}
return void 0;
}
var nullMatcher, wildcardRegExpCache, RegExpRouter;
var init_router2 = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/router.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router();
init_url();
init_matcher();
init_node();
init_trie();
nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
__name(buildWildcardRegExp, "buildWildcardRegExp");
__name(clearWildcardRegExpCache, "clearWildcardRegExpCache");
__name(buildMatcherFromPreprocessedRoutes, "buildMatcherFromPreprocessedRoutes");
__name(findMiddleware, "findMiddleware");
RegExpRouter = class {
static {
__name(this, "RegExpRouter");
}
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, path, 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]];
});
});
}
if (path === "/*") {
path = "*";
}
const paramCount = (path.match(/\/:/g) || []).length;
if (/\*$/.test(path)) {
const re = buildWildcardRegExp(path);
if (method === METHOD_NAME_ALL) {
Object.keys(middleware).forEach((m) => {
middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
});
} else {
middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];
}
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;
}
const paths = checkOptionalParameter(path) || [path];
for (let i = 0, len = paths.length; i < len; i++) {
const path2 = paths[i];
Object.keys(routes).forEach((m) => {
if (method === METHOD_NAME_ALL || method === m) {
routes[m][path2] ||= [
...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []
];
routes[m][path2].push([handler, paramCount - len + i + 1]);
}
});
}
}
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;
}
#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((path) => [path, r[method][path]]) : [];
if (ownRoute.length !== 0) {
hasOwnRoute ||= true;
routes.push(...ownRoute);
} else if (method !== METHOD_NAME_ALL) {
routes.push(
...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])
);
}
});
if (!hasOwnRoute) {
return null;
} else {
return buildMatcherFromPreprocessedRoutes(routes);
}
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/prepared-router.js
var init_prepared_router = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/prepared-router.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router();
init_matcher();
init_router2();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/index.js
var init_reg_exp_router = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/index.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router2();
init_prepared_router();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/router.js
var SmartRouter;
var init_router3 = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/router.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router();
SmartRouter = class {
static {
__name(this, "SmartRouter");
}
name = "SmartRouter";
#routers = [];
#routes = [];
constructor(init) {
this.#routers = init.routers;
}
add(method, path, handler) {
if (!this.#routes) {
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
}
this.#routes.push([method, path, handler]);
}
match(method, path) {
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, path);
} 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;
}
get activeRouter() {
if (this.#routes || this.#routers.length !== 1) {
throw new Error("No active router has been determined yet.");
}
return this.#routers[0];
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/index.js
var init_smart_router = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/index.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router3();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/node.js
var emptyParams, hasChildren, Node2;
var init_node2 = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/node.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router();
init_url();
emptyParams = /* @__PURE__ */ Object.create(null);
hasChildren = /* @__PURE__ */ __name((children) => {
for (const _ in children) {
return true;
}
return false;
}, "hasChildren");
Node2 = class _Node2 {
static {
__name(this, "_Node");
}
#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];
}
this.#patterns = [];
}
insert(method, path, handler) {
this.#order = ++this.#order;
let curNode = this;
const parts = splitRoutingPath(path);
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];
}
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;
}
}
}
}
}
search(method, path) {
const handlerSets = [];
this.#params = emptyParams;
const curNode = this;
let curNodes = [curNode];
const parts = splitPath(path);
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 = path[0] === "/" ? 1 : 0;
for (let p = 0; p < len; p++) {
partOffsets[p] = offset;
offset += parts[p].length + 1;
}
}
const restPathString = path.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 shifted = curNodesQueue.shift();
curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
}
if (handlerSets.length > 1) {
handlerSets.sort((a, b) => {
return a.score - b.score;
});
}
return [handlerSets.map(({ handler, params }) => [handler, params])];
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/router.js
var TrieRouter;
var init_router4 = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/router.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_url();
init_node2();
TrieRouter = class {
static {
__name(this, "TrieRouter");
}
name = "TrieRouter";
#node;
constructor() {
this.#node = new Node2();
}
add(method, path, handler) {
const results = checkOptionalParameter(path);
if (results) {
for (let i = 0, len = results.length; i < len; i++) {
this.#node.insert(method, results[i], handler);
}
return;
}
this.#node.insert(method, path, handler);
}
match(method, path) {
return this.#node.search(method, path);
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/index.js
var init_trie_router = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/index.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_router4();
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono.js
var Hono2;
var init_hono = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_hono_base();
init_reg_exp_router();
init_smart_router();
init_trie_router();
Hono2 = class extends Hono {
static {
__name(this, "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()]
});
}
};
}
});
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/index.js
var init_dist = __esm({
"node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/index.js"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_hono();
}
});
// src/types.ts
async function kvGetNodeOutput(store, nodeId) {
try {
const val = await store.kv.get(`${store.runId}:node:${nodeId}`, "json");
return val;
} catch {
return void 0;
}
}
async function kvSetNodeOutput(store, nodeId, output) {
try {
await store.kv.put(
`${store.runId}:node:${nodeId}`,
JSON.stringify(output),
{ expirationTtl: 3600 }
);
} catch {
}
}
var WorkflowPaused, ExecutionError;
var init_types = __esm({
"src/types.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(kvGetNodeOutput, "kvGetNodeOutput");
WorkflowPaused = class extends Error {
static {
__name(this, "WorkflowPaused");
}
task_id;
run_id;
paused_node_id;
trace_so_far;
constructor(task_id, run_id, paused_node_id, trace_so_far) {
super(`workflow paused at node ${paused_node_id} waiting for task ${task_id}`);
this.name = "WorkflowPaused";
this.task_id = task_id;
this.run_id = run_id;
this.paused_node_id = paused_node_id;
this.trace_so_far = trace_so_far;
}
};
ExecutionError = class extends Error {
static {
__name(this, "ExecutionError");
}
failed_node;
failed_input;
trace;
constructor(message, failed_node, failed_input, trace3) {
super(message);
this.name = "ExecutionError";
this.failed_node = failed_node;
this.failed_input = failed_input;
this.trace = trace3;
}
};
__name(kvSetNodeOutput, "kvSetNodeOutput");
}
});
// src/lib/hash.ts
async function deriveRecipeHash(canonicalId) {
return "rec_" + await sha256Prefix(canonicalId);
}
function isComponentHash(id) {
return /^cmp_[0-9a-f]{8}$/.test(id);
}
function isRecipeHash(id) {
return /^rec_[0-9a-f]{8}$/.test(id);
}
async function sha256Prefix(input) {
const data = new TextEncoder().encode(input);
const buf = await crypto.subtle.digest("SHA-256", data);
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 8);
}
var init_hash = __esm({
"src/lib/hash.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(deriveRecipeHash, "deriveRecipeHash");
__name(isComponentHash, "isComponentHash");
__name(isRecipeHash, "isRecipeHash");
__name(sha256Prefix, "sha256Prefix");
}
});
// src/routes/recipes.ts
async function installRecipeRecord(kv, recipe) {
const uuid = recipe.uuid;
const { canonical_id, hash_id } = recipe;
const listRaw = await kv.get(kIdxCanonical(canonical_id));
const uuids = listRaw ? JSON.parse(listRaw) : [];
if (!uuids.includes(uuid)) uuids.push(uuid);
await Promise.all([
kv.put(`recipe:${uuid}`, JSON.stringify(recipe)),
kv.put(kIdxCanonical(canonical_id), JSON.stringify(uuids)),
kv.put(kIdxInstalled(canonical_id), uuid),
kv.put(`idx:${hash_id}`, canonical_id)
]);
}
async function fetchMarketStat(env2, canonicalId) {
try {
const base = (env2.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, "");
const headers = {};
if (env2.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env2.KBDB_INTERNAL_TOKEN}`;
const res = await fetch(`${base}/recipe-stats/${encodeURIComponent(canonicalId)}`, { headers });
if (!res.ok) return null;
const json = await res.json();
if (!json.stat) return null;
return {
success_count: json.stat.success_count ?? 0,
failure_count: json.stat.failure_count ?? 0
};
} catch {
return null;
}
}
async function listAllRecipes(kv) {
const list = await kv.list({ prefix: "recipe:" });
const all = (await Promise.all(
list.keys.map((k) => kv.get(k.name, "json"))
)).filter(Boolean);
const hasUuid = new Set(all.filter((r) => r.uuid).map((r) => r.canonical_id));
return all.filter((r) => r.uuid || !hasUuid.has(r.canonical_id));
}
async function resolveRecipe(id, kv) {
const direct = await kv.get(`recipe:${id}`, "json");
if (direct && direct.uuid) return direct;
let canonicalId = id;
if (id.startsWith("rec_")) {
const looked = await kv.get(`idx:${id}`);
if (!looked) return direct;
canonicalId = looked;
}
const installedUuid = await kv.get(kIdxInstalled(canonicalId));
if (installedUuid) {
const byUuid = await kv.get(`recipe:${installedUuid}`, "json");
if (byUuid) return byUuid;
}
return direct ?? await kv.get(`recipe:${canonicalId}`, "json");
}
async function resolveAuthRecipe(service, kv) {
return kv.get(`auth_recipe:${service}`, "json");
}
var recipesRouter, kIdxCanonical, kIdxInstalled;
var init_recipes = __esm({
"src/routes/recipes.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
init_hash();
recipesRouter = new Hono2();
kIdxCanonical = /* @__PURE__ */ __name((canonicalId) => `idx:canonical:${canonicalId}`, "kIdxCanonical");
kIdxInstalled = /* @__PURE__ */ __name((canonicalId) => `idx:installed:${canonicalId}`, "kIdxInstalled");
__name(installRecipeRecord, "installRecipeRecord");
recipesRouter.post("/recipes", async (c) => {
let body;
try {
body = await c.req.json();
} catch {
return c.json({ success: false, error: "request body \u5FC5\u9808\u70BA JSON" }, 400);
}
const canonicalId = (body.canonical_id ?? "").trim().toLowerCase();
if (!canonicalId) return c.json({ success: false, error: "canonical_id \u5FC5\u586B" }, 400);
if (!body.endpoint) return c.json({ success: false, error: "endpoint \u5FC5\u586B" }, 400);
const hashId = await deriveRecipeHash(canonicalId);
const now2 = Date.now();
const existing = await resolveRecipe(canonicalId, c.env.RECIPES);
const recipe = {
uuid: existing?.uuid ?? crypto.randomUUID(),
author: body.author ?? existing?.author ?? "local",
derived_from: body.derived_from ?? existing?.derived_from,
canonical_id: canonicalId,
hash_id: hashId,
display_name: body.display_name,
description: body.description,
endpoint: body.endpoint,
method: (body.method ?? "POST").toUpperCase(),
headers: body.headers,
body: body.body,
// ③ payload/回應/binding 三層(3.12):全選填,沒給就是 undefined=既有行為
body_template: body.body_template,
response_map: body.response_map,
auth: body.auth,
binding_name: body.binding_name,
auth_service: body.auth_service,
credentials_required: body.credentials_required,
created_at: existing?.created_at ?? now2,
updated_at: now2
};
await installRecipeRecord(c.env.RECIPES, recipe);
return c.json({ success: true, recipe });
});
recipesRouter.post("/recipes/submit", async (c) => {
let body;
try {
body = await c.req.json();
} catch {
return c.json({ success: false, error: "request body \u5FC5\u9808\u70BA JSON" }, 400);
}
const canonicalId = (body.canonical_id ?? "").trim().toLowerCase();
if (!canonicalId) return c.json({ success: false, error: "canonical_id \u5FC5\u586B" }, 400);
if (!body.endpoint) return c.json({ success: false, error: "endpoint \u5FC5\u586B" }, 400);
const hashId = await deriveRecipeHash(canonicalId);
const now2 = Date.now();
const recipe = {
uuid: crypto.randomUUID(),
author: body.author ?? body.submitter ?? "anonymous",
derived_from: body.derived_from,
canonical_id: canonicalId,
hash_id: hashId,
display_name: body.display_name,
description: body.description,
endpoint: body.endpoint,
method: (body.method ?? "POST").toUpperCase(),
headers: body.headers,
body: body.body,
auth_service: body.auth_service,
credentials_required: body.credentials_required,
created_at: now2,
updated_at: now2
};
await installRecipeRecord(c.env.RECIPES, recipe);
const kbdbBase2 = (c.env.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, "");
const evidence = {
content: canonicalId,
entry_type: "recipe_submission",
metadata_json: JSON.stringify({
uuid: recipe.uuid,
canonical_id: canonicalId,
author: recipe.author,
submitter: body.submitter ?? "unknown",
claimed_stat: body.stat ?? null,
submitted_at: now2
})
};
const kbdbHeaders = { "Content-Type": "application/json" };
if (c.env.KBDB_INTERNAL_TOKEN) kbdbHeaders["Authorization"] = `Bearer ${c.env.KBDB_INTERNAL_TOKEN}`;
c.executionCtx.waitUntil(
fetch(`${kbdbBase2}/entries`, {
method: "POST",
headers: kbdbHeaders,
body: JSON.stringify(evidence)
}).catch(() => void 0)
);
return c.json({ success: true, recipe, evidence_recorded: true });
});
recipesRouter.post("/recipes/migrate-uuid", async (c) => {
const list = await c.env.RECIPES.list({ prefix: "recipe:" });
let migrated = 0, skipped = 0;
const errors = [];
for (const k of list.keys) {
try {
const rec = await c.env.RECIPES.get(k.name, "json");
if (!rec || !rec.canonical_id) {
skipped++;
continue;
}
if (rec.uuid) {
skipped++;
continue;
}
const migrated_recipe = {
...rec,
uuid: crypto.randomUUID(),
author: rec.author ?? "system"
// 舊種子歸 system
};
await installRecipeRecord(c.env.RECIPES, migrated_recipe);
migrated++;
} catch (e) {
errors.push(`${k.name}: ${e instanceof Error ? e.message : String(e)}`);
}
}
return c.json({ success: errors.length === 0, migrated, skipped, errors });
});
recipesRouter.get("/recipes/:id", async (c) => {
const id = c.req.param("id");
const recipe = await resolveRecipe(id, c.env.RECIPES);
if (!recipe) return c.json({ success: false, error: `\u627E\u4E0D\u5230 recipe: ${id}` }, 404);
return c.json({ success: true, recipe });
});
recipesRouter.get("/recipes", async (c) => {
const list = await c.env.RECIPES.list({ prefix: "recipe:" });
const all = (await Promise.all(
list.keys.map((k) => c.env.RECIPES.get(k.name, "json"))
)).filter(Boolean);
const hasUuidVersion = new Set(all.filter((r) => r.uuid).map((r) => r.canonical_id));
const recipes = all.filter((r) => r.uuid || !hasUuidVersion.has(r.canonical_id));
return c.json({ success: true, recipes, count: recipes.length });
});
__name(fetchMarketStat, "fetchMarketStat");
__name(listAllRecipes, "listAllRecipes");
recipesRouter.get("/public-recipes", async (c) => {
const q = (c.req.query("q") ?? "").trim().toLowerCase();
const limit = Math.min(Number(c.req.query("limit") ?? 50), 200);
const offset = Number(c.req.query("offset") ?? 0);
const all = await listAllRecipes(c.env.RECIPES);
const matched = q ? all.filter((r) => r.canonical_id.toLowerCase().includes(q) || (r.display_name ?? "").toLowerCase().includes(q) || (r.description ?? "").toLowerCase().includes(q)) : all;
if (q && matched.length === 0) {
return c.json({
found: false,
query: q,
hint: `\u516C\u5EAB\u7121\u7B26\u5408\u300C${q}\u300D\u7684 recipe\u3002\u53EF\u81EA\u884C\u5EFA\u7ACB\u4E26 submit-p \u6295\u7A3F\u6210\u70BA\u4F5C\u8005\uFF08app-store \u6A21\u578B\uFF09\u3002`
});
}
const page = matched.slice(offset, offset + limit);
const withStats = await Promise.all(
page.map(async (r) => ({
uuid: r.uuid,
canonical_id: r.canonical_id,
author: r.author,
display_name: r.display_name,
description: r.description,
market_stat: await fetchMarketStat(c.env, r.uuid ?? r.canonical_id)
// §7.5.h per-uuid
}))
);
return c.json({ found: true, recipes: withStats, count: matched.length });
});
recipesRouter.get("/public-recipes/:canonical_id", async (c) => {
const canonicalId = c.req.param("canonical_id").trim().toLowerCase();
const author = c.req.query("author");
const all = await listAllRecipes(c.env.RECIPES);
let versions2 = all.filter((r) => r.canonical_id === canonicalId);
if (author) versions2 = versions2.filter((r) => r.author === author);
if (versions2.length === 0) {
return c.json({
found: false,
canonical_id: canonicalId,
hint: `\u516C\u5EAB\u7121 recipe\u300C${canonicalId}\u300D${author ? `\uFF08author=${author}\uFF09` : ""}\u3002\u53EF\u81EA\u884C\u5EFA\u7ACB\u4E26 submit-p \u6295\u7A3F\u6210\u70BA\u4F5C\u8005\uFF08app-store \u6A21\u578B\uFF09\u3002`
});
}
let best = versions2[0];
let bestStat = null;
let bestScore = -1;
for (const v of versions2) {
const stat = await fetchMarketStat(c.env, v.uuid ?? v.canonical_id);
const score = stat?.success_count ?? 0;
if (score > bestScore) {
bestScore = score;
best = v;
bestStat = stat;
}
}
return c.json({ found: true, recipe: best, market_stat: bestStat });
});
recipesRouter.delete("/recipes/:id", async (c) => {
const id = c.req.param("id");
const recipe = await resolveRecipe(id, c.env.RECIPES);
if (!recipe) return c.json({ success: false, error: `\u627E\u4E0D\u5230 recipe: ${id}` }, 404);
const canonicalId = recipe.canonical_id;
const ops = [
c.env.RECIPES.delete(`idx:${recipe.hash_id}`),
c.env.RECIPES.delete(`recipe:${canonicalId}`)
// 舊 key(若存在)
];
if (recipe.uuid) {
ops.push(c.env.RECIPES.delete(`recipe:${recipe.uuid}`));
const listRaw = await c.env.RECIPES.get(kIdxCanonical(canonicalId));
const uuids = listRaw ? JSON.parse(listRaw) : [];
const left = uuids.filter((u) => u !== recipe.uuid);
if (left.length > 0) {
ops.push(c.env.RECIPES.put(kIdxCanonical(canonicalId), JSON.stringify(left)));
const installed = await c.env.RECIPES.get(kIdxInstalled(canonicalId));
if (installed === recipe.uuid) ops.push(c.env.RECIPES.put(kIdxInstalled(canonicalId), left[0]));
} else {
ops.push(c.env.RECIPES.delete(kIdxCanonical(canonicalId)));
ops.push(c.env.RECIPES.delete(kIdxInstalled(canonicalId)));
}
}
await Promise.all(ops);
return c.json({ success: true, deleted: recipe.uuid ?? canonicalId });
});
__name(resolveRecipe, "resolveRecipe");
__name(resolveAuthRecipe, "resolveAuthRecipe");
recipesRouter.post("/auth-recipes", async (c) => {
let body;
try {
body = await c.req.json();
} catch {
return c.json({ success: false, error: "request body \u5FC5\u9808\u70BA JSON" }, 400);
}
const service = (body.service ?? "").trim().toLowerCase();
if (!service) return c.json({ success: false, error: "service \u5FC5\u586B" }, 400);
if (!body.primitive) return c.json({ success: false, error: "primitive \u5FC5\u586B" }, 400);
if (!body.base_url) return c.json({ success: false, error: "base_url \u5FC5\u586B" }, 400);
if (!body.required_secrets?.length) return c.json({ success: false, error: "required_secrets \u5FC5\u586B" }, 400);
if (!body.inject) return c.json({ success: false, error: "inject \u5FC5\u586B" }, 400);
const missingHelp = body.required_secrets.filter((s) => !s.help_url || !/^https?:\/\//.test(s.help_url));
if (missingHelp.length > 0) {
return c.json({
success: false,
error: `\u6BCF\u500B required_secret \u5FC5\u9808\u6709 help_url\uFF08\u5B98\u65B9\u6587\u4EF6\u9023\u7D50\uFF0Chttp(s)://\uFF09\u3002\u7F3A\uFF1A${missingHelp.map((s) => s.key).join(", ")}`,
requires: "help_url"
}, 400);
}
const now2 = Date.now();
const existing = await c.env.RECIPES.get(`auth_recipe:${service}`, "json");
const recipe = {
kind: "auth_recipe",
service,
version: body.version ?? 1,
primitive: body.primitive,
base_url: body.base_url,
display_name: body.display_name,
description: body.description,
service_account_kind: body.service_account_kind,
token_exchange: body.token_exchange,
required_secrets: body.required_secrets,
inject: body.inject,
created_at: existing?.created_at ?? now2,
updated_at: now2
};
await c.env.RECIPES.put(`auth_recipe:${service}`, JSON.stringify(recipe));
return c.json({ success: true, recipe });
});
recipesRouter.get("/auth-recipes", async (c) => {
const list = await c.env.RECIPES.list({ prefix: "auth_recipe:" });
const recipes = await Promise.all(
list.keys.map((k) => c.env.RECIPES.get(k.name, "json"))
);
return c.json({ success: true, recipes: recipes.filter(Boolean), count: recipes.length });
});
recipesRouter.get("/auth-recipes/:service", async (c) => {
const service = c.req.param("service");
const recipe = await resolveAuthRecipe(service, c.env.RECIPES);
if (!recipe) return c.json({ success: false, error: `\u627E\u4E0D\u5230 auth recipe: ${service}` }, 404);
return c.json({ success: true, recipe });
});
recipesRouter.delete("/auth-recipes/:service", async (c) => {
const service = c.req.param("service");
const recipe = await resolveAuthRecipe(service, c.env.RECIPES);
if (!recipe) return c.json({ success: false, error: `\u627E\u4E0D\u5230 auth recipe: ${service}` }, 404);
await c.env.RECIPES.delete(`auth_recipe:${service}`);
return c.json({ success: true, deleted: service });
});
}
});
// src/lib/constants.ts
var VALID_EDGE_TYPES, SEMANTIC_EDGE_MAP, BUILTIN_COMPONENTS;
var init_constants3 = __esm({
"src/lib/constants.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
VALID_EDGE_TYPES = /* @__PURE__ */ new Set([
// 現有
"PIPE",
"IF",
"FOREACH",
"CONTINUE",
// 新增:執行語意
"IS_A",
"ON_SUCCESS",
"ON_FAIL",
// 新增:條件語意(SDD workflow-discovery 3.11)—— 讀上游 if_control/switch 的 branch
"ON_TRUE",
"ON_FALSE",
"ON_BRANCH",
// 新增:觸發語意
"ON_CLICK",
"CALLS_SUBFLOW",
// 新增:結構語意(記錄圖結構,不執行)
"CONTAINS",
"HAS_STYLE",
"HAS_BEHAVIOR"
]);
SEMANTIC_EDGE_MAP = {
// 中文語意詞
"\u5B8C\u6210\u5F8C": "PIPE",
"\u5931\u6557\u6642": "ON_FAIL",
"\u5C0D\u6BCF\u500B": "FOREACH",
"\u689D\u4EF6\u6EFF\u8DB3\u6642": "IF",
// 條件分支語意(SDD workflow-discovery 3.11):讓意圖工作流寫得出兩條路
"\u6210\u7ACB\u6642": "ON_TRUE",
"\u70BA\u771F\u6642": "ON_TRUE",
"\u4E0D\u6210\u7ACB\u6642": "ON_FALSE",
"\u70BA\u5047\u6642": "ON_FALSE",
"\u5426\u5247": "ON_FALSE",
// 英文別名
"SUCCESS": "ON_SUCCESS",
"FAIL": "ON_FAIL",
"TRUE": "ON_TRUE",
"FALSE": "ON_FALSE",
"ELSE": "ON_FALSE",
"BRANCH": "ON_BRANCH",
"CLICK": "ON_CLICK",
"SUBFLOW": "CALLS_SUBFLOW"
};
BUILTIN_COMPONENTS = /* @__PURE__ */ new Map([
["comp_passthrough", (ctx) => ctx],
["comp_uppercase", (ctx) => {
const c = ctx;
return { ...c, text: String(c.text || "").toUpperCase() };
}],
["comp_counter", (ctx) => {
const c = ctx;
return { ...c, count: (Number(c.count) || 0) + 1 };
}]
]);
}
});
// src/lib/recipe-payload.ts
function getPath2(obj, path) {
let cur = obj;
for (const part of path.split(".")) {
if (cur === null || cur === void 0) return void 0;
if (typeof cur !== "object") return void 0;
cur = cur[part];
}
return cur;
}
function renderBodyTemplate(template, ctx) {
if (template === void 0 || template === null) return void 0;
return renderValue(template, ctx);
}
function renderValue(v, ctx) {
if (typeof v === "string") return renderString(v, ctx);
if (Array.isArray(v)) return v.map((item) => renderValue(item, ctx));
if (v !== null && typeof v === "object") {
const out = {};
for (const [k, val] of Object.entries(v)) {
out[k] = renderValue(val, ctx);
}
return out;
}
return v;
}
function renderString(s, ctx) {
const single = s.match(/^\s*\{\{([\w.]+)\}\}\s*$/);
if (single) {
const val = getPath2(ctx, single[1]);
return val === void 0 ? s : val;
}
return s.replace(/\{\{([\w.]+)\}\}/g, (_, key) => {
const val = getPath2(ctx, key);
if (val === void 0) return `{{${key}}}`;
return typeof val === "string" ? val : JSON.stringify(val);
});
}
function applyResponseMap(body, map) {
if (!map) return { raw: body };
let picked = map.text_path ? getPath2(body, map.text_path) : body;
if (map.thinking_model && Array.isArray(picked)) {
const real = picked.filter(
(p) => !(p && typeof p === "object" && p.thought === true)
);
const last = real[real.length - 1];
picked = last && typeof last === "object" ? last.text : last;
}
if (typeof picked !== "string") return { text: void 0, raw: body };
return { text: sanitize(picked, map), raw: body };
}
function sanitize(input, map) {
let s = input.trim();
if (map.answer_marker) {
const idx = s.lastIndexOf(map.answer_marker);
if (idx >= 0) s = s.slice(idx + map.answer_marker.length);
}
const prefixes = map.strip_prefixes ?? [];
if (prefixes.length > 0) {
let changed = true;
while (changed) {
changed = false;
s = s.trimStart();
for (const p of prefixes) {
if (p && s.startsWith(p)) {
s = s.slice(p.length);
changed = true;
}
}
}
}
return s.trim();
}
var init_recipe_payload = __esm({
"src/lib/recipe-payload.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(getPath2, "getPath");
__name(renderBodyTemplate, "renderBodyTemplate");
__name(renderValue, "renderValue");
__name(renderString, "renderString");
__name(applyResponseMap, "applyResponseMap");
__name(sanitize, "sanitize");
}
});
// src/lib/component-loader.ts
function wasmWorkerUrl(canonicalId, subdomain) {
const kebab = canonicalId.replace(/_/g, "-");
return `https://arcrun-${kebab}.${subdomain}.workers.dev`;
}
function createComponentLoader(env2) {
return async (componentId) => {
if (componentId === "trigger_workflow") {
return makeTriggerWorkflowRunner(env2);
}
const builtin = BUILTIN_COMPONENTS.get(componentId);
if (builtin) return builtin;
if (componentId.startsWith("http://") || componentId.startsWith("https://")) {
return makeHttpRunner(componentId);
}
if (isComponentHash(componentId)) {
const canonicalId = await env2.WEBHOOKS.get(`idx:${componentId}`);
if (canonicalId) {
const runner = makeLogicRunner(canonicalId, env2);
if (runner) return runner;
}
throw new Error(`\u627E\u4E0D\u5230\u96F6\u4EF6 hash "${componentId}"\uFF0C\u8ACB\u78BA\u8A8D\u5DF2\u900F\u904E acr push \u4E0A\u50B3`);
}
if (isRecipeHash(componentId)) {
const recipe = await resolveRecipe(componentId, env2.RECIPES);
if (recipe) return pickRecipeRunner(recipe, env2);
throw new Error(`\u627E\u4E0D\u5230 recipe hash "${componentId}"\uFF0C\u8ACB\u78BA\u8A8D\u5DF2\u900F\u904E acr push \u4E0A\u50B3`);
}
const logicRunner = makeLogicRunner(componentId, env2);
if (logicRunner) return logicRunner;
const authRecipe = await resolveAuthRecipe(componentId, env2.RECIPES);
if (authRecipe) return makeAuthRecipeRunner(authRecipe);
const kvRecipe = await resolveRecipe(componentId, env2.RECIPES);
if (kvRecipe) return pickRecipeRunner(kvRecipe, env2);
if (WASM_HTTP_RUNNER_IDS.has(componentId)) {
return makeHttpRunner(wasmWorkerUrl(componentId, env2.WORKER_SUBDOMAIN));
}
throw new Error(
`\u627E\u4E0D\u5230\u96F6\u4EF6 "${componentId}"\u3002
\u908F\u8F2F\u96F6\u4EF6\uFF1A${Object.keys(LOGIC_BINDING_MAP).join(", ")}
\u6216\u50B3\u5165\u5916\u90E8 URL\uFF08https://...\uFF09\u3001recipe hash\uFF08rec_xxxxxxxx\uFF09\u3001\u96F6\u4EF6 hash\uFF08cmp_xxxxxxxx\uFF09`
);
};
}
function makeTriggerWorkflowRunner(env2) {
return async (ctx) => {
const c = ctx && typeof ctx === "object" ? ctx : {};
const workflowName = String(c.workflow_name ?? "");
const apiKey = String(c.api_key ?? "");
const input = c.input && typeof c.input === "object" ? c.input : {};
const wait = c.wait !== false;
if (!workflowName) return { success: false, error: "trigger_workflow \u7F3A workflow_name" };
if (!apiKey) return { success: false, error: "trigger_workflow \u7F3A api_key" };
const wfKey = `${apiKey}:wf:${workflowName}`;
const wfRaw = await env2.WEBHOOKS.get(wfKey, "text");
if (!wfRaw) return { success: false, error: `\u627E\u4E0D\u5230 workflow "${workflowName}" (key=${wfKey})` };
let record;
try {
record = JSON.parse(wfRaw);
} catch {
return { success: false, error: `workflow "${workflowName}" KV \u5167\u5BB9\u975E JSON` };
}
if (!record.graph) return { success: false, error: `workflow "${workflowName}" \u7F3A graph \u6B04\u4F4D` };
const { executeWebhookGraph: executeWebhookGraph2 } = await Promise.resolve().then(() => (init_webhook_handlers(), webhook_handlers_exports));
const triggerContext = { ...input, _triggered_by: "trigger_workflow" };
if (wait) {
const r = await executeWebhookGraph2(env2, record.graph, triggerContext, workflowName, apiKey);
const isPaused = !r.success && typeof r.error === "string" && /workflow paused/i.test(r.error);
return {
success: r.success || isPaused,
triggered_workflow: workflowName,
status: r.success ? "completed" : isPaused ? "running_async" : "failed",
sub_result: r
};
} else {
void executeWebhookGraph2(env2, record.graph, triggerContext, workflowName, apiKey).catch((e) => console.error("[trigger_workflow] fire-and-forget fail", workflowName, e));
return { success: true, triggered_workflow: workflowName, mode: "fire_and_forget" };
}
};
}
function makeHttpRunner(url) {
return async (ctx) => {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(ctx)
});
if (!res.ok) {
const text = await res.text();
return { success: false, status: res.status, error: text.slice(0, 200) };
}
try {
return await res.json();
} catch {
return { success: true, data: await res.text() };
}
};
}
function makeLogicRunner(canonicalId, env2) {
const bindingKey = LOGIC_BINDING_MAP[canonicalId];
if (!bindingKey) return null;
const svc = env2[bindingKey];
if (svc) {
return async (ctx) => {
const res = await svc.fetch(new Request("https://component/", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(ctx)
}));
if (!res.ok) {
const text = await res.text();
return { success: false, error: `${canonicalId} \u56DE\u50B3 ${res.status}: ${text.slice(0, 200)}` };
}
try {
return await res.json();
} catch {
return { success: false, error: `${canonicalId} \u56DE\u50B3\u975E JSON` };
}
};
}
return makeHttpRunner(wasmWorkerUrl(canonicalId, env2.WORKER_SUBDOMAIN));
}
function pickRecipeRunner(recipe, env2) {
return recipe.auth === "binding" ? makeBindingRecipeRunner(recipe, env2) : makeRecipeRunner(recipe);
}
function makeBindingRecipeRunner(recipe, env2) {
return async (ctx) => {
const ctxObj = ctx && typeof ctx === "object" ? ctx : {};
const name = recipe.binding_name ?? "AI";
const binding2 = env2[name];
if (!binding2) {
return {
success: false,
error: `recipe "${recipe.canonical_id}" \u5BA3\u544A auth: binding\u3001binding_name: "${name}"\uFF0C\u4F46\u9019\u500B\u90E8\u7F72\u6C92\u6709\u7D81\u5B9A ${name}\u3002\u8ACB\u5728 wrangler.toml \u88DC\u4E0A\u8A72 binding \u5F8C\u91CD\u65B0\u90E8\u7F72\u3002`
};
}
const target = recipe.endpoint;
const payload = renderBodyTemplate(recipe.body_template ?? recipe.body, ctxObj) ?? Object.fromEntries(Object.entries(ctxObj).filter(([k]) => !k.startsWith("_")));
try {
const runner = binding2;
if (typeof runner.run !== "function") {
return {
success: false,
error: `binding "${name}" \u6C92\u6709 run() \u65B9\u6CD5\uFF0C\u76EE\u524D binding \u578B\u53EA\u652F\u63F4 run(model, input) \u5F62\u72C0\uFF08\u5982 env.AI\uFF09\u3002`
};
}
const data = await runner.run(target, payload);
if (recipe.response_map) {
const normalized = applyResponseMap(data, recipe.response_map);
return { success: true, data, text: normalized.text };
}
return { success: true, data };
} catch (e) {
return {
success: false,
error: `binding "${name}" \u547C\u53EB\u5931\u6557\uFF08${target}\uFF09\uFF1A${e instanceof Error ? e.message : String(e)}`
};
}
};
}
function makeRecipeRunner(recipe) {
return async (ctx) => {
const ctxObj = ctx && typeof ctx === "object" ? ctx : {};
const authPath = ctxObj._auth_path ?? {};
const interpolate2 = /* @__PURE__ */ __name((s) => s.replace(
/\{\{(auth\.)?(\w+)\}\}/g,
(_, authPrefix, k) => String(authPrefix ? authPath[k] ?? "" : ctxObj[k] ?? "")
), "interpolate");
const method = (recipe.method ?? "POST").toUpperCase();
const authHeaders = ctxObj._auth_headers ?? {};
const headers = {
"Content-Type": "application/json",
...authHeaders
};
for (const [k, v] of Object.entries(recipe.headers ?? {})) {
headers[k] = interpolate2(v);
}
let bodyStr;
if (recipe.body_template) {
bodyStr = JSON.stringify(renderBodyTemplate(recipe.body_template, ctxObj));
} else if (recipe.body) {
bodyStr = interpolate2(JSON.stringify(recipe.body));
} else if (method !== "GET") {
const bodyObj = Object.fromEntries(
Object.entries(ctxObj).filter(([k]) => !k.startsWith("_"))
);
bodyStr = JSON.stringify(bodyObj);
}
const res = await fetch(interpolate2(recipe.endpoint), {
method,
headers,
body: bodyStr
});
const data = await readBodyOnce(res);
if (recipe.response_map) {
const normalized = applyResponseMap(data, recipe.response_map);
return { success: res.ok, status: res.status, data, text: normalized.text };
}
return { success: res.ok, status: res.status, data };
};
}
function makeAuthRecipeRunner(recipe) {
return async (ctx) => {
const ctxObj = ctx && typeof ctx === "object" ? ctx : {};
const authHeaders = ctxObj._auth_headers ?? {};
const authQuery = ctxObj._auth_query ?? {};
const path = typeof ctxObj._path === "string" ? ctxObj._path : "";
const method = (ctxObj.method ?? "POST").toUpperCase();
const url = new URL(recipe.base_url.replace(/\/$/, "") + path);
for (const [k, v] of Object.entries(authQuery)) {
url.searchParams.set(k, v);
}
const headers = {
"Content-Type": "application/json",
...authHeaders
};
const bodyObj = Object.fromEntries(
Object.entries(ctxObj).filter(([k]) => !k.startsWith("_") && k !== "method")
);
const res = await fetch(url.toString(), {
method,
headers,
body: method !== "GET" ? JSON.stringify(bodyObj) : void 0
});
const data = await readBodyOnce(res);
return { success: res.ok, status: res.status, data };
};
}
async function readBodyOnce(res) {
const text = await res.text();
try {
return JSON.parse(text);
} catch {
return text;
}
}
var WASM_HTTP_RUNNER_IDS, LOGIC_BINDING_MAP;
var init_component_loader = __esm({
"src/lib/component-loader.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_constants3();
init_hash();
init_recipes();
init_recipe_payload();
WASM_HTTP_RUNNER_IDS = /* @__PURE__ */ new Set([
// 通用 HTTP 零件
"http_request",
// 通用 code 零件(sandbox inline JS,Arcrun#10 / 07-thin-shell §3.5 code-node):獨立 Worker,
// URL 走 wasmWorkerUrl 通用推導(arcrun-code.{WORKER_SUBDOMAIN}.workers.dev,
// self-hosted 由 WORKER_SUBDOMAIN var 注入自己的 subdomain,無寫死官方域名)。
// 漏這行 = workflow 寫 `component: code` 落到 step 8 直接「找不到零件」(#29 發現)。
"code",
// gmail / telegram / line_notify / google_sheets 已降級為 recipe(2026-05-29 Phase 2):
// recipe:gmail_send / telegram_send / line_notify_send / google_sheets_read|append
// 走 step 6 KV recipe 解析,不再是零件。零件目錄已刪。
"cron",
// Auth primitives
"auth_static_key",
"auth_service_account",
"auth_oauth2",
"auth_mtls"
]);
__name(wasmWorkerUrl, "wasmWorkerUrl");
LOGIC_BINDING_MAP = {
if_control: "SVC_IF_CONTROL",
switch: "SVC_SWITCH",
foreach_control: "SVC_FOREACH_CONTROL",
filter: "SVC_FILTER",
merge: "SVC_MERGE",
try_catch: "SVC_TRY_CATCH",
wait: "SVC_WAIT",
set: "SVC_SET",
array_ops: "SVC_ARRAY_OPS",
string_ops: "SVC_STRING_OPS",
number_ops: "SVC_NUMBER_OPS",
date_ops: "SVC_DATE_OPS",
validate_json: "SVC_VALIDATE_JSON"
// ai_transform_compile / ai_transform_run 已刪除(2026-05-29):
// Arcrun 是 AI 呼叫的工具,工作流不該內嵌 AI 節點回頭呼叫 AI(n8n 才需要,因它沒大腦)。
};
__name(createComponentLoader, "createComponentLoader");
__name(makeTriggerWorkflowRunner, "makeTriggerWorkflowRunner");
__name(makeHttpRunner, "makeHttpRunner");
__name(makeLogicRunner, "makeLogicRunner");
__name(pickRecipeRunner, "pickRecipeRunner");
__name(makeBindingRecipeRunner, "makeBindingRecipeRunner");
__name(makeRecipeRunner, "makeRecipeRunner");
__name(makeAuthRecipeRunner, "makeAuthRecipeRunner");
__name(readBodyOnce, "readBodyOnce");
}
});
// src/lib/wasi-shim.ts
async function routedKvGet(env2, apiKey, key) {
if (key.startsWith("auth_recipe:")) {
return env2.RECIPES.get(key);
}
const credMatch = key.match(/^([^:]+):cred:.+$/);
if (credMatch) {
if (credMatch[1] !== apiKey) {
return null;
}
return env2.CREDENTIALS_KV.get(key);
}
return null;
}
async function routedKvPut(env2, apiKey, key, value, ttlSeconds) {
const oauth2Match = key.match(/^([^:]+):oauth2:.+$/);
if (oauth2Match && oauth2Match[1] === apiKey) {
const opts = ttlSeconds > 0 ? { expirationTtl: ttlSeconds } : void 0;
await env2.CREDENTIALS_KV.put(key, value, opts);
return;
}
}
async function rsaPkcs1Sha256Sign(data, pkcs8) {
const cryptoKey = await crypto.subtle.importKey(
"pkcs8",
pkcs8,
{ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" },
false,
["sign"]
);
const sig = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", cryptoKey, data);
return new Uint8Array(sig);
}
function secretGet(env2, ref) {
if (!/^CRED_/.test(ref)) return null;
const value = env2[ref];
return typeof value === "string" ? value : null;
}
function createArcrunHostFunctions(env2, apiKey) {
return {
kv_get: /* @__PURE__ */ __name((key) => routedKvGet(env2, apiKey, key), "kv_get"),
kv_put: /* @__PURE__ */ __name((key, value, ttlSeconds) => routedKvPut(env2, apiKey, key, value, ttlSeconds), "kv_put"),
crypto_sign_rs256: /* @__PURE__ */ __name((data, pkcs8) => rsaPkcs1Sha256Sign(data, pkcs8), "crypto_sign_rs256"),
secret_get: /* @__PURE__ */ __name(async (ref) => secretGet(env2, ref), "secret_get")
};
}
var init_wasi_shim = __esm({
"src/lib/wasi-shim.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(routedKvGet, "routedKvGet");
__name(routedKvPut, "routedKvPut");
__name(rsaPkcs1Sha256Sign, "rsaPkcs1Sha256Sign");
__name(secretGet, "secretGet");
__name(createArcrunHostFunctions, "createArcrunHostFunctions");
}
});
// src/actions/auth-dispatcher.ts
async function resolveSecretsFromNewHome(env2, apiKey, names) {
const resolved = {};
if (names.length === 0) return resolved;
const db = env2.CREDENTIALS_DB;
if (!db) return resolved;
let rows;
try {
const placeholders = names.map(() => "?").join(", ");
const result = await db.prepare(
`SELECT name, secret_ref FROM credentials
WHERE api_key = ? AND name IN (${placeholders})`
).bind(apiKey, ...names).all();
rows = result.results ?? [];
} catch {
return resolved;
}
if (rows.length === 0) return resolved;
const secretGet2 = createArcrunHostFunctions(env2, apiKey).secret_get;
if (!secretGet2) return resolved;
const resolvedNames = [];
for (const row of rows) {
const value = await secretGet2(row.secret_ref);
if (value === null) continue;
resolved[row.name] = value;
resolvedNames.push(row.name);
}
if (resolvedNames.length > 0) {
try {
const now2 = Math.floor(Date.now() / 1e3);
const placeholders = resolvedNames.map(() => "?").join(", ");
await db.prepare(
`UPDATE credentials SET last_used_at = ?
WHERE api_key = ? AND name IN (${placeholders})`
).bind(now2, apiKey, ...resolvedNames).run();
} catch {
}
}
return resolved;
}
async function tryAuthDispatch(componentId, input, env2, apiKey) {
if (AUTH_PRIMITIVE_IDS.has(componentId)) {
return null;
}
let service = componentId;
const apiRecipe = await resolveRecipe(componentId, env2.RECIPES);
if (apiRecipe?.auth_service) {
service = apiRecipe.auth_service;
}
const recipe = await resolveAuthRecipe(service, env2.RECIPES);
if (!recipe) return null;
if (!SUPPORTED_PRIMITIVES.has(recipe.primitive)) return null;
const secretNames = recipe.required_secrets.filter((s) => !s.optional).map((s) => s.key);
const resolvedSecrets = await resolveSecretsFromNewHome(env2, apiKey, secretNames);
const primitiveUrl = wasmWorkerUrl(`auth_${recipe.primitive}`, env2.WORKER_SUBDOMAIN);
const res = await fetch(primitiveUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: "authenticate",
api_key: apiKey,
service,
// 只在有取到值時帶上(空物件也無妨,WASM 對 nil/空 map 同樣 fallback)
resolved_secrets: resolvedSecrets
})
});
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(
`auth primitive "${recipe.primitive}" \u56DE\u50B3 ${res.status}: ${text.slice(0, 200)}`
);
}
const result = await res.json().catch(() => null);
if (!result || result.success === false) {
throw new Error(
`auth primitive \u5931\u6557: ${result?.error ?? "\u672A\u77E5\u932F\u8AA4"}`
);
}
return {
...input,
_auth_headers: result.auth_headers ?? {},
_auth_query: result.auth_query ?? {},
_auth_body: result.auth_body ?? {},
_auth_path: result.auth_path ?? {}
};
}
function collectCredentialNames(value, out) {
if (typeof value === "string") {
for (const m of value.matchAll(CREDENTIAL_REF)) out.add(m[1]);
} else if (Array.isArray(value)) {
for (const v of value) collectCredentialNames(v, out);
} else if (value && typeof value === "object") {
for (const v of Object.values(value)) collectCredentialNames(v, out);
}
}
function replaceCredentialRefs(value, resolved) {
if (typeof value === "string") {
return value.replace(
CREDENTIAL_REF,
(orig, name) => Object.prototype.hasOwnProperty.call(resolved, name) ? resolved[name] : orig
);
}
if (Array.isArray(value)) return value.map((v) => replaceCredentialRefs(v, resolved));
if (value && typeof value === "object") {
const out = {};
for (const [k, v] of Object.entries(value)) {
out[k] = replaceCredentialRefs(v, resolved);
}
return out;
}
return value;
}
async function resolveCredentialRefs(data, env2, apiKey) {
const names = /* @__PURE__ */ new Set();
collectCredentialNames(data, names);
if (names.size === 0) return data;
const nameList = [...names];
const resolvedSecrets = await resolveSecretsFromNewHome(env2, apiKey, nameList);
const url = wasmWorkerUrl("auth_static_key", env2.WORKER_SUBDOMAIN);
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: "resolve_credentials",
api_key: apiKey,
names: nameList,
resolved_secrets: resolvedSecrets
})
});
if (!res.ok) {
const text = await res.text().catch(() => "");
throw new Error(`credential resolve \u56DE\u50B3 ${res.status}: ${text.slice(0, 200)}`);
}
const result = await res.json().catch(() => null);
if (!result || result.success === false) {
throw new Error(`credential resolve \u5931\u6557: ${result?.error ?? "\u672A\u77E5\u932F\u8AA4"}`);
}
return replaceCredentialRefs(data, result.credentials ?? {});
}
var SUPPORTED_PRIMITIVES, AUTH_PRIMITIVE_IDS, CREDENTIAL_REF;
var init_auth_dispatcher = __esm({
"src/actions/auth-dispatcher.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_recipes();
init_component_loader();
init_wasi_shim();
__name(resolveSecretsFromNewHome, "resolveSecretsFromNewHome");
SUPPORTED_PRIMITIVES = /* @__PURE__ */ new Set(["static_key", "service_account", "oauth2"]);
AUTH_PRIMITIVE_IDS = /* @__PURE__ */ new Set([
"auth_static_key",
"auth_service_account",
"auth_oauth2",
"auth_mtls"
]);
__name(tryAuthDispatch, "tryAuthDispatch");
CREDENTIAL_REF = /\{\{credential\.(\w+)\}\}/g;
__name(collectCredentialNames, "collectCredentialNames");
__name(replaceCredentialRefs, "replaceCredentialRefs");
__name(resolveCredentialRefs, "resolveCredentialRefs");
}
});
// node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.mjs
function setErrorMap(map) {
overrideErrorMap = map;
}
function getErrorMap() {
return overrideErrorMap;
}
function addIssueToContext(ctx, issueData) {
const overrideMap = getErrorMap();
const issue = makeIssue({
issueData,
data: ctx.data,
path: ctx.path,
errorMaps: [
ctx.common.contextualErrorMap,
ctx.schemaErrorMap,
overrideMap,
overrideMap === errorMap ? void 0 : errorMap
// then global default map
].filter((x) => !!x)
});
ctx.common.issues.push(issue);
}
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
}
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 (errorMap2)
return { errorMap: errorMap2, description };
const customMap = /* @__PURE__ */ __name((iss, ctx) => {
var _a, _b;
const { message } = params;
if (iss.code === "invalid_enum_value") {
return { message: message !== null && message !== void 0 ? message : ctx.defaultError };
}
if (typeof ctx.data === "undefined") {
return { message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError };
}
if (iss.code !== "invalid_type")
return { message: ctx.defaultError };
return { message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError };
}, "customMap");
return { errorMap: customMap, description };
}
function timeRegexSource(args) {
let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`;
if (args.precision) {
regex = `${regex}\\.\\d{${args.precision}}`;
} else if (args.precision == null) {
regex = `${regex}(\\.\\d+)?`;
}
return regex;
}
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, version2) {
if ((version2 === "v4" || !version2) && ipv4Regex.test(ip)) {
return true;
}
if ((version2 === "v6" || !version2) && ipv6Regex.test(ip)) {
return true;
}
return false;
}
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 = parseInt(val.toFixed(decCount).replace(".", ""));
const stepInt = parseInt(step.toFixed(decCount).replace(".", ""));
return valInt % stepInt / Math.pow(10, decCount);
}
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));
}
return new ZodObject({
...schema._def,
shape: /* @__PURE__ */ __name(() => newShape, "shape")
});
} 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;
}
}
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;
}
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);
}
return { valid: true, data: newArray };
} else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a === +b) {
return { valid: true, data: a };
} else {
return { valid: false };
}
}
function createZodEnum(values, params) {
return new ZodEnum({
values,
typeName: ZodFirstPartyTypeKind.ZodEnum,
...processCreateParams(params)
});
}
function custom(check, params = {}, fatal) {
if (check)
return ZodAny.create().superRefine((data, ctx) => {
var _a, _b;
if (!check(data)) {
const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
const p2 = typeof p === "string" ? { message: p } : p;
ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
}
});
return ZodAny.create();
}
var util, objectUtil, ZodParsedType, getParsedType, ZodIssueCode, quotelessJson, ZodError, errorMap, overrideErrorMap, makeIssue, EMPTY_PATH, ParseStatus, INVALID, DIRTY, OK, isAborted, isDirty, isValid, isAsync, errorUtil, _ZodEnum_cache, _ZodNativeEnum_cache, ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv6Regex, base64Regex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, BRAND, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, instanceOfType, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, ostring, onumber, oboolean, coerce, NEVER, z;
var init_lib = __esm({
"node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.mjs"() {
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
(function(util2) {
util2.assertEqual = (val) => val;
function assertIs(_arg) {
}
__name(assertIs, "assertIs");
util2.assertIs = assertIs;
function assertNever(_x) {
throw new Error();
}
__name(assertNever, "assertNever");
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) : (object) => {
const keys = [];
for (const key in object) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
keys.push(key);
}
}
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" && isFinite(val) && Math.floor(val) === val;
function joinValues(array, separator = " | ") {
return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
}
__name(joinValues, "joinValues");
util2.joinValues = joinValues;
util2.jsonStringifyReplacer = (_, value) => {
if (typeof value === "bigint") {
return value.toString();
}
return value;
};
})(util || (util = {}));
(function(objectUtil2) {
objectUtil2.mergeShapes = (first, second) => {
return {
...first,
...second
// second overwrites first
};
};
})(objectUtil || (objectUtil = {}));
ZodParsedType = util.arrayToEnum([
"string",
"nan",
"number",
"integer",
"float",
"boolean",
"date",
"bigint",
"symbol",
"function",
"undefined",
"null",
"array",
"object",
"unknown",
"promise",
"void",
"never",
"map",
"set"
]);
getParsedType = /* @__PURE__ */ __name((data) => {
const t = typeof data;
switch (t) {
case "undefined":
return ZodParsedType.undefined;
case "string":
return ZodParsedType.string;
case "number":
return 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;
}
}, "getParsedType");
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"
]);
quotelessJson = /* @__PURE__ */ __name((obj) => {
const json = JSON.stringify(obj, null, 2);
return json.replace(/"([^"]+)":/g, "$1:");
}, "quotelessJson");
ZodError = class _ZodError extends Error {
static {
__name(this, "ZodError");
}
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 {
this.__proto__ = actualProto;
}
this.name = "ZodError";
this.issues = issues;
}
get errors() {
return this.issues;
}
format(_mapper) {
const mapper = _mapper || function(issue) {
return issue.message;
};
const fieldErrors = { _errors: [] };
const processError = /* @__PURE__ */ __name((error3) => {
for (const issue of error3.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");
processError(this);
return fieldErrors;
}
static assert(value) {
if (!(value instanceof _ZodError)) {
throw new Error(`Not a ZodError: ${value}`);
}
}
toString() {
return this.message;
}
get message() {
return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
}
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) {
fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
fieldErrors[sub.path[0]].push(mapper(sub));
} else {
formErrors.push(mapper(sub));
}
}
return { formErrors, fieldErrors };
}
get formErrors() {
return this.flatten();
}
};
ZodError.create = (issues) => {
const error3 = new ZodError(issues);
return error3;
};
errorMap = /* @__PURE__ */ __name((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}`;
}
} 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}`;
} else {
message = "Invalid";
}
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 === "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 };
}, "errorMap");
overrideErrorMap = errorMap;
__name(setErrorMap, "setErrorMap");
__name(getErrorMap, "getErrorMap");
makeIssue = /* @__PURE__ */ __name((params) => {
const { data, path, errorMaps, issueData } = params;
const fullPath = [...path, ...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
};
}, "makeIssue");
EMPTY_PATH = [];
__name(addIssueToContext, "addIssueToContext");
ParseStatus = class _ParseStatus {
static {
__name(this, "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 _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;
}
}
return { status: status.value, value: finalObject };
}
};
INVALID = Object.freeze({
status: "aborted"
});
DIRTY = /* @__PURE__ */ __name((value) => ({ status: "dirty", value }), "DIRTY");
OK = /* @__PURE__ */ __name((value) => ({ status: "valid", value }), "OK");
isAborted = /* @__PURE__ */ __name((x) => x.status === "aborted", "isAborted");
isDirty = /* @__PURE__ */ __name((x) => x.status === "dirty", "isDirty");
isValid = /* @__PURE__ */ __name((x) => x.status === "valid", "isValid");
isAsync = /* @__PURE__ */ __name((x) => typeof Promise !== "undefined" && x instanceof Promise, "isAsync");
__name(__classPrivateFieldGet, "__classPrivateFieldGet");
__name(__classPrivateFieldSet, "__classPrivateFieldSet");
(function(errorUtil2) {
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
errorUtil2.toString = (message) => typeof message === "string" ? message : message === null || message === void 0 ? void 0 : message.message;
})(errorUtil || (errorUtil = {}));
ParseInputLazyPath = class {
static {
__name(this, "ParseInputLazyPath");
}
constructor(parent, value, path, key) {
this._cachedPath = [];
this.parent = parent;
this.data = value;
this._path = path;
this._key = key;
}
get path() {
if (!this._cachedPath.length) {
if (this._key instanceof Array) {
this._cachedPath.push(...this._path, ...this._key);
} else {
this._cachedPath.push(...this._path, this._key);
}
}
return this._cachedPath;
}
};
handleResult = /* @__PURE__ */ __name((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 error3 = new ZodError(ctx.common.issues);
this._error = error3;
return this._error;
}
};
}
}, "handleResult");
__name(processCreateParams, "processCreateParams");
ZodType = class {
static {
__name(this, "ZodType");
}
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);
}
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;
}
_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;
}
safeParse(data, params) {
var _a;
const ctx = {
common: {
issues: [],
async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,
contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap
},
path: (params === null || params === void 0 ? void 0 : 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);
}
async parseAsync(data, params) {
const result = await this.safeParseAsync(data, params);
if (result.success)
return result.data;
throw result.error;
}
async safeParseAsync(data, params) {
const ctx = {
common: {
issues: [],
contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,
async: true
},
path: (params === null || params === void 0 ? void 0 : 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);
}
refine(check, message) {
const getIssueProperties = /* @__PURE__ */ __name((val) => {
if (typeof message === "string" || typeof message === "undefined") {
return { message };
} else if (typeof message === "function") {
return message(val);
} else {
return message;
}
}, "getIssueProperties");
return this._refinement((val, ctx) => {
const result = check(val);
const setError = /* @__PURE__ */ __name(() => ctx.addIssue({
code: ZodIssueCode.custom,
...getIssueProperties(val)
}), "setError");
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;
}
});
}
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;
}
});
}
_refinement(refinement) {
return new ZodEffects({
schema: this,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect: { type: "refinement", refinement }
});
}
superRefine(refinement) {
return this._refinement(refinement);
}
optional() {
return ZodOptional.create(this, this._def);
}
nullable() {
return ZodNullable.create(this, this._def);
}
nullish() {
return this.nullable().optional();
}
array() {
return ZodArray.create(this, this._def);
}
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 }
});
}
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,
description
});
}
pipe(target) {
return ZodPipeline.create(this, target);
}
readonly() {
return ZodReadonly.create(this);
}
isOptional() {
return this.safeParse(void 0).success;
}
isNullable() {
return this.safeParse(null).success;
}
};
cuidRegex = /^c[^\s-]{8,}$/i;
cuid2Regex = /^[0-9a-z]+$/;
ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/;
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;
nanoidRegex = /^[a-z0-9_-]{21}$/i;
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)?)??$/;
emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
_emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
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])$/;
ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;
base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
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])))`;
dateRegex = new RegExp(`^${dateRegexSource}$`);
__name(timeRegexSource, "timeRegexSource");
__name(timeRegex, "timeRegex");
__name(datetimeRegex, "datetimeRegex");
__name(isValidIP, "isValidIP");
ZodString = class _ZodString extends ZodType {
static {
__name(this, "ZodString");
}
_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();
}
} 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") {
try {
new URL(input.data);
} catch (_a) {
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 === "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 {
util.assertNever(check);
}
}
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) });
}
ip(options) {
return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
}
datetime(options) {
var _a, _b;
if (typeof options === "string") {
return this._addCheck({
kind: "datetime",
precision: null,
offset: false,
local: false,
message: options
});
}
return this._addCheck({
kind: "datetime",
precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision,
offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,
local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false,
...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message)
});
}
date(message) {
return this._addCheck({ kind: "date", message });
}
time(options) {
if (typeof options === "string") {
return this._addCheck({
kind: "time",
precision: null,
message: options
});
}
return this._addCheck({
kind: "time",
precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision,
...errorUtil.errToObj(options === null || options === void 0 ? void 0 : 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 === null || options === void 0 ? void 0 : options.position,
...errorUtil.errToObj(options === null || options === void 0 ? void 0 : 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)
});
}
/**
* @deprecated Use z.string().min(1) instead.
* @see {@link ZodString.min}
*/
nonempty(message) {
return this.min(1, errorUtil.errToObj(message));
}
trim() {
return new _ZodString({
...this._def,
checks: [...this._def.checks, { kind: "trim" }]
});
}
toLowerCase() {
return new _ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toLowerCase" }]
});
}
toUpperCase() {
return new _ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toUpperCase" }]
});
}
get isDatetime() {
return !!this._def.checks.find((ch) => ch.kind === "datetime");
}
get isDate() {
return !!this._def.checks.find((ch) => ch.kind === "date");
}
get isTime() {
return !!this._def.checks.find((ch) => ch.kind === "time");
}
get isDuration() {
return !!this._def.checks.find((ch) => ch.kind === "duration");
}
get isEmail() {
return !!this._def.checks.find((ch) => ch.kind === "email");
}
get isURL() {
return !!this._def.checks.find((ch) => ch.kind === "url");
}
get isEmoji() {
return !!this._def.checks.find((ch) => ch.kind === "emoji");
}
get isUUID() {
return !!this._def.checks.find((ch) => ch.kind === "uuid");
}
get isNANOID() {
return !!this._def.checks.find((ch) => ch.kind === "nanoid");
}
get isCUID() {
return !!this._def.checks.find((ch) => ch.kind === "cuid");
}
get isCUID2() {
return !!this._def.checks.find((ch) => ch.kind === "cuid2");
}
get isULID() {
return !!this._def.checks.find((ch) => ch.kind === "ulid");
}
get isIP() {
return !!this._def.checks.find((ch) => ch.kind === "ip");
}
get isBase64() {
return !!this._def.checks.find((ch) => ch.kind === "base64");
}
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;
}
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;
}
};
ZodString.create = (params) => {
var _a;
return new ZodString({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodString,
coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,
...processCreateParams(params)
});
};
__name(floatSafeRemainder, "floatSafeRemainder");
ZodNumber = class _ZodNumber extends ZodType {
static {
__name(this, "ZodNumber");
}
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
this.step = this.multipleOf;
}
_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 {
util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
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)
}
]
});
}
_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)
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: 0,
inclusive: true,
message: errorUtil.toString(message)
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value,
message: errorUtil.toString(message)
});
}
finite(message) {
return this._addCheck({
kind: "finite",
message: errorUtil.toString(message)
});
}
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)
});
}
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;
}
get isInt() {
return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value));
}
get isFinite() {
let max = null, 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;
}
}
return Number.isFinite(min) && Number.isFinite(max);
}
};
ZodNumber.create = (params) => {
return new ZodNumber({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodNumber,
coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
...processCreateParams(params)
});
};
ZodBigInt = class _ZodBigInt extends ZodType {
static {
__name(this, "ZodBigInt");
}
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
}
_parse(input) {
if (this._def.coerce) {
input.data = BigInt(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== ZodParsedType.bigint) {
const ctx2 = this._getOrReturnCtx(input);
addIssueToContext(ctx2, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.bigint,
received: ctx2.parsedType
});
return INVALID;
}
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 };
}
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 _ZodBigInt({
...this._def,
checks: [
...this._def.checks,
{
kind,
value,
inclusive,
message: errorUtil.toString(message)
}
]
});
}
_addCheck(check) {
return new _ZodBigInt({
...this._def,
checks: [...this._def.checks, check]
});
}
positive(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: false,
message: errorUtil.toString(message)
});
}
negative(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: false,
message: errorUtil.toString(message)
});
}
nonpositive(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: true,
message: errorUtil.toString(message)
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: true,
message: errorUtil.toString(message)
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value,
message: errorUtil.toString(message)
});
}
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) => {
var _a;
return new ZodBigInt({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodBigInt,
coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,
...processCreateParams(params)
});
};
ZodBoolean = class extends ZodType {
static {
__name(this, "ZodBoolean");
}
_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);
}
};
ZodBoolean.create = (params) => {
return new ZodBoolean({
typeName: ZodFirstPartyTypeKind.ZodBoolean,
coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
...processCreateParams(params)
});
};
ZodDate = class _ZodDate extends ZodType {
static {
__name(this, "ZodDate");
}
_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 (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())
};
}
_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)
});
}
max(maxDate, message) {
return this._addCheck({
kind: "max",
value: maxDate.getTime(),
message: errorUtil.toString(message)
});
}
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 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;
}
};
ZodDate.create = (params) => {
return new ZodDate({
checks: [],
coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
typeName: ZodFirstPartyTypeKind.ZodDate,
...processCreateParams(params)
});
};
ZodSymbol = class extends ZodType {
static {
__name(this, "ZodSymbol");
}
_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);
}
};
ZodSymbol.create = (params) => {
return new ZodSymbol({
typeName: ZodFirstPartyTypeKind.ZodSymbol,
...processCreateParams(params)
});
};
ZodUndefined = class extends ZodType {
static {
__name(this, "ZodUndefined");
}
_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)
});
};
ZodNull = class extends ZodType {
static {
__name(this, "ZodNull");
}
_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);
}
};
ZodNull.create = (params) => {
return new ZodNull({
typeName: ZodFirstPartyTypeKind.ZodNull,
...processCreateParams(params)
});
};
ZodAny = class extends ZodType {
static {
__name(this, "ZodAny");
}
constructor() {
super(...arguments);
this._any = true;
}
_parse(input) {
return OK(input.data);
}
};
ZodAny.create = (params) => {
return new ZodAny({
typeName: ZodFirstPartyTypeKind.ZodAny,
...processCreateParams(params)
});
};
ZodUnknown = class extends ZodType {
static {
__name(this, "ZodUnknown");
}
constructor() {
super(...arguments);
this._unknown = true;
}
_parse(input) {
return OK(input.data);
}
};
ZodUnknown.create = (params) => {
return new ZodUnknown({
typeName: ZodFirstPartyTypeKind.ZodUnknown,
...processCreateParams(params)
});
};
ZodNever = class extends ZodType {
static {
__name(this, "ZodNever");
}
_parse(input) {
const ctx = this._getOrReturnCtx(input);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_type,
expected: ZodParsedType.never,
received: ctx.parsedType
});
return INVALID;
}
};
ZodNever.create = (params) => {
return new ZodNever({
typeName: ZodFirstPartyTypeKind.ZodNever,
...processCreateParams(params)
});
};
ZodVoid = class extends ZodType {
static {
__name(this, "ZodVoid");
}
_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);
}
};
ZodVoid.create = (params) => {
return new ZodVoid({
typeName: ZodFirstPartyTypeKind.ZodVoid,
...processCreateParams(params)
});
};
ZodArray = class _ZodArray extends ZodType {
static {
__name(this, "ZodArray");
}
_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) }
});
}
length(len, message) {
return new _ZodArray({
...this._def,
exactLength: { value: len, message: errorUtil.toString(message) }
});
}
nonempty(message) {
return this.min(1, message);
}
};
ZodArray.create = (schema, params) => {
return new ZodArray({
type: schema,
minLength: null,
maxLength: null,
exactLength: null,
typeName: ZodFirstPartyTypeKind.ZodArray,
...processCreateParams(params)
});
};
__name(deepPartialify, "deepPartialify");
ZodObject = class _ZodObject extends ZodType {
static {
__name(this, "ZodObject");
}
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);
return this._cached = { shape, keys };
}
_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);
}
}
}
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
});
}
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] }
});
}
} 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
});
}
}
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);
});
} else {
return ParseStatus.mergeObjectSync(status, pairs);
}
}
get shape() {
return this._def.shape();
}
strict(message) {
errorUtil.errToObj;
return new _ZodObject({
...this._def,
unknownKeys: "strict",
...message !== void 0 ? {
errorMap: /* @__PURE__ */ __name((issue, ctx) => {
var _a, _b, _c, _d;
const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;
if (issue.code === "unrecognized_keys")
return {
message: (_d = errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError
};
return {
message: defaultError
};
}, "errorMap")
} : {}
});
}
strip() {
return new _ZodObject({
...this._def,
unknownKeys: "strip"
});
}
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: /* @__PURE__ */ __name(() => ({
...this._def.shape(),
...augmentation
}), "shape")
});
}
/**
* 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: /* @__PURE__ */ __name(() => ({
...this._def.shape(),
...merging._def.shape()
}), "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 = {};
util.objectKeys(mask).forEach((key) => {
if (mask[key] && this.shape[key]) {
shape[key] = this.shape[key];
}
});
return new _ZodObject({
...this._def,
shape: /* @__PURE__ */ __name(() => shape, "shape")
});
}
omit(mask) {
const shape = {};
util.objectKeys(this.shape).forEach((key) => {
if (!mask[key]) {
shape[key] = this.shape[key];
}
});
return new _ZodObject({
...this._def,
shape: /* @__PURE__ */ __name(() => shape, "shape")
});
}
/**
* @deprecated
*/
deepPartial() {
return deepPartialify(this);
}
partial(mask) {
const newShape = {};
util.objectKeys(this.shape).forEach((key) => {
const fieldSchema = this.shape[key];
if (mask && !mask[key]) {
newShape[key] = fieldSchema;
} else {
newShape[key] = fieldSchema.optional();
}
});
return new _ZodObject({
...this._def,
shape: /* @__PURE__ */ __name(() => newShape, "shape")
});
}
required(mask) {
const newShape = {};
util.objectKeys(this.shape).forEach((key) => {
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;
}
});
return new _ZodObject({
...this._def,
shape: /* @__PURE__ */ __name(() => newShape, "shape")
});
}
keyof() {
return createZodEnum(util.objectKeys(this.shape));
}
};
ZodObject.create = (shape, params) => {
return new ZodObject({
shape: /* @__PURE__ */ __name(() => shape, "shape"),
unknownKeys: "strip",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params)
});
};
ZodObject.strictCreate = (shape, params) => {
return new ZodObject({
shape: /* @__PURE__ */ __name(() => 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)
});
};
ZodUnion = class extends ZodType {
static {
__name(this, "ZodUnion");
}
_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;
}
__name(handleResults, "handleResults");
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;
}
const unionErrors = issues.map((issues2) => new ZodError(issues2));
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors
});
return INVALID;
}
}
get options() {
return this._def.options;
}
};
ZodUnion.create = (types, params) => {
return new ZodUnion({
options: types,
typeName: ZodFirstPartyTypeKind.ZodUnion,
...processCreateParams(params)
});
};
getDiscriminator = /* @__PURE__ */ __name((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 [];
}
}, "getDiscriminator");
ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType {
static {
__name(this, "ZodDiscriminatedUnion");
}
_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 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
});
}
}
get discriminator() {
return this._def.discriminator;
}
get options() {
return this._def.options;
}
get optionsMap() {
return this._def.optionsMap;
}
/**
* 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)
});
}
};
__name(mergeValues, "mergeValues");
ZodIntersection = class extends ZodType {
static {
__name(this, "ZodIntersection");
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
const handleParsed = /* @__PURE__ */ __name((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 };
}, "handleParsed");
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
}));
}
}
};
ZodIntersection.create = (left, right, params) => {
return new ZodIntersection({
left,
right,
typeName: ZodFirstPartyTypeKind.ZodIntersection,
...processCreateParams(params)
});
};
ZodTuple = class _ZodTuple extends ZodType {
static {
__name(this, "ZodTuple");
}
_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;
}
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;
}
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);
}
}
get items() {
return this._def.items;
}
rest(rest) {
return new _ZodTuple({
...this._def,
rest
});
}
};
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)
});
};
ZodRecord = class _ZodRecord extends ZodType {
static {
__name(this, "ZodRecord");
}
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_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);
} else {
return ParseStatus.mergeObjectSync(status, pairs);
}
}
get element() {
return this._def.valueType;
}
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)
});
}
};
ZodMap = class extends ZodType {
static {
__name(this, "ZodMap");
}
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_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 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;
}
if (key.status === "dirty" || value.status === "dirty") {
status.dirty();
}
finalMap.set(key.value, value.value);
}
return { status: status.value, value: finalMap };
}
}
};
ZodMap.create = (keyType, valueType, params) => {
return new ZodMap({
valueType,
keyType,
typeName: ZodFirstPartyTypeKind.ZodMap,
...processCreateParams(params)
});
};
ZodSet = class _ZodSet extends ZodType {
static {
__name(this, "ZodSet");
}
_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;
}
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();
}
}
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();
}
}
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 };
}
__name(finalizeSet, "finalizeSet");
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) }
});
}
size(size, message) {
return this.min(size, message).max(size, message);
}
nonempty(message) {
return this.min(1, message);
}
};
ZodSet.create = (valueType, params) => {
return new ZodSet({
valueType,
minSize: null,
maxSize: null,
typeName: ZodFirstPartyTypeKind.ZodSet,
...processCreateParams(params)
});
};
ZodFunction = class _ZodFunction extends ZodType {
static {
__name(this, "ZodFunction");
}
constructor() {
super(...arguments);
this.validate = this.implement;
}
_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, error3) {
return makeIssue({
data: args,
path: ctx.path,
errorMaps: [
ctx.common.contextualErrorMap,
ctx.schemaErrorMap,
getErrorMap(),
errorMap
].filter((x) => !!x),
issueData: {
code: ZodIssueCode.invalid_arguments,
argumentsError: error3
}
});
}
__name(makeArgsIssue, "makeArgsIssue");
function makeReturnsIssue(returns, error3) {
return makeIssue({
data: returns,
path: ctx.path,
errorMaps: [
ctx.common.contextualErrorMap,
ctx.schemaErrorMap,
getErrorMap(),
errorMap
].filter((x) => !!x),
issueData: {
code: ZodIssueCode.invalid_return_type,
returnTypeError: error3
}
});
}
__name(makeReturnsIssue, "makeReturnsIssue");
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 error3 = new ZodError([]);
const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
error3.addIssue(makeArgsIssue(args, e));
throw error3;
});
const result = await Reflect.apply(fn, this, parsedArgs);
const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
error3.addIssue(makeReturnsIssue(result, e));
throw error3;
});
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;
});
}
}
parameters() {
return this._def.args;
}
returnType() {
return this._def.returns;
}
args(...items) {
return new _ZodFunction({
...this._def,
args: ZodTuple.create(items).rest(ZodUnknown.create())
});
}
returns(returnType) {
return new _ZodFunction({
...this._def,
returns: returnType
});
}
implement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
strictImplement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
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)
});
}
};
ZodLazy = class extends ZodType {
static {
__name(this, "ZodLazy");
}
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)
});
};
ZodLiteral = class extends ZodType {
static {
__name(this, "ZodLiteral");
}
_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 };
}
get value() {
return this._def.value;
}
};
ZodLiteral.create = (value, params) => {
return new ZodLiteral({
value,
typeName: ZodFirstPartyTypeKind.ZodLiteral,
...processCreateParams(params)
});
};
__name(createZodEnum, "createZodEnum");
ZodEnum = class _ZodEnum extends ZodType {
static {
__name(this, "ZodEnum");
}
constructor() {
super(...arguments);
_ZodEnum_cache.set(this, void 0);
}
_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 (!__classPrivateFieldGet(this, _ZodEnum_cache, "f")) {
__classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), "f");
}
if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f").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);
}
get options() {
return this._def.values;
}
get enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Values() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
extract(values, newDef = this._def) {
return _ZodEnum.create(values, {
...this._def,
...newDef
});
}
exclude(values, newDef = this._def) {
return _ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
...this._def,
...newDef
});
}
};
_ZodEnum_cache = /* @__PURE__ */ new WeakMap();
ZodEnum.create = createZodEnum;
ZodNativeEnum = class extends ZodType {
static {
__name(this, "ZodNativeEnum");
}
constructor() {
super(...arguments);
_ZodNativeEnum_cache.set(this, void 0);
}
_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 (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f")) {
__classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util.getValidEnumValues(this._def.values)), "f");
}
if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f").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);
}
get enum() {
return this._def.values;
}
};
_ZodNativeEnum_cache = /* @__PURE__ */ new WeakMap();
ZodNativeEnum.create = (values, params) => {
return new ZodNativeEnum({
values,
typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
...processCreateParams(params)
});
};
ZodPromise = class extends ZodType {
static {
__name(this, "ZodPromise");
}
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;
}
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
});
}));
}
};
ZodPromise.create = (schema, params) => {
return new ZodPromise({
type: schema,
typeName: ZodFirstPartyTypeKind.ZodPromise,
...processCreateParams(params)
});
};
ZodEffects = class extends ZodType {
static {
__name(this, "ZodEffects");
}
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: /* @__PURE__ */ __name((arg) => {
addIssueToContext(ctx, arg);
if (arg.fatal) {
status.abort();
} else {
status.dirty();
}
}, "addIssue"),
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 (effect.type === "refinement") {
const executeRefinement = /* @__PURE__ */ __name((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;
}, "executeRefinement");
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 };
});
});
}
}
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 base;
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 base;
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)
});
};
ZodOptional = class extends ZodType {
static {
__name(this, "ZodOptional");
}
_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)
});
};
ZodNullable = class extends ZodType {
static {
__name(this, "ZodNullable");
}
_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)
});
};
ZodDefault = class extends ZodType {
static {
__name(this, "ZodDefault");
}
_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)
});
};
ZodCatch = class extends ZodType {
static {
__name(this, "ZodCatch");
}
_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)
});
};
ZodNaN = class extends ZodType {
static {
__name(this, "ZodNaN");
}
_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)
});
};
BRAND = Symbol("zod_brand");
ZodBranded = class extends ZodType {
static {
__name(this, "ZodBranded");
}
_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;
}
};
ZodPipeline = class _ZodPipeline extends ZodType {
static {
__name(this, "ZodPipeline");
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.common.async) {
const handleAsync = /* @__PURE__ */ __name(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
});
}
}, "handleAsync");
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
});
}
};
ZodReadonly = class extends ZodType {
static {
__name(this, "ZodReadonly");
}
_parse(input) {
const result = this._def.innerType._parse(input);
const freeze = /* @__PURE__ */ __name((data) => {
if (isValid(data)) {
data.value = Object.freeze(data.value);
}
return data;
}, "freeze");
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)
});
};
__name(custom, "custom");
late = {
object: ZodObject.lazycreate
};
(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 = {}));
instanceOfType = /* @__PURE__ */ __name((cls, params = {
message: `Input not instance of ${cls.name}`
}) => custom((data) => data instanceof cls, params), "instanceOfType");
stringType = ZodString.create;
numberType = ZodNumber.create;
nanType = ZodNaN.create;
bigIntType = ZodBigInt.create;
booleanType = ZodBoolean.create;
dateType = ZodDate.create;
symbolType = ZodSymbol.create;
undefinedType = ZodUndefined.create;
nullType = ZodNull.create;
anyType = ZodAny.create;
unknownType = ZodUnknown.create;
neverType = ZodNever.create;
voidType = ZodVoid.create;
arrayType = ZodArray.create;
objectType = ZodObject.create;
strictObjectType = ZodObject.strictCreate;
unionType = ZodUnion.create;
discriminatedUnionType = ZodDiscriminatedUnion.create;
intersectionType = ZodIntersection.create;
tupleType = ZodTuple.create;
recordType = ZodRecord.create;
mapType = ZodMap.create;
setType = ZodSet.create;
functionType = ZodFunction.create;
lazyType = ZodLazy.create;
literalType = ZodLiteral.create;
enumType = ZodEnum.create;
nativeEnumType = ZodNativeEnum.create;
promiseType = ZodPromise.create;
effectsType = ZodEffects.create;
optionalType = ZodOptional.create;
nullableType = ZodNullable.create;
preprocessType = ZodEffects.createWithPreprocess;
pipelineType = ZodPipeline.create;
ostring = /* @__PURE__ */ __name(() => stringType().optional(), "ostring");
onumber = /* @__PURE__ */ __name(() => numberType().optional(), "onumber");
oboolean = /* @__PURE__ */ __name(() => booleanType().optional(), "oboolean");
coerce = {
string: /* @__PURE__ */ __name((arg) => ZodString.create({ ...arg, coerce: true }), "string"),
number: /* @__PURE__ */ __name((arg) => ZodNumber.create({ ...arg, coerce: true }), "number"),
boolean: /* @__PURE__ */ __name((arg) => ZodBoolean.create({
...arg,
coerce: true
}), "boolean"),
bigint: /* @__PURE__ */ __name((arg) => ZodBigInt.create({ ...arg, coerce: true }), "bigint"),
date: /* @__PURE__ */ __name((arg) => ZodDate.create({ ...arg, coerce: true }), "date")
};
NEVER = INVALID;
z = /* @__PURE__ */ Object.freeze({
__proto__: null,
defaultErrorMap: errorMap,
setErrorMap,
getErrorMap,
makeIssue,
EMPTY_PATH,
addIssueToContext,
ParseStatus,
INVALID,
DIRTY,
OK,
isAborted,
isDirty,
isValid,
isAsync,
get util() {
return util;
},
get objectUtil() {
return objectUtil;
},
ZodParsedType,
getParsedType,
ZodType,
datetimeRegex,
ZodString,
ZodNumber,
ZodBigInt,
ZodBoolean,
ZodDate,
ZodSymbol,
ZodUndefined,
ZodNull,
ZodAny,
ZodUnknown,
ZodNever,
ZodVoid,
ZodArray,
ZodObject,
ZodUnion,
ZodDiscriminatedUnion,
ZodIntersection,
ZodTuple,
ZodRecord,
ZodMap,
ZodSet,
ZodFunction,
ZodLazy,
ZodLiteral,
ZodEnum,
ZodNativeEnum,
ZodPromise,
ZodEffects,
ZodTransformer: ZodEffects,
ZodOptional,
ZodNullable,
ZodDefault,
ZodCatch,
ZodNaN,
BRAND,
ZodBranded,
ZodPipeline,
ZodReadonly,
custom,
Schema: ZodType,
ZodSchema: ZodType,
late,
get ZodFirstPartyTypeKind() {
return ZodFirstPartyTypeKind;
},
coerce,
any: anyType,
array: arrayType,
bigint: bigIntType,
boolean: booleanType,
date: dateType,
discriminatedUnion: discriminatedUnionType,
effect: effectsType,
"enum": enumType,
"function": functionType,
"instanceof": instanceOfType,
intersection: intersectionType,
lazy: lazyType,
literal: literalType,
map: mapType,
nan: nanType,
nativeEnum: nativeEnumType,
never: neverType,
"null": nullType,
nullable: nullableType,
number: numberType,
object: objectType,
oboolean,
onumber,
optional: optionalType,
ostring,
pipeline: pipelineType,
preprocess: preprocessType,
promise: promiseType,
record: recordType,
set: setType,
strictObject: strictObjectType,
string: stringType,
symbol: symbolType,
transformer: effectsType,
tuple: tupleType,
"undefined": undefinedType,
union: unionType,
unknown: unknownType,
"void": voidType,
NEVER,
ZodIssueCode,
quotelessJson,
ZodError
});
}
});
// src/lib/prompt-recipe-schema.ts
var TransformSchema, KBDBBlockFragmentSchema, KVFragmentSchema, FragmentSchema, InputSchema, PromptAssemblySchema, OutputSpecSchema, PromptRecipeSchema;
var init_prompt_recipe_schema = __esm({
"src/lib/prompt-recipe-schema.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_lib();
TransformSchema = z.string().regex(/^[a-z_]+(:.+)?$/, "transform \u5FC5\u9808\u70BA name \u6216 name:arg \u683C\u5F0F");
KBDBBlockFragmentSchema = z.object({
var: z.string().min(1),
// prompt template 內的變數名
source: z.literal("kbdb_block"),
block_id: z.string().optional(),
// 二擇一
block_page_name: z.string().optional(),
// 比 block_id 穩定
field: z.string().default("content")
// 抓 block 的哪個欄位
});
KVFragmentSchema = z.object({
var: z.string().min(1),
source: z.literal("kv"),
key: z.string().min(1)
});
FragmentSchema = z.discriminatedUnion("source", [
KBDBBlockFragmentSchema,
KVFragmentSchema
]).superRefine((d, ctx) => {
if (d.source === "kbdb_block" && !d.block_id && !d.block_page_name) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "block_id \u6216 block_page_name \u5FC5\u586B\u5176\u4E00"
});
}
});
InputSchema = z.object({
var: z.string().min(1),
from: z.string().min(1),
// JSONPath-lite,如 "ctx.read_drafts.blocks"
transform: TransformSchema.optional(),
default: z.unknown().optional()
// from 取不到時的預設值(避免炸 prompt)
});
PromptAssemblySchema = z.object({
system: z.string().min(1),
// 模板,可含 {{var}}
user: z.string().min(1)
});
OutputSpecSchema = z.object({
format: z.enum(["text", "json"]).default("text"),
// 若 format=json,可選 schema 做 parse 後驗證(簡化版,列必填欄位即可)
required_fields: z.array(z.string()).optional()
});
PromptRecipeSchema = z.object({
kind: z.literal("prompt_recipe"),
name: z.string().min(1).regex(/^[a-z][a-z0-9_]*$/, "name \u70BA lowercase + underscore"),
version: z.number().int().positive().default(1),
description: z.string().optional(),
model: z.enum(["haiku", "sonnet", "opus"]).default("sonnet"),
fragments: z.array(FragmentSchema).default([]),
inputs: z.array(InputSchema).default([]),
prompt_assembly: PromptAssemblySchema,
output: OutputSpecSchema.default({ format: "text" })
});
}
});
// src/lib/recipe-loader.ts
async function loadPromptRecipe(recipeRef, recipesKv) {
const key = recipeRef.startsWith("prompt_recipe:") ? recipeRef : `prompt_recipe:${recipeRef}`;
const raw2 = await recipesKv.get(key);
if (!raw2) {
throw new RecipeLoadError(`\u627E\u4E0D\u5230 recipe: ${key}`, key);
}
let parsed;
try {
parsed = JSON.parse(raw2);
} catch (e) {
throw new RecipeLoadError(
`recipe ${key} \u4E0D\u662F\u5408\u6CD5 JSON: ${e instanceof Error ? e.message : String(e)}`,
key
);
}
const result = PromptRecipeSchema.safeParse(parsed);
if (!result.success) {
const issues = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
throw new RecipeLoadError(`recipe ${key} schema \u9A57\u8B49\u5931\u6557: ${issues}`, key);
}
return result.data;
}
var RecipeLoadError;
var init_recipe_loader = __esm({
"src/lib/recipe-loader.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_prompt_recipe_schema();
RecipeLoadError = class extends Error {
constructor(message, recipe) {
super(message);
this.recipe = recipe;
}
static {
__name(this, "RecipeLoadError");
}
};
__name(loadPromptRecipe, "loadPromptRecipe");
}
});
// src/lib/recipe-transforms.ts
function applyTransform(value, spec) {
const colonIdx = spec.indexOf(":");
const name = colonIdx === -1 ? spec : spec.slice(0, colonIdx);
const arg = colonIdx === -1 ? void 0 : spec.slice(colonIdx + 1);
const fn = transforms[name];
if (!fn) throw new Error(`\u672A\u77E5 transform: ${name}`);
return fn(value, arg);
}
var transforms;
var init_recipe_transforms = __esm({
"src/lib/recipe-transforms.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
transforms = {
json_array: /* @__PURE__ */ __name((v) => JSON.stringify(v ?? []), "json_array"),
to_string: /* @__PURE__ */ __name((v) => {
if (v === null || v === void 0) return "";
if (typeof v === "object") return JSON.stringify(v);
return String(v);
}, "to_string"),
join: /* @__PURE__ */ __name((v, sep) => {
if (!Array.isArray(v)) throw new Error("join: input \u4E0D\u662F array");
return v.map((x) => typeof x === "string" ? x : JSON.stringify(x)).join(sep ?? "\n");
}, "join"),
markdown_list: /* @__PURE__ */ __name((v) => {
if (!Array.isArray(v)) throw new Error("markdown_list: input \u4E0D\u662F array");
return v.map((x) => `- ${typeof x === "string" ? x : JSON.stringify(x)}`).join("\n");
}, "markdown_list"),
extract_field: /* @__PURE__ */ __name((v, field) => {
if (!field) throw new Error("extract_field: \u9700\u8981 field \u53C3\u6578\uFF0C\u4F8B\u5982 extract_field:page_name");
if (!Array.isArray(v)) throw new Error("extract_field: input \u4E0D\u662F array");
return v.map((x) => x && typeof x === "object" ? x[field] : void 0);
}, "extract_field"),
first: /* @__PURE__ */ __name((v) => {
if (!Array.isArray(v)) return v;
return v[0];
}, "first"),
pluck_content: /* @__PURE__ */ __name((v) => {
if (!Array.isArray(v)) throw new Error("pluck_content: input \u4E0D\u662F array");
return v.map((b) => b && typeof b === "object" ? String(b.content ?? "") : "").filter((s) => s.length > 0).join("\n\n---\n\n");
}, "pluck_content")
};
__name(applyTransform, "applyTransform");
}
});
// src/lib/recipe-expander.ts
function getByPath(ctx, path) {
const parts = path.split(".");
let cur = ctx;
for (const p of parts) {
if (cur === null || cur === void 0) return void 0;
if (typeof cur !== "object") return void 0;
cur = cur[p];
}
return cur;
}
function interpolate(template, vars) {
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => vars[key] !== void 0 ? vars[key] : `{{${key}}}`);
}
async function fetchKbdbBlock(env2, apiKey, fragment) {
const base = (env2.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, "");
let url;
if (fragment.block_id) {
url = `${base}/blocks/${encodeURIComponent(fragment.block_id)}`;
} else {
url = `${base}/blocks?page_name=${encodeURIComponent(fragment.block_page_name)}&limit=1`;
}
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
if (!res.ok) throw new Error(`KBDB fragment \u6293\u53D6\u5931\u6557 (${res.status}): ${url}`);
const data = await res.json();
const block = fragment.block_id ? data : data.blocks?.[0] ?? {};
if (!block) throw new Error(`KBDB block \u4E0D\u5B58\u5728: ${fragment.block_id ?? fragment.block_page_name}`);
const fieldVal = block[fragment.field];
if (fieldVal === void 0) throw new Error(`block \u7F3A\u6B04\u4F4D "${fragment.field}"`);
return fieldVal;
}
async function resolveFragment(env2, apiKey, frag) {
if (frag.source === "kv") {
const val = await env2.RECIPES.get(frag.key);
if (val === null) throw new Error(`KV \u627E\u4E0D\u5230 key: ${frag.key}`);
return { var: frag.var, value: val };
}
return { var: frag.var, value: await fetchKbdbBlock(env2, apiKey, frag) };
}
function resolveInput(input, ctx) {
let val = getByPath(ctx, input.from);
const beforeDefault = val;
if (val === void 0) val = input.default;
try {
if (input.transform) val = applyTransform(val, input.transform);
return { var: input.var, value: val };
} catch (e) {
const valType = Array.isArray(beforeDefault) ? `array(${beforeDefault.length})` : beforeDefault === void 0 ? "undefined(default applied)" : typeof beforeDefault;
throw new Error(`${e instanceof Error ? e.message : String(e)} [path=${input.from}, type=${valType}]`);
}
}
async function expandPromptRecipe(recipeRef, ctx, env2, apiKey) {
const recipe = await loadPromptRecipe(recipeRef, env2.RECIPES);
const vars = {};
for (const frag of recipe.fragments) {
const { var: name, value } = await resolveFragment(env2, apiKey, frag);
vars[name] = typeof value === "string" ? value : JSON.stringify(value);
}
for (const inp of recipe.inputs) {
const { var: name, value } = resolveInput(inp, ctx);
vars[name] = typeof value === "string" ? value : JSON.stringify(value);
}
const system = interpolate(recipe.prompt_assembly.system, vars);
const user = interpolate(recipe.prompt_assembly.user, vars);
const prompt = `${system}
--- USER ---
${user}`;
return {
prompt,
model: recipe.model,
output_format: recipe.output.format,
output_required_fields: recipe.output.required_fields
};
}
var init_recipe_expander = __esm({
"src/lib/recipe-expander.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_recipe_loader();
init_recipe_transforms();
__name(getByPath, "getByPath");
__name(interpolate, "interpolate");
__name(fetchKbdbBlock, "fetchKbdbBlock");
__name(resolveFragment, "resolveFragment");
__name(resolveInput, "resolveInput");
__name(expandPromptRecipe, "expandPromptRecipe");
}
});
// src/lib/paused-runs.ts
async function readIndex(kv, apiKey) {
const raw2 = await kv.get(`${IDX_PREFIX}${apiKey}`);
if (!raw2) return [];
try {
const arr = JSON.parse(raw2);
return Array.isArray(arr) ? arr : [];
} catch {
return [];
}
}
async function writeIndex(kv, apiKey, entries) {
const now2 = Date.now();
const fresh = entries.filter((e) => e.expires_at > now2);
await kv.put(`${IDX_PREFIX}${apiKey}`, JSON.stringify(fresh), { expirationTtl: TTL_SECONDS });
}
async function persistPausedRun(kv, taskId, state) {
await kv.put(`${KEY_PREFIX}${taskId}`, JSON.stringify(state), { expirationTtl: TTL_SECONDS });
if (state.api_key) {
const idx = await readIndex(kv, state.api_key);
const filtered = idx.filter((e) => e.task_id !== taskId);
filtered.unshift({
task_id: taskId,
run_id: state.run_id,
paused_node_id: state.paused_node_id,
workflow_name: state.graph.name,
expires_at: state.expires_at,
persisted_at: Date.now()
});
await writeIndex(kv, state.api_key, filtered.slice(0, 100));
}
}
async function loadPausedRun(kv, taskId) {
const raw2 = await kv.get(`${KEY_PREFIX}${taskId}`);
if (!raw2) return null;
try {
return JSON.parse(raw2);
} catch {
return null;
}
}
async function listPausedRunsByApiKey(kv, apiKey, limit = 20) {
const idx = await readIndex(kv, apiKey);
const now2 = Date.now();
return idx.filter((e) => e.expires_at > now2).slice(0, limit);
}
async function consumePausedRun(kv, taskId) {
const state = await loadPausedRun(kv, taskId);
if (!state) return null;
await kv.delete(`${KEY_PREFIX}${taskId}`).catch(() => {
});
if (state.api_key) {
const idx = await readIndex(kv, state.api_key);
const filtered = idx.filter((e) => e.task_id !== taskId);
await writeIndex(kv, state.api_key, filtered).catch(() => {
});
}
return state;
}
function isResumablePending(result) {
if (!result || typeof result !== "object") return null;
const r = result;
if (r.pending !== true) return null;
if (typeof r.task_id !== "string" || !r.task_id) return null;
return { task_id: r.task_id };
}
function parseRecipeOutput(result, format, requiredFields) {
if (format !== "json" || !result || typeof result !== "object") return result;
const r = result;
const text = r.data?.text ?? r.text;
if (typeof text !== "string") return result;
let jsonText = String(text).trim();
const fenceMatch = jsonText.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/);
if (fenceMatch) jsonText = fenceMatch[1].trim();
try {
const parsed = JSON.parse(jsonText);
if (requiredFields && parsed && typeof parsed === "object") {
const missing = requiredFields.filter((f) => !(f in parsed));
if (missing.length > 0) {
return { success: false, error: `recipe output \u7F3A\u6B04\u4F4D: ${missing.join(", ")}`, raw: parsed };
}
}
return { success: true, data: parsed, ...parsed && typeof parsed === "object" ? parsed : {} };
} catch (e) {
return { success: false, error: `recipe output JSON parse \u5931\u6557: ${e instanceof Error ? e.message : String(e)}`, raw_text: text };
}
}
var KEY_PREFIX, IDX_PREFIX, TTL_SECONDS;
var init_paused_runs = __esm({
"src/lib/paused-runs.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
KEY_PREFIX = "paused_run:";
IDX_PREFIX = "paused_idx:";
TTL_SECONDS = 24 * 60 * 60;
__name(readIndex, "readIndex");
__name(writeIndex, "writeIndex");
__name(persistPausedRun, "persistPausedRun");
__name(loadPausedRun, "loadPausedRun");
__name(listPausedRunsByApiKey, "listPausedRunsByApiKey");
__name(consumePausedRun, "consumePausedRun");
__name(isResumablePending, "isResumablePending");
__name(parseRecipeOutput, "parseRecipeOutput");
}
});
// src/lib/magic-vars.ts
function isoWeekNumber(d) {
const target = new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
const dayNum = (target.getUTCDay() + 6) % 7;
target.setUTCDate(target.getUTCDate() - dayNum + 3);
const firstThursday = new Date(Date.UTC(target.getUTCFullYear(), 0, 4));
const weekNum = 1 + Math.round(
((target.getTime() - firstThursday.getTime()) / 864e5 - 3 + (firstThursday.getUTCDay() + 6) % 7) / 7
);
return { year: target.getUTCFullYear(), week: weekNum };
}
function pad2(n) {
return n.toString().padStart(2, "0");
}
function buildMagicVars(now2 = /* @__PURE__ */ new Date()) {
const iso = now2.toISOString();
const yyyy = now2.getUTCFullYear();
const mm = pad2(now2.getUTCMonth() + 1);
const dd = pad2(now2.getUTCDate());
const hh = pad2(now2.getUTCHours());
const mi = pad2(now2.getUTCMinutes());
const ss = pad2(now2.getUTCSeconds());
const yesterday = new Date(now2.getTime() - 864e5);
const yMm = pad2(yesterday.getUTCMonth() + 1);
const yDd = pad2(yesterday.getUTCDate());
const { year: isoYear, week: isoWeek } = isoWeekNumber(now2);
return {
// 日期 / 時間(UTC)
_today: `${yyyy}-${mm}-${dd}`,
// 2026-05-16
_yesterday: `${yesterday.getUTCFullYear()}-${yMm}-${yDd}`,
// 2026-05-15
_now: iso,
// ISO 8601
_now_unix: now2.getTime(),
// unix ms
_now_unix_s: Math.floor(now2.getTime() / 1e3),
// unix sec
// 個別欄位(給 path / page_name 拼)
_year: yyyy,
_month: mm,
_day: dd,
_hour: hh,
_minute: mi,
_second: ss,
// ISO 週(roadmap weekly archive 必備)
_iso_week: `${isoYear}-W${pad2(isoWeek)}`,
// 2026-W20
_iso_week_num: isoWeek,
_iso_year: isoYear,
// 簡單時間 slot(cron-friendly)
_yyyymm: `${yyyy}${mm}`,
// 202605
_yyyymmdd: `${yyyy}${mm}${dd}`,
// 20260516
// 週幾(0=週日,1=週一 ... 6=週六;ISO 風格在 _iso_weekday)
_weekday: now2.getUTCDay(),
_iso_weekday: (now2.getUTCDay() + 6) % 7 + 1
// 1=Mon...7=Sun
};
}
var init_magic_vars = __esm({
"src/lib/magic-vars.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(isoWeekNumber, "isoWeekNumber");
__name(pad2, "pad2");
__name(buildMagicVars, "buildMagicVars");
}
});
// src/lib/telemetry.ts
async function hashApiKey(apiKey) {
if (!apiKey) return "anon";
const encoder = new TextEncoder();
const data = encoder.encode(apiKey);
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.slice(0, 8).map((b) => b.toString(16).padStart(2, "0")).join("");
}
function kbdbCreateBlockUrl(env2) {
const subdomain = env2.WORKER_SUBDOMAIN || "uncle6-me";
return `https://arcrun-kbdb-create-block.${subdomain}.workers.dev`;
}
function recordTelemetry(env2, apiKey, record, ctx) {
const promise = (async () => {
try {
const api_key_hash = await hashApiKey(apiKey ?? "");
const platformKey = env2.PLATFORM_API_KEY || apiKey || "";
if (!platformKey) {
console.warn("[telemetry] no api_key, skipping");
return;
}
const body = {
api_key: platformKey,
type: "agent-telemetry",
source: "cypher-executor",
user_id: "platform_telemetry",
content: JSON.stringify(record),
metadata_json: JSON.stringify({ ...record, api_key_hash }),
tags_json: JSON.stringify([
"agent-telemetry",
`event:${record.event_type}`
])
};
const res = await fetch(kbdbCreateBlockUrl(env2), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
});
if (!res.ok) {
console.warn(
"[telemetry] write failed",
res.status,
await res.text().catch(() => "no body")
);
}
} catch (e) {
console.warn("[telemetry] exception", e);
}
})();
if (ctx?.waitUntil) {
ctx.waitUntil(promise);
}
}
var init_telemetry = __esm({
"src/lib/telemetry.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
__name(hashApiKey, "hashApiKey");
__name(kbdbCreateBlockUrl, "kbdbCreateBlockUrl");
__name(recordTelemetry, "recordTelemetry");
}
});
// src/graph-executor.ts
function propagateCtx(context2, upstreamResult, upstreamNodeId) {
const baseCtx = typeof context2 === "object" && context2 !== null ? context2 : {};
const baseResult = typeof upstreamResult === "object" && upstreamResult !== null ? upstreamResult : {};
return {
...baseCtx,
...baseResult,
[upstreamNodeId]: upstreamResult
};
}
function interpolateString(s, ctx) {
const single = s.match(/^\s*\{\{([\w.]+)\}\}\s*$/);
if (single) {
const val = getNestedValue(ctx, single[1]);
return val === void 0 ? s : val;
}
return s.replace(/\{\{([\w.]+)\}\}/g, (_, key) => {
const val = getNestedValue(ctx, key);
if (val === void 0) return `{{${key}}}`;
if (typeof val === "string") return val;
return JSON.stringify(val);
});
}
function interpolateValue(v, ctx) {
if (typeof v === "string") return interpolateString(v, ctx);
if (Array.isArray(v)) return v.map((item) => interpolateValue(item, ctx));
if (v !== null && typeof v === "object") {
const result = {};
for (const [k, val] of Object.entries(v)) {
result[k] = interpolateValue(val, ctx);
}
return result;
}
return v;
}
function interpolateData(data, ctx) {
if (!data) return {};
return interpolateValue(data, ctx);
}
function getNestedValue(ctx, path) {
const parts = path.split(".");
let cur = ctx;
for (const p of parts) {
if (cur === null || cur === void 0) return void 0;
if (typeof cur !== "object") return void 0;
cur = cur[p];
}
return cur;
}
function readBranch(result) {
if (!result || typeof result !== "object") return void 0;
const r = result;
const data = r.data && typeof r.data === "object" ? r.data : void 0;
const named = data?.branch ?? r.branch;
if (typeof named === "string") return named;
const bool = data?.result ?? r.result;
if (typeof bool === "boolean") return bool ? "true" : "false";
return void 0;
}
function isFailure(result) {
if (!result || typeof result !== "object") return false;
const r = result;
return r["success"] === false || "error" in r;
}
function evaluateCondition(condition, context2) {
if (!context2 || typeof context2 !== "object") return false;
const ctx = context2;
const expr = condition.replace(/result\./g, "").replace(/ctx\./g, "");
const eqMatch = expr.match(/^(\w+)\s*===?\s*(.+)$/);
if (eqMatch) {
const key2 = eqMatch[1];
const rawVal = eqMatch[2].trim();
const expected = rawVal === "true" ? true : rawVal === "false" ? false : rawVal.replace(/['"]/g, "");
return ctx[key2] === expected;
}
const gtMatch = expr.match(/^(\w+)\s*>\s*(\d+)$/);
if (gtMatch) {
return Number(ctx[gtMatch[1]]) > Number(gtMatch[2]);
}
const key = expr.trim();
if (key && key in ctx) return !!ctx[key];
return true;
}
function getIterableFromContext(context2, key) {
if (!context2 || typeof context2 !== "object") return [];
const variants = [
key + "s",
// paragraph → paragraphs
key.replace(/y$/, "ies"),
// entity → entities
key.replace(/(s|x|z|ch|sh)$/, "$1es"),
// box → boxes
key
// singular fallback
];
const obj = context2;
for (const v of variants) {
if (Array.isArray(obj[v])) return obj[v];
}
for (const val of Object.values(obj)) {
if (val !== null && typeof val === "object" && !Array.isArray(val)) {
for (const v of variants) {
const nested = val[v];
if (Array.isArray(nested)) return nested;
}
}
}
return [];
}
var GraphExecutor;
var init_graph_executor = __esm({
"src/graph-executor.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_types();
init_auth_dispatcher();
init_recipe_expander();
init_recipes();
init_paused_runs();
init_magic_vars();
init_telemetry();
GraphExecutor = class _GraphExecutor {
static {
__name(this, "GraphExecutor");
}
loader;
workflowLoader;
env;
apiKey;
recordComponentReference;
// kbdb-base §7.1+§7.5.h:本次執行用到的 recipe **key**(uuid 優先,舊資料 fallback canonical_id)。
// 判定單位是「工作流執行」(n8n execution):執行結束後由 executeWebhookGraph 一次性把這組 key
// 各記成功/失敗到 KBDB 市場星數(per-uuid → 能區分同 canonical 的不同作者版本,§7.5.5)。執行中只收集。
usedRecipeKeys = /* @__PURE__ */ new Set();
// resumable workflow(SDD: resumable-workflow/design.md)
// 暫停時持久化 state 用,需在 execute 進入時設定
currentGraph;
currentRunId;
constructor(loader, workflowLoader, env2, apiKey) {
this.loader = loader;
this.workflowLoader = workflowLoader;
this.env = env2;
this.apiKey = apiKey;
}
async execute(graph, initialContext, kvNamespace) {
const trace3 = [];
const kvStore = kvNamespace ? { runId: `${graph.id}-${Date.now()}`, kv: kvNamespace } : void 0;
this.currentGraph = graph;
this.currentRunId = kvStore?.runId ?? `${graph.id}-${Date.now()}`;
const ctxWithMagic = {
...initialContext,
...buildMagicVars()
};
const hasIncoming = new Set(graph.edges.map((e) => e.to));
const startNodes = graph.nodes.filter((n) => !hasIncoming.has(n.id));
if (startNodes.length === 0) {
return { data: ctxWithMagic, trace: trace3 };
}
const fanIn = /* @__PURE__ */ new Map();
for (const node of graph.nodes) {
const inDeg = graph.edges.filter((e) => e.to === node.id).length;
if (inDeg > 1) {
fanIn.set(node.id, { ctx: { ...ctxWithMagic }, remaining: inDeg });
}
}
const results = await Promise.all(
startNodes.map(
(node) => this.executeNode(node, graph, ctxWithMagic, /* @__PURE__ */ new Set(), trace3, fanIn, kvStore)
)
);
let mergedResult;
if (results.length === 1) {
mergedResult = results[0];
} else {
mergedResult = results.reduce(
(acc, r) => ({
...acc,
...typeof r === "object" && r !== null ? r : {}
}),
{}
);
}
return { data: mergedResult, trace: trace3 };
}
/**
* 從 paused state 繼續執行 workflow
* SDD: resumable-workflow/design.md §3.2
*
* 流程:
* 1. 把 paused_node 當已執行(result = callbackResult,注入進 context)
* 2. 找出 paused_node 的所有下游節點當新起點
* 3. 執行下游節點直到結束(或再次 paused)
*/
async resumeFromPaused(args) {
const { graph, paused_node_id, paused_context, prior_trace, kvNamespace } = args;
let { callback_result } = args;
callback_result = parseRecipeOutput(
callback_result,
args.recipe_output_format,
args.recipe_output_required_fields
);
this.currentGraph = graph;
this.currentRunId = `${graph.id}-resume-${Date.now()}`;
const trace3 = [...prior_trace];
const kvStore = kvNamespace ? { runId: this.currentRunId, kv: kvNamespace } : void 0;
if (kvStore) {
await kvSetNodeOutput(kvStore, paused_node_id, callback_result);
}
const mergedContext = {
...paused_context,
...callback_result && typeof callback_result === "object" ? callback_result : {},
[paused_node_id]: callback_result
};
if (kvStore) {
if (!mergedContext._kv_outputs) mergedContext._kv_outputs = {};
mergedContext._kv_outputs[paused_node_id] = callback_result;
}
const downstreamEdges = graph.edges.filter((e) => e.from === paused_node_id);
if (downstreamEdges.length === 0) {
return { data: callback_result, trace: trace3 };
}
const fanIn = /* @__PURE__ */ new Map();
for (const node of graph.nodes) {
const inDeg = graph.edges.filter((e) => e.to === node.id).length;
if (inDeg > 1) {
fanIn.set(node.id, { ctx: { ...mergedContext }, remaining: inDeg });
}
}
const visited = /* @__PURE__ */ new Set([`${paused_node_id}:${JSON.stringify(paused_context).slice(0, 50)}`]);
const downstreamNodes = downstreamEdges.map((e) => graph.nodes.find((n) => n.id === e.to)).filter((n) => !!n);
const results = await Promise.all(
downstreamNodes.map(
(node) => this.executeNode(node, graph, mergedContext, visited, trace3, fanIn, kvStore)
)
);
let mergedResult;
if (results.length === 1) {
mergedResult = results[0];
} else {
mergedResult = results.reduce(
(acc, r) => ({
...acc,
...typeof r === "object" && r !== null ? r : {}
}),
{}
);
}
return { data: mergedResult, trace: trace3 };
}
async executeNode(node, graph, context2, visited, trace3, fanIn, kvStore) {
const nodeKey = `${node.id}:${JSON.stringify(context2).slice(0, 50)}`;
if (visited.has(nodeKey)) return context2;
visited.add(nodeKey);
const start = Date.now();
let result = context2;
let nodeInput = context2;
try {
switch (node.type) {
case "Input":
result = node.data ?? context2;
nodeInput = result;
break;
case "Component": {
if (!node.componentId) throw new Error(`\u7BC0\u9EDE ${node.id} \u7F3A\u5C11 componentId`);
const runner = await this.loader(node.componentId);
const ctx = context2;
const resolvedData = interpolateData(node.data, ctx);
let mergedContext = {
...ctx,
...resolvedData
};
if (this.env && this.apiKey) {
mergedContext = await resolveCredentialRefs(mergedContext, this.env, this.apiKey);
}
if (node.componentId === "claude_api") {
const baseUrl = this.env?.PUBLIC_BASE_URL ?? "https://cypher.arcrun.dev";
mergedContext.callback_url = `${baseUrl.replace(/\/$/, "")}/workflows/resume`;
}
if (typeof resolvedData.recipe === "string" && this.env?.RECIPES) {
try {
const expanded = await expandPromptRecipe(
resolvedData.recipe,
ctx,
this.env,
this.apiKey ?? ""
);
mergedContext = {
...mergedContext,
prompt: expanded.prompt,
model: expanded.model,
_recipe_output_format: expanded.output_format,
_recipe_output_required_fields: expanded.output_required_fields
};
} catch (e) {
throw new Error(`recipe \u5C55\u958B\u5931\u6557 (${resolvedData.recipe}): ${e instanceof Error ? e.message : String(e)}`);
}
}
if (this.env && this.apiKey) {
const dispatched = await tryAuthDispatch(node.componentId, mergedContext, this.env, this.apiKey);
if (dispatched) {
mergedContext = dispatched;
}
}
if (this.env?.RECIPES) {
try {
const apiRecipe = await resolveRecipe(node.componentId, this.env.RECIPES);
if (apiRecipe) this.usedRecipeKeys.add(apiRecipe.uuid ?? apiRecipe.canonical_id);
} catch {
}
}
nodeInput = mergedContext;
result = await runner(mergedContext);
const pending = isResumablePending(result);
if (pending && this.env?.EXEC_CONTEXT && this.currentGraph && this.currentRunId) {
trace3.push({
nodeId: node.id,
type: node.type,
input: nodeInput,
output: result,
duration_ms: Date.now() - start
});
await persistPausedRun(this.env.EXEC_CONTEXT, pending.task_id, {
run_id: this.currentRunId,
graph: this.currentGraph,
paused_node_id: node.id,
paused_context: context2,
paused_pending_result: result,
trace_so_far: trace3,
api_key: this.apiKey,
expires_at: Date.now() + 24 * 60 * 60 * 1e3,
recipe_output_format: mergedContext._recipe_output_format,
recipe_output_required_fields: mergedContext._recipe_output_required_fields
});
throw new WorkflowPaused(pending.task_id, this.currentRunId, node.id, trace3);
}
result = parseRecipeOutput(
result,
mergedContext._recipe_output_format,
mergedContext._recipe_output_required_fields
);
if (kvStore && result !== null && result !== void 0) {
await kvSetNodeOutput(kvStore, node.id, result);
}
void this.recordComponentReference?.(node.componentId, graph.id).catch(() => {
});
break;
}
case "Output":
result = context2;
break;
}
} catch (e) {
if (e instanceof WorkflowPaused) throw e;
const errMsg = e.message || String(e);
const duration_ms2 = Date.now() - start;
trace3.push({
nodeId: node.id,
type: node.type,
input: nodeInput,
output: null,
error: errMsg,
duration_ms: duration_ms2
});
if (this.env && node.type === "Component") {
recordTelemetry(this.env, this.apiKey, {
event_type: "node_failure",
workflow_name: graph.name,
component_id: node.componentId,
error_code: "node_error",
duration_ms: duration_ms2
});
}
if (e instanceof ExecutionError) throw e;
throw new ExecutionError(
`Node ${node.id} failed: ${errMsg}`,
node.id,
nodeInput,
trace3
);
}
const duration_ms = Date.now() - start;
trace3.push({
nodeId: node.id,
type: node.type,
input: nodeInput,
output: result,
duration_ms
});
if (this.env && node.type === "Component") {
recordTelemetry(this.env, this.apiKey, {
event_type: "node_success",
workflow_name: graph.name,
component_id: node.componentId,
duration_ms
});
}
const outEdges = graph.edges.filter((e) => e.from === node.id);
for (const edge of outEdges) {
const nextNode = graph.nodes.find((n) => n.id === edge.to);
if (!nextNode) continue;
switch (edge.type) {
case "PIPE": {
const pipeContext = propagateCtx(context2, result, node.id);
if (kvStore) {
const kvOutput = await kvGetNodeOutput(kvStore, node.id);
if (kvOutput !== void 0) {
if (!pipeContext._kv_outputs) pipeContext._kv_outputs = {};
pipeContext._kv_outputs[node.id] = kvOutput;
}
}
const fanInState = fanIn.get(nextNode.id);
if (fanInState) {
Object.assign(fanInState.ctx, pipeContext);
fanInState.remaining--;
if (fanInState.remaining === 0) {
result = await this.executeNode(nextNode, graph, fanInState.ctx, visited, trace3, fanIn, kvStore);
}
} else {
result = await this.executeNode(nextNode, graph, pipeContext, visited, trace3, fanIn, kvStore);
}
break;
}
case "ON_SUCCESS": {
if (!isFailure(result)) {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
case "ON_FAIL": {
if (isFailure(result)) {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
case "IF": {
const passes = evaluateCondition(edge.condition ?? "true", result);
if (passes) {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
// ── 條件邊(SDD workflow-discovery 3.11 / CP arcrun-usable 步驟 5 缺口①)──
// 為什麼要有:`if_control` 回 {result, branch} 卻沒有邊讀得懂它,
// AI 照規矩用了零件仍得寫 code 判斷走哪條 ⇒「全變成 code」的根(Arcrun#5)。
// 讀法對齊零件 output_schema:優先 data.branch(if_control/switch 的正式形狀),
// 相容 top-level branch / result 布林。讀不出分支=不走(誠實,不亂挑一條)。
case "ON_TRUE": {
if (readBranch(result) === "true") {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
case "ON_FALSE": {
if (readBranch(result) === "false") {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
case "ON_BRANCH": {
const actual = readBranch(result);
if (edge.branch !== void 0 && actual !== void 0 && actual === edge.branch) {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
}
break;
}
case "FOREACH": {
const iteratorKey = edge.iterator ?? "item";
let items = getIterableFromContext(result, iteratorKey);
if (items.length === 0) {
items = getIterableFromContext(context2, iteratorKey);
}
const iterResults = [];
const baseForeachCtx = propagateCtx(context2, result, node.id);
for (const item of items) {
const itemContext = {
...baseForeachCtx,
[iteratorKey]: item
};
const itemResult = await this.executeNode(nextNode, graph, itemContext, /* @__PURE__ */ new Set(), trace3, fanIn, kvStore);
iterResults.push(itemResult);
}
result = { ...result, results: iterResults };
break;
}
case "CALLS_SUBFLOW": {
const subWorkflowId = nextNode.componentId?.replace("workflow://", "") ?? nextNode.id;
if (this.workflowLoader) {
const subGraph = await this.workflowLoader(subWorkflowId);
const subExecutor = new _GraphExecutor(this.loader, this.workflowLoader);
const subResult = await subExecutor.execute(
subGraph,
result,
kvStore?.kv
);
result = {
...result,
...subResult.data
};
}
break;
}
case "ON_CLICK": {
const mergedCtx = propagateCtx(context2, result, node.id);
result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace3, fanIn, kvStore);
break;
}
case "IS_A": {
break;
}
case "CONTAINS":
case "HAS_STYLE":
case "HAS_BEHAVIOR": {
break;
}
case "CONTINUE":
break;
}
}
return result;
}
};
__name(propagateCtx, "propagateCtx");
__name(interpolateString, "interpolateString");
__name(interpolateValue, "interpolateValue");
__name(interpolateData, "interpolateData");
__name(getNestedValue, "getNestedValue");
__name(readBranch, "readBranch");
__name(isFailure, "isFailure");
__name(evaluateCondition, "evaluateCondition");
__name(getIterableFromContext, "getIterableFromContext");
}
});
// src/lib/schemas.ts
var graphSchema, executeSchema;
var init_schemas = __esm({
"src/lib/schemas.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_lib();
graphSchema = z.object({
id: z.string().min(1),
name: z.string().min(1),
nodes: z.array(z.object({
id: z.string(),
type: z.enum(["Input", "Component", "Output"]),
componentId: z.string().optional(),
label: z.string().optional(),
data: z.record(z.unknown()).optional()
})),
edges: z.array(z.object({
from: z.string(),
to: z.string(),
type: z.enum(["PIPE", "IF", "FOREACH", "CONTINUE", "IS_A", "ON_SUCCESS", "ON_FAIL", "ON_TRUE", "ON_FALSE", "ON_BRANCH", "ON_CLICK", "CALLS_SUBFLOW", "CONTAINS", "HAS_STYLE", "HAS_BEHAVIOR"]),
condition: z.string().optional(),
iterator: z.string().optional(),
branch: z.string().optional()
// ON_BRANCH 的具名分支(SDD workflow-discovery 3.11)
}))
});
executeSchema = z.object({
graph: graphSchema,
context: z.record(z.unknown()).default({})
});
}
});
// src/actions/execution-evaluator.ts
function componentVerdictsFromTrace(nodes, trace3) {
const componentByNodeId = /* @__PURE__ */ new Map();
for (const n of nodes) {
if (n.type === "Component" && n.componentId) componentByNodeId.set(n.id, n.componentId);
}
const verdicts = [];
for (const step of trace3) {
const componentId = componentByNodeId.get(step.nodeId);
if (!componentId) continue;
const out = step.output;
const outputSaysFailed = typeof out === "object" && out !== null && !Array.isArray(out) && out.success === false;
verdicts.push({
component_id: componentId,
success: !step.error && !outputSaysFailed,
duration_ms: Math.max(0, Number(step.duration_ms) || 0)
});
}
return verdicts;
}
async function recordComponentStats(env2, nodes, trace3) {
try {
const base = (env2.REGISTRY_BASE_URL ?? (env2.WORKER_SUBDOMAIN ? wasmWorkerUrl("registry", env2.WORKER_SUBDOMAIN) : void 0))?.replace(/\/$/, "");
if (!base) return;
const verdicts = componentVerdictsFromTrace(nodes, trace3);
if (verdicts.length === 0) return;
await Promise.all(
verdicts.map(
(v) => fetch(`${base}/analytics/record`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
canonical_id: v.component_id,
success: v.success,
duration_ms: v.duration_ms
})
}).catch(() => void 0)
// 統計失敗不影響執行
)
);
} catch {
}
}
var init_execution_evaluator = __esm({
"src/actions/execution-evaluator.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_component_loader();
__name(componentVerdictsFromTrace, "componentVerdictsFromTrace");
__name(recordComponentStats, "recordComponentStats");
}
});
// src/actions/webhook-handlers.ts
var webhook_handlers_exports = {};
__export(webhook_handlers_exports, {
executeWebhookGraph: () => executeWebhookGraph,
generateToken: () => generateToken,
validateAndParseWebhook: () => validateAndParseWebhook
});
function recordRecipeStats(env2, recipeKeys, ok, at, ctx) {
if (recipeKeys.size === 0) return;
const base = (env2.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, "");
const headers = { "Content-Type": "application/json" };
if (env2.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env2.KBDB_INTERNAL_TOKEN}`;
const promise = Promise.all(
[...recipeKeys].map(
(key) => fetch(`${base}/recipe-stats/record`, {
method: "POST",
headers,
body: JSON.stringify({ canonical_id: key, ok, at })
}).catch(() => void 0)
)
).then(() => void 0);
if (ctx?.waitUntil) ctx.waitUntil(promise);
else void promise;
}
function generateToken() {
const tokenBytes = crypto.getRandomValues(new Uint8Array(16));
return Array.from(tokenBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
}
async function validateAndParseWebhook(raw2) {
try {
return JSON.parse(raw2);
} catch {
return null;
}
}
async function executeWebhookGraph(env2, graph, triggerContext, token, apiKey, ctx, userAgent) {
const parsed = graphSchema.safeParse(graph);
if (!parsed.success) {
return { success: false, error: "\u5716\u5B9A\u7FA9\u5DF2\u5931\u6548", duration_ms: 0 };
}
const loader = createComponentLoader(env2);
const executor = new GraphExecutor(loader, void 0, env2, apiKey);
const start = Date.now();
try {
const result = await executor.execute(
parsed.data,
{ ...triggerContext, _webhook_token: token },
env2.EXEC_CONTEXT
);
const duration_ms = Date.now() - start;
recordTelemetry(env2, apiKey, {
event_type: "run_success",
workflow_name: token,
duration_ms,
agent_user_agent: userAgent
}, ctx);
recordRecipeStats(env2, executor.usedRecipeKeys, true, Date.now(), ctx);
{
const statsPromise = recordComponentStats(
env2,
parsed.data.nodes,
result.trace
);
if (ctx?.waitUntil) ctx.waitUntil(statsPromise);
else void statsPromise;
}
return { success: true, data: result.data, duration_ms };
} catch (err) {
const duration_ms = Date.now() - start;
const errMsg = err instanceof Error ? err.message : String(err);
const isPaused = /workflow paused/i.test(errMsg);
recordTelemetry(env2, apiKey, {
event_type: isPaused ? "run_success" : "run_fail",
workflow_name: token,
error_code: isPaused ? "paused_awaiting_resume" : "execution_error",
duration_ms,
agent_user_agent: userAgent
}, ctx);
if (!isPaused) {
recordRecipeStats(env2, executor.usedRecipeKeys, false, Date.now(), ctx);
}
if (!isPaused && err instanceof ExecutionError) {
const statsPromise = recordComponentStats(
env2,
parsed.data.nodes,
err.trace
);
if (ctx?.waitUntil) ctx.waitUntil(statsPromise);
else void statsPromise;
}
if (err instanceof ExecutionError) {
const traceFormatted = err.trace.map((s) => ({
node: s.nodeId,
status: s.error ? "failed" : "success",
...s.error ? { error: s.error } : {}
}));
return {
success: false,
error: errMsg,
trace: traceFormatted,
duration_ms
};
}
return { success: false, error: errMsg, duration_ms };
}
}
var init_webhook_handlers = __esm({
"src/actions/webhook-handlers.ts"() {
"use strict";
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_types();
init_graph_executor();
init_schemas();
init_component_loader();
init_telemetry();
init_execution_evaluator();
__name(recordRecipeStats, "recordRecipeStats");
__name(generateToken, "generateToken");
__name(validateAndParseWebhook, "validateAndParseWebhook");
__name(executeWebhookGraph, "executeWebhookGraph");
}
});
// src/index.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
// node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/middleware/cors/index.js
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
var cors = /* @__PURE__ */ __name((options) => {
const defaults = {
origin: "*",
allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
allowHeaders: [],
exposeHeaders: []
};
const opts = {
...defaults,
...options
};
const findAllowOrigin = ((optsOrigin) => {
if (typeof optsOrigin === "string") {
if (optsOrigin === "*") {
if (opts.credentials) {
return (origin) => origin || null;
}
return () => optsOrigin;
} else {
return (origin) => optsOrigin === origin ? origin : null;
}
} else if (typeof optsOrigin === "function") {
return optsOrigin;
} else {
return (origin) => optsOrigin.includes(origin) ? origin : null;
}
})(opts.origin);
const findAllowMethods = ((optsAllowMethods) => {
if (typeof optsAllowMethods === "function") {
return optsAllowMethods;
} else if (Array.isArray(optsAllowMethods)) {
return () => optsAllowMethods;
} else {
return () => [];
}
})(opts.allowMethods);
return /* @__PURE__ */ __name(async function cors2(c, next) {
function set(key, value) {
c.res.headers.set(key, value);
}
__name(set, "set");
const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
if (allowOrigin) {
set("Access-Control-Allow-Origin", allowOrigin);
}
if (opts.credentials) {
set("Access-Control-Allow-Credentials", "true");
}
if (opts.exposeHeaders?.length) {
set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
}
if (c.req.method === "OPTIONS") {
if (opts.origin !== "*" || opts.credentials) {
set("Vary", "Origin");
}
if (opts.maxAge != null) {
set("Access-Control-Max-Age", opts.maxAge.toString());
}
const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
if (allowMethods.length) {
set("Access-Control-Allow-Methods", allowMethods.join(","));
}
let headers = opts.allowHeaders;
if (!headers?.length) {
const requestHeaders = c.req.header("Access-Control-Request-Headers");
if (requestHeaders) {
headers = requestHeaders.split(/\s*,\s*/);
}
}
if (headers?.length) {
set("Access-Control-Allow-Headers", headers.join(","));
c.res.headers.append("Vary", "Access-Control-Request-Headers");
}
c.res.headers.delete("Content-Length");
c.res.headers.delete("Content-Type");
return new Response(null, {
headers: c.res.headers,
status: 204,
statusText: "No Content"
});
}
await next();
if (opts.origin !== "*" || opts.credentials) {
c.header("Vary", "Origin", { append: true });
}
}, "cors2");
}, "cors");
// src/scheduled.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
// src/lib/cron-match.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
function matchField(expr, value, min, max) {
if (expr === "*") return true;
for (const part of expr.split(",")) {
if (matchPart(part.trim(), value, min, max)) return true;
}
return false;
}
__name(matchField, "matchField");
function matchPart(part, value, min, max) {
if (part.startsWith("*/")) {
const step = parseInt(part.slice(2), 10);
if (!Number.isFinite(step) || step <= 0) return false;
return (value - min) % step === 0;
}
if (part.includes("-")) {
const [rangePart, stepStr] = part.split("/");
const [aStr, bStr] = rangePart.split("-");
const a = parseInt(aStr, 10);
const b = parseInt(bStr, 10);
if (!Number.isFinite(a) || !Number.isFinite(b)) return false;
if (value < a || value > b) return false;
if (stepStr === void 0) return true;
const step = parseInt(stepStr, 10);
if (!Number.isFinite(step) || step <= 0) return false;
return (value - a) % step === 0;
}
const n = parseInt(part, 10);
if (!Number.isFinite(n)) return false;
if (n < min || n > max) return false;
return value === n;
}
__name(matchPart, "matchPart");
function cronMatch(expr, date) {
const fields = expr.trim().split(/\s+/);
if (fields.length !== 5) return false;
const [m, h, dom, mon, dow] = fields;
return matchField(m, date.getUTCMinutes(), 0, 59) && matchField(h, date.getUTCHours(), 0, 23) && matchField(dom, date.getUTCDate(), 1, 31) && matchField(mon, date.getUTCMonth() + 1, 1, 12) && matchField(dow, date.getUTCDay(), 0, 6);
}
__name(cronMatch, "cronMatch");
function extractCronExpr(graph) {
if (!graph || typeof graph !== "object") return null;
const nodes = graph.nodes;
if (!Array.isArray(nodes)) return null;
for (const node of nodes) {
if (node.componentId !== "cron") continue;
const expr = node.data?.cron_expr;
if (typeof expr === "string" && expr.trim()) return expr.trim();
}
return null;
}
__name(extractCronExpr, "extractCronExpr");
// src/lib/cron-index.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
var CRON_INDEX_KEY = "cron-idx:_all";
function cronEntryKey(apiKey, name) {
return `${apiKey}:${name}`;
}
__name(cronEntryKey, "cronEntryKey");
function parseCronEntryKey(entryKey) {
const idx = entryKey.indexOf(":");
if (idx <= 0) return null;
return { apiKey: entryKey.slice(0, idx), name: entryKey.slice(idx + 1) };
}
__name(parseCronEntryKey, "parseCronEntryKey");
async function readCronIndex(kv) {
const raw2 = await kv.get(CRON_INDEX_KEY, "text");
if (!raw2) return {};
try {
const parsed = JSON.parse(raw2);
return parsed && typeof parsed === "object" ? parsed : {};
} catch {
return {};
}
}
__name(readCronIndex, "readCronIndex");
async function updateCronIndexEntry(kv, apiKey, name, cronExpr) {
const index = await readCronIndex(kv);
const entryKey = cronEntryKey(apiKey, name);
if (cronExpr) {
if (index[entryKey] === cronExpr) return;
index[entryKey] = cronExpr;
} else {
if (!(entryKey in index)) return;
delete index[entryKey];
}
await kv.put(CRON_INDEX_KEY, JSON.stringify(index));
}
__name(updateCronIndexEntry, "updateCronIndexEntry");
// src/scheduled.ts
init_webhook_handlers();
async function handleScheduled(controller, env2, ctx) {
const now2 = new Date(controller.scheduledTime);
console.log("[scheduled] tick", now2.toISOString(), "controller.cron=", controller.cron);
const index = await readCronIndex(env2.WEBHOOKS);
const entries = Object.entries(index);
let triggered = 0;
for (const [entryKey, cronExpr] of entries) {
const parsed = parseCronEntryKey(entryKey);
if (!parsed) continue;
const { apiKey, name } = parsed;
if (!cronExpr) continue;
if (!cronMatch(cronExpr, now2)) continue;
const wfKey = `${apiKey}:wf:${name}`;
const wfRaw = await env2.WEBHOOKS.get(wfKey, "text");
if (!wfRaw) {
console.warn("[scheduled] cron-idx \u5C0D\u61C9 workflow \u4E0D\u5B58\u5728", wfKey);
continue;
}
let record;
try {
record = JSON.parse(wfRaw);
} catch {
continue;
}
triggered++;
console.log("[scheduled] trigger", name, "apiKey=", apiKey.slice(0, 12) + "...", "cron=", cronExpr);
const triggerContext = {
api_key: apiKey,
_triggered_by: "cron",
_scheduled_at: now2.toISOString()
};
ctx.waitUntil(
executeWebhookGraph(env2, record.graph, triggerContext, name, apiKey).then(
(r) => console.log("[scheduled] done", name, r.success, r.duration_ms + "ms"),
(e) => console.error("[scheduled] fail", name, e)
)
);
}
console.log(`[scheduled] scanned ${entries.length} cron-idx entries, ${triggered} triggered`);
}
__name(handleScheduled, "handleScheduled");
// src/routes/health.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
var healthRouter = new Hono2();
healthRouter.get("/health", (c) => {
const bundleVersion = c.env.ARCRUN_BUNDLE_VERSION;
return c.json(
bundleVersion ? { ok: true, bundle_version: bundleVersion } : { ok: true }
);
});
healthRouter.get(
"/",
(c) => c.json({
service: "arcrun-cypher-executor",
version: "1.0.0",
status: "ok"
})
);
// src/routes/execute.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
init_types();
init_graph_executor();
init_schemas();
init_component_loader();
// src/actions/execution-logger.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
async function writeExecutionVerdict(env2, workflowId, nodes, verdict, durationMs, message) {
try {
const componentIds = nodes.filter((n) => n.type === "Component" && n.componentId).map((n) => n.componentId);
const record = {
workflow_id: workflowId,
component_ids: componentIds,
verdict,
duration_ms: durationMs,
message,
recorded_at: (/* @__PURE__ */ new Date()).toISOString()
};
const key = `stats:${workflowId}:${Date.now()}`;
await env2.ANALYTICS_KV.put(key, JSON.stringify(record), {
expirationTtl: 60 * 60 * 24 * 90
// 保留 90 天
});
} catch {
}
}
__name(writeExecutionVerdict, "writeExecutionVerdict");
// src/routes/execute.ts
var executeRouter = new Hono2();
executeRouter.post("/execute", async (c) => {
const body = await c.req.json();
const parsed = executeSchema.safeParse(body);
if (!parsed.success) {
return c.json({ error: "\u5716\u5B9A\u7FA9\u9A57\u8B49\u5931\u6557", details: parsed.error.issues }, 400);
}
const { graph, context: context2 } = parsed.data;
const apiKey = c.req.header("x-arcrun-api-key") ?? void 0;
const loader = createComponentLoader(c.env);
const executor = new GraphExecutor(loader, void 0, c.env, apiKey);
const start = Date.now();
try {
const result = await executor.execute(graph, context2, c.env.EXEC_CONTEXT);
const duration_ms = Date.now() - start;
c.executionCtx.waitUntil(
writeExecutionVerdict(c.env, graph.id, graph.nodes, "success", duration_ms, "\u57F7\u884C\u5B8C\u6210")
);
return c.json({ success: true, data: result.data, trace: result.trace, duration_ms });
} catch (err) {
const duration_ms = Date.now() - start;
const errMsg = err instanceof Error ? err.message : String(err);
c.executionCtx.waitUntil(
writeExecutionVerdict(c.env, graph.id, graph.nodes, "failed", duration_ms, errMsg.slice(0, 100))
);
if (err instanceof ExecutionError) {
const traceFormatted = err.trace.map((s) => ({
node: s.nodeId,
status: s.error ? "failed" : "success",
...s.error ? { error: s.error } : {}
}));
return c.json({
success: false,
error: errMsg,
failed_node: err.failed_node,
failed_input: err.failed_input,
trace: traceFormatted,
duration_ms
}, 500);
}
return c.json({ success: false, error: errMsg, failed_node: null, trace: [], duration_ms }, 500);
}
});
// src/routes/cypher.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
// src/actions/cypher-handlers.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_types();
init_graph_executor();
init_schemas();
init_component_loader();
init_execution_evaluator();
// src/actions/triplet-parser.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_constants3();
function parseTriplets(rawTriplets) {
const edges = [];
const nodeNames = /* @__PURE__ */ new Set();
const fromSet = /* @__PURE__ */ new Set();
const toSet = /* @__PURE__ */ new Set();
for (const line of rawTriplets) {
if (typeof line !== "string") continue;
const parts = line.split(">>").map((s) => s.trim());
if (parts.length !== 3) continue;
const [from, action, to] = parts;
edges.push({ from, to, label: action });
nodeNames.add(from);
nodeNames.add(to);
fromSet.add(from);
toSet.add(to);
}
if (nodeNames.size === 0) return null;
const sourceNodes = new Set([...fromSet].filter((n) => !toSet.has(n)));
const sinkNodes = new Set([...toSet].filter((n) => !fromSet.has(n)));
return { edges, nodeNames, sourceNodes, sinkNodes };
}
__name(parseTriplets, "parseTriplets");
var INPUT_NAMES = /* @__PURE__ */ new Set(["input", "trigger", "webhook", "start"]);
var OUTPUT_NAMES = /* @__PURE__ */ new Set(["output", "result", "end", "done"]);
function isVirtualIoName(name) {
const lower = name.toLowerCase();
return INPUT_NAMES.has(lower) || OUTPUT_NAMES.has(lower);
}
__name(isVirtualIoName, "isVirtualIoName");
function resolveNodeRole(name, parsed) {
if (INPUT_NAMES.has(name.toLowerCase())) return "Input";
if (OUTPUT_NAMES.has(name.toLowerCase())) return "Output";
if (parsed.sourceNodes.has(name)) return "Input";
return "Component";
}
__name(resolveNodeRole, "resolveNodeRole");
function toEdgeType(label) {
const upper = label.toUpperCase();
if (VALID_EDGE_TYPES.has(upper)) return upper;
return SEMANTIC_EDGE_MAP[label] ?? SEMANTIC_EDGE_MAP[upper] ?? "PIPE";
}
__name(toEdgeType, "toEdgeType");
// src/actions/search-nodes.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_component_loader();
init_recipes();
// src/lib/branch-hints.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
var BRANCH_HINTS = {
if_control: {
branch_field: "data.branch",
branches: ["true", "false"],
edge_types: ["ON_TRUE", "ON_FALSE"],
usage: '\u9019\u9846\u7B97\u5B8C\u6703\u8F38\u51FA data.branch\uFF08"true"\uFF0F"false"\uFF09\u3002\u4E0B\u6E38\u63A5\u5169\u689D\u908A\uFF1AON_TRUE \u63A5\u689D\u4EF6\u6210\u7ACB\u8981\u505A\u7684\u4E8B\uFF0CON_FALSE \u63A5\u4E0D\u6210\u7ACB\u8981\u505A\u7684\u4E8B\u3002**\u4E0D\u9700\u8981\u81EA\u5DF1\u5BEB code \u5224\u65B7\u8D70\u54EA\u689D**\u2014\u2014\u5F15\u64CE\u4F9D branch \u81EA\u52D5\u9078\u8DEF\u3002',
example: "\u5224\u65B7\u6709\u6C92\u6709\u65B0\u8CC7\u6599 >> ON_TRUE >> \u50B3\u5230 telegram\n\u5224\u65B7\u6709\u6C92\u6709\u65B0\u8CC7\u6599 >> ON_FALSE >> \u7D50\u675F\n\uFF08\u4E2D\u6587\u8A9E\u610F\u8A5E\u4EA6\u53EF\uFF1A\u300C\u6210\u7ACB\u6642\u300D\uFF1DON_TRUE\u3001\u300C\u5426\u5247\u300D\uFF1DON_FALSE\uFF09"
},
switch: {
branch_field: "data.branch",
branches: "\u7531 input_schema.cases[].branch \u8207 default_branch \u6C7A\u5B9A\uFF08N \u8DEF\uFF0C\u975E\u56FA\u5B9A\u6E05\u55AE\uFF09",
edge_types: ["ON_BRANCH"],
usage: "\u9019\u9846\u4F9D value \u6BD4\u5C0D cases\uFF0C\u8F38\u51FA data.branch\uFF1D\u547D\u4E2D\u90A3\u500B case \u7684 branch \u540D\uFF08\u90FD\u6C92\u4E2D\u5247\u662F default_branch\uFF09\u3002\u4E0B\u6E38**\u6BCF\u689D\u8DEF\u5404\u63A5\u4E00\u689D ON_BRANCH \u908A\uFF0C\u4E26\u5728\u908A\u4E0A\u6A19 branch \u7B49\u65BC\u4F60\u5728 cases \u88E1\u53D6\u7684\u540D\u5B57**\u3002default_branch \u4E0D\u9700\u8981\u7279\u5225\u7684\u908A\u578B\uFF0C\u7167\u6A23\u7528 ON_BRANCH \u6A19\u5B83\u7684\u540D\u5B57\u5373\u53EF\u3002",
example: '{"cases":[{"match":"active","branch":"branch_active"}],"default_branch":"branch_default"}\nedges: [\n {"from":"my_switch","to":"\u8655\u7406\u555F\u7528","type":"ON_BRANCH","branch":"branch_active"},\n {"from":"my_switch","to":"\u8655\u7406\u5176\u4ED6","type":"ON_BRANCH","branch":"branch_default"}\n]'
},
try_catch: {
branch_field: "data.branch",
branches: ["try", "catch"],
edge_types: ["ON_BRANCH"],
usage: '\u9019\u9846\u770B\u4E0A\u6E38 error \u662F\u5426\u975E\u7A7A\uFF0C\u8F38\u51FA data.branch\uFF08"try"\uFF1D\u6C92\u932F\uFF0F"catch"\uFF1D\u6709\u932F\uFF09\u3002\u4E0B\u6E38\u63A5\u5169\u689D ON_BRANCH \u908A\uFF0Cbranch \u5206\u5225\u6A19 "try" \u8207 "catch"\u3002**\u932F\u8AA4\u8655\u7406\u4E0D\u9700\u8981\u5BEB code**\u2014\u2014\u628A\u8981\u88DC\u6551\u7684\u7BC0\u9EDE\u63A5\u5728 catch \u90A3\u689D\u908A\u5F8C\u9762\u5373\u53EF\u3002',
example: 'edges: [\n {"from":"my_try_catch","to":"\u6B63\u5E38\u6D41\u7A0B","type":"ON_BRANCH","branch":"try"},\n {"from":"my_try_catch","to":"\u88DC\u6551\u6D41\u7A0B","type":"ON_BRANCH","branch":"catch"}\n]'
}
};
function branchHintFor(componentId) {
if (!componentId) return void 0;
return BRANCH_HINTS[componentId.toLowerCase()];
}
__name(branchHintFor, "branchHintFor");
// src/actions/search-nodes.ts
async function searchNodes(parsed, config2, env2, mode = "discover", target) {
const nodeResults = {};
const missingNodes = [];
if (mode === "compile") {
for (const nodeName of parsed.nodeNames) {
const role = resolveNodeRole(nodeName, parsed);
if ((role === "Input" || role === "Output") && isVirtualIoName(nodeName)) {
nodeResults[nodeName] = { status: "found", componentId: nodeName.toLowerCase(), type: role };
continue;
}
const configComponent = config2?.[nodeName]?.component;
nodeResults[nodeName] = {
status: configComponent ? "found" : "unchecked",
componentId: configComponent ?? nodeName,
type: role
};
}
return { nodeResults, missingNodes };
}
const sub = env2?.WORKER_SUBDOMAIN;
const registryBase = env2?.REGISTRY_BASE_URL ?? (sub ? wasmWorkerUrl("registry", sub) : void 0);
const wantComponents = target !== "recipe";
const wantRecipes = target !== "component";
const catalog = !wantComponents ? { status: "ok", entries: [] } : registryBase ? await fetchCatalog(registryBase) : { status: "unreachable", entries: [] };
const recipes = wantRecipes && env2?.RECIPES ? await listAllRecipes2(env2.RECIPES) : [];
const byId = /* @__PURE__ */ new Map();
for (const e of catalog.entries) {
const prev = byId.get(e.canonical_id);
if (!prev || (e.score ?? 0) > (prev.score ?? 0)) byId.set(e.canonical_id, e);
for (const a of e.aliases ?? []) if (!byId.has(a)) byId.set(a, e);
}
for (const nodeName of parsed.nodeNames) {
const role = resolveNodeRole(nodeName, parsed);
if ((role === "Input" || role === "Output") && isVirtualIoName(nodeName)) {
nodeResults[nodeName] = { status: "found", componentId: nodeName.toLowerCase(), type: role };
continue;
}
const configComponent = config2?.[nodeName]?.component;
const componentId = configComponent ?? nodeName;
if (configComponent) {
nodeResults[nodeName] = { status: "found", componentId, type: role };
continue;
}
if (catalog.status === "unreachable") {
nodeResults[nodeName] = { status: "unknown", componentId, type: role };
continue;
}
if (catalog.status === "no_endpoint") {
const legacy = await legacyPerNodeLookup(registryBase, componentId, nodeName, role, env2, recipes);
nodeResults[nodeName] = legacy.info;
if (legacy.missing) missingNodes.push(nodeName);
continue;
}
const hit = byId.get(componentId);
if (hit) {
nodeResults[nodeName] = {
status: "found",
componentId,
type: role,
source: "component",
input_schema: hit.input_schema,
success_rate: typeof hit.success_rate === "number" ? hit.success_rate : void 0,
stability: typeof hit.stability === "string" ? hit.stability : void 0,
branch_hint: branchHintFor(componentId)
};
continue;
}
const recipe = recipes.find((r) => r.canonical_id === componentId);
if (recipe) {
nodeResults[nodeName] = {
status: "found",
componentId: recipe.canonical_id,
type: role,
source: "recipe",
description: recipe.description,
endpoint: recipe.endpoint,
payload_hint: buildPayloadHint(recipe)
};
continue;
}
const substituted = trySubstitution(nodeName, catalog.entries, recipes);
if (substituted) {
nodeResults[nodeName] = { ...substituted, type: role };
continue;
}
const similarComponents = similarFromCatalog(catalog.entries, nodeName);
const similarRecipes = similarFromRecipes(recipes, nodeName);
nodeResults[nodeName] = {
status: "not_found",
componentId,
type: role,
suggestion: buildSuggestion(componentId),
...similarComponents.length > 0 ? { similar_components: similarComponents } : {},
...similarRecipes.length > 0 ? { similar_recipes: similarRecipes } : {}
};
missingNodes.push(nodeName);
}
return { nodeResults, missingNodes };
}
__name(searchNodes, "searchNodes");
async function fetchCatalog(registryBase) {
try {
const res = await fetch(`${registryBase}/components/catalog`, { signal: AbortSignal.timeout(1e4) });
if (res.status === 404) return { status: "no_endpoint", entries: [] };
if (!res.ok) return { status: "unreachable", entries: [] };
const body = await res.json();
return { status: "ok", entries: body.data?.components ?? [] };
} catch {
return { status: "unreachable", entries: [] };
}
}
__name(fetchCatalog, "fetchCatalog");
async function listAllRecipes2(kv) {
try {
const list = await kv.list({ prefix: "recipe:" });
return (await Promise.all(
list.keys.map((k) => kv.get(k.name, "json"))
)).filter(Boolean);
} catch {
return [];
}
}
__name(listAllRecipes2, "listAllRecipes");
function similarFromCatalog(entries, nodeName) {
const searchableOf = /* @__PURE__ */ __name((e) => [e.canonical_id, e.display_name ?? "", e.description ?? "", ...e.aliases ?? [], ...e.tags ?? []].join(" ").toLowerCase(), "searchableOf");
const full = nodeName.toLowerCase();
const direct = entries.filter((e) => searchableOf(e).includes(full)).map((e) => e.canonical_id);
if (direct.length > 0) return [...new Set(direct)].slice(0, 3);
const tokens = extractTokens(nodeName);
if (tokens.length === 0) return [];
const count3 = /* @__PURE__ */ new Map();
for (const e of entries) {
const hay = searchableOf(e);
const hits = tokens.filter((t) => hay.includes(t)).length;
if (hits > 0) count3.set(e.canonical_id, Math.max(count3.get(e.canonical_id) ?? 0, hits));
}
return [...count3.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([id]) => id);
}
__name(similarFromCatalog, "similarFromCatalog");
function similarFromRecipes(recipes, nodeName) {
const tokens = [nodeName.toLowerCase(), ...extractTokens(nodeName)];
const seen = /* @__PURE__ */ new Set();
const matched = [];
for (const r of recipes) {
if (seen.has(r.canonical_id)) continue;
const hay = `${r.canonical_id} ${r.display_name ?? ""} ${r.description ?? ""}`.toLowerCase();
if (tokens.some((t) => hay.includes(t))) {
seen.add(r.canonical_id);
matched.push(r.canonical_id);
}
}
return matched.slice(0, 3);
}
__name(similarFromRecipes, "similarFromRecipes");
async function legacyPerNodeLookup(registryBase, componentId, nodeName, role, env2, recipes) {
const q = await fetchComponent(registryBase, componentId);
if (!q.ok) return { info: { status: "unknown", componentId, type: role }, missing: false };
if (q.entry) {
return {
info: {
status: "found",
componentId,
type: role,
source: "component",
input_schema: q.entry.input_schema,
success_rate: q.entry.success_rate,
stability: q.entry.stability,
branch_hint: branchHintFor(componentId)
},
missing: false
};
}
const recipe = recipes.find((r) => r.canonical_id === componentId) ?? (env2?.RECIPES ? await resolveRecipe(componentId, env2.RECIPES) : null);
if (recipe) {
return {
info: {
status: "found",
componentId: recipe.canonical_id,
type: role,
source: "recipe",
description: recipe.description,
endpoint: recipe.endpoint,
payload_hint: buildPayloadHint(recipe)
},
missing: false
};
}
const similarComponents = await searchSimilarComponents(registryBase, nodeName);
const similarRecipes = similarFromRecipes(recipes, nodeName);
return {
info: {
status: "not_found",
componentId,
type: role,
suggestion: buildSuggestion(componentId),
...similarComponents.length > 0 ? { similar_components: similarComponents } : {},
...similarRecipes.length > 0 ? { similar_recipes: similarRecipes } : {}
},
missing: true
};
}
__name(legacyPerNodeLookup, "legacyPerNodeLookup");
function trySubstitution(nodeName, catalogEntries, recipes) {
const lower = nodeName.toLowerCase();
const serviceHits = SERVICE_HINTS.filter((w) => lower.includes(w));
if (serviceHits.length > 0) {
const matched = /* @__PURE__ */ new Map();
for (const r of recipes) {
const hay = `${r.canonical_id} ${r.display_name ?? ""} ${r.description ?? ""}`.toLowerCase();
if (serviceHits.every((h) => hay.includes(h))) matched.set(r.canonical_id, r);
}
if (matched.size !== 1) return null;
const recipe = [...matched.values()][0];
return {
status: "resolved",
componentId: recipe.canonical_id,
source: "recipe",
description: recipe.description,
endpoint: recipe.endpoint,
substitution: {
from: nodeName,
componentId: "http_request",
// recipe=http_request+參數模板的具名封裝
recipe: recipe.canonical_id,
reason: `\u670D\u52D9\u8A5E\u300C${serviceHits.join("\u3001")}\u300D\u552F\u4E00\u547D\u4E2D recipe\u300C${recipe.canonical_id}\u300D\uFF1Bworkflow config \u5BEB component: ${recipe.canonical_id}\uFF08\u5E95\u5C64\u96F6\u4EF6\uFF1Dhttp_request\uFF09\uFF0C\u53EA\u9700\u586B payload`
}
};
}
const tokens = extractTokens(nodeName);
if (tokens.length === 0) return null;
const byCanonical = /* @__PURE__ */ new Map();
for (const e of catalogEntries) {
const strongHay = [e.canonical_id, e.display_name ?? "", ...e.aliases ?? []].join(" ").toLowerCase();
const weakHay = [e.description ?? "", ...e.tags ?? []].join(" ").toLowerCase();
const strongHits = tokens.filter((t) => strongHay.includes(t));
const weakCount = tokens.filter((t) => weakHay.includes(t)).length;
const score = strongHits.length * 10 + weakCount;
if (score === 0) continue;
const prev = byCanonical.get(e.canonical_id);
if (!prev || score > prev.score) byCanonical.set(e.canonical_id, { entry: e, score, strongHits });
}
const ranked = [...byCanonical.values()].sort((a, b) => b.score - a.score);
const top = ranked[0];
if (!top || top.strongHits.length === 0) return null;
if (ranked[1] && ranked[1].score >= top.score) return null;
return {
status: "resolved",
componentId: top.entry.canonical_id,
source: "component",
input_schema: top.entry.input_schema,
success_rate: typeof top.entry.success_rate === "number" ? top.entry.success_rate : void 0,
stability: typeof top.entry.stability === "string" ? top.entry.stability : void 0,
// 替換成分岔零件時(例「判斷有沒有新資料」→ if_control)一併附分支用法,
// 否則 AI 換到零件卻不知道怎麼接兩條路,仍會退回寫 code。
branch_hint: branchHintFor(top.entry.canonical_id),
substitution: {
from: nodeName,
componentId: top.entry.canonical_id,
reason: `\u65B7\u8A5E\u300C${top.strongHits.join("\u3001")}\u300D\u547D\u4E2D\u96F6\u4EF6\u300C${top.entry.canonical_id}\u300D\uFF08${top.entry.display_name ?? ""}\uFF09\u5F37\u6B04\u4F4D\u4E14\u5206\u6578\u552F\u4E00\u6700\u9AD8\uFF1B\u53EA\u9700\u7167 input_schema \u586B payload`
}
};
}
__name(trySubstitution, "trySubstitution");
var SERVICE_HINTS = [
"google",
"gmail",
"sheets",
"slides",
"gdocs",
"drive",
"calendar",
"youtube",
"slack",
"telegram",
"discord",
"line",
"whatsapp",
"twilio",
"notion",
"airtable",
"trello",
"jira",
"asana",
"linear",
"github",
"gitea",
"gitlab",
"bitbucket",
"stripe",
"paypal",
"shopify",
"hubspot",
"salesforce",
"openai",
"anthropic",
"claude",
"gemini",
"groq",
"twitter",
"facebook",
"instagram",
"linkedin",
"dropbox",
"zoom",
"sendgrid",
"mailgun",
"kbdb"
];
var COMPUTE_HINTS = [
"encrypt",
"decrypt",
"cipher",
"aes",
"rsa",
"sha",
"md5",
"hmac",
"hash",
"sign",
"verify",
"encode",
"decode",
"base64",
"hex",
"compress",
"decompress",
"zip",
"gzip",
"uuid",
"random",
"regex",
"math",
"calc",
"sort",
"dedup",
"diff",
"template",
"render",
"convert",
"transform",
"parse",
"format",
"csv",
"xml"
];
function buildSuggestion(componentId) {
const lower = componentId.toLowerCase();
const serviceHit = SERVICE_HINTS.find((w) => lower.includes(w));
const computeHit = COMPUTE_HINTS.find((w) => lower.includes(w));
if (serviceHit) {
return `\u5169\u5EAB\u90FD\u67E5\u904E\uFF0C\u96F6\u4EF6 registry \u8207 recipe \u5EAB\u7686\u7121\u300C${componentId}\u300D\u3002\u540D\u5B57\u542B\u670D\u52D9\u8A5E\u300C${serviceHit}\u300D\uFF1D\u5916\u90E8 API \u6A23\u8C8C \u2192 \u6C92\u6709\u6B64 recipe\uFF0C\u53EF\u81EA\u5DF1\u5BEB\uFF1A\u5BEB\u6CD5\u770B skill\u300Cwrite_recipe\u300D\uFF08arcrun_get_skill('write_recipe')\uFF09\uFF0C\u5BEB\u597D\u7528 acr recipe push \u6216 POST /recipes \u88DD\u4E0A\u5373\u53EF\u7528\uFF0C\u4E0D\u7528\u6539\u5E73\u53F0\u3002`;
}
if (computeHit) {
return `\u5169\u5EAB\u90FD\u67E5\u904E\uFF0C\u96F6\u4EF6 registry \u8207 recipe \u5EAB\u7686\u7121\u300C${componentId}\u300D\u3002\u540D\u5B57\u542B\u8A08\u7B97\u8A5E\u300C${computeHit}\u300D\uFF1D\u8A08\u7B97\u539F\u8A9E\u6A23\u8C8C \u2192 \u6C92\u6709\u6B64\u96F6\u4EF6\uFF0C\u53EF\u6295\u7A3F PR \u65B0\u589E WASM component\uFF1A\u505A\u6CD5\u770B skill\u300Cadd_new_wasm_component\u300D\uFF08arcrun_get_skill('add_new_wasm_component')\uFF09\u3002`;
}
return `\u5169\u5EAB\u90FD\u67E5\u904E\uFF0C\u96F6\u4EF6 registry \u8207 recipe \u5EAB\u7686\u7121\u300C${componentId}\u300D\uFF0C\u4E14\u540D\u5B57\u5224\u4E0D\u51FA\u578B\u3002\u7F3A\u5916\u90E8 API \u2192 \u81EA\u5DF1\u5BEB recipe\uFF08skill\u300Cwrite_recipe\u300D\uFF09\uFF1B\u7F3A\u8A08\u7B97\u80FD\u529B \u2192 \u6295\u7A3F\u96F6\u4EF6 PR\uFF08skill\u300Cadd_new_wasm_component\u300D\uFF0Ccomponent \u9032 WASM \u6C99\u7BB1\uFF09\u3002`;
}
__name(buildSuggestion, "buildSuggestion");
function buildPayloadHint(recipe) {
const parts = [];
if (recipe.body_template) {
parts.push("payload \u5DF2\u6536\u5728 recipe \u7684 body_template \u88E1\uFF0C\u4F60\u53EA\u8981\u628A {{\u8B8A\u6578}} \u5C0D\u61C9\u7684\u503C\u653E\u9032\u7BC0\u9EDE context");
} else if (recipe.body) {
parts.push("payload \u5F62\u72C0\u898B body \u6B04\u4F4D\uFF08{{\u8B8A\u6578}} \u7531\u7BC0\u9EDE context \u586B\uFF09");
} else {
parts.push("\u672A\u5B9A\u7FA9 body_template\uFF1A\u7BC0\u9EDE context \u6703\u6574\u5305\u7576 body \u9001\u51FA\uFF08_ \u958B\u982D\u7684\u5167\u90E8\u6B04\u4F4D\u6703\u88AB\u5254\u9664\uFF09");
}
if (recipe.response_map) {
parts.push("\u56DE\u61C9\u5DF2\u6B63\u898F\u5316\uFF1A\u57F7\u884C\u7D50\u679C\u9664\u4E86\u539F\u59CB data\uFF0C\u53E6\u9644 text\uFF08\u53D6\u503C\u8DEF\u5F91\u7B49\u898F\u5247\u5BEB\u5728 recipe \u88E1\uFF0C\u63DB\u6E90\u4E0D\u5FC5\u6539 workflow\uFF09");
} else {
parts.push("\u672A\u5B9A\u7FA9 response_map\uFF1A\u56DE\u61C9\u539F\u6A23\u653E\u5728 data\uFF0C\u53D6\u503C\u8981\u81EA\u5DF1\u6307\u8DEF\u5F91");
}
if (recipe.auth === "binding") {
parts.push(`\u8A8D\u8B49\uFF1Dbinding\uFF08\u514D\u91D1\u9470\uFF0C\u7528\u5E73\u53F0\u5167\u5EFA ${recipe.binding_name ?? "AI"}\uFF09`);
} else if (recipe.auth_service) {
parts.push(`\u8A8D\u8B49\u8D70 auth recipe\u300C${recipe.auth_service}\u300D\uFF08\u91D1\u9470\u7531\u7CFB\u7D71\u5728\u57F7\u884C\u524D\u6CE8\u5165\uFF0C\u4F60\u4E0D\u5FC5\u4E5F\u4E0D\u8A72\u586B\uFF09`);
}
return {
body_template: recipe.body_template,
response_map: recipe.response_map,
usage: parts.join("\uFF1B") + "\u3002"
};
}
__name(buildPayloadHint, "buildPayloadHint");
async function fetchComponent(registryBase, id) {
try {
const res = await fetch(`${registryBase}/components/${encodeURIComponent(id)}`, {
signal: AbortSignal.timeout(5e3)
});
if (res.status === 404) return { ok: true };
if (!res.ok) return { ok: false };
const body = await res.json();
if (body.success === false) return { ok: true };
const d = body.data ?? body;
return {
ok: true,
entry: {
input_schema: d.input_schema,
success_rate: typeof d.success_rate === "number" ? d.success_rate : void 0,
stability: typeof d.stability === "string" ? d.stability : void 0
}
};
} catch {
return { ok: false };
}
}
__name(fetchComponent, "fetchComponent");
function extractTokens(name) {
const tokens = [];
const ascii = name.toLowerCase().match(/[a-z0-9]{3,}/g) ?? [];
tokens.push(...ascii);
const cjkRuns = name.match(/[一-鿿]+/g) ?? [];
for (const run2 of cjkRuns) {
for (let i = 0; i + 2 <= run2.length; i++) tokens.push(run2.slice(i, i + 2));
}
return [...new Set(tokens)].slice(0, 8);
}
__name(extractTokens, "extractTokens");
async function searchRegistryIds(registryBase, q) {
try {
const res = await fetch(`${registryBase}/components/search?q=${encodeURIComponent(q)}`, {
signal: AbortSignal.timeout(5e3)
});
if (!res.ok) return [];
const body = await res.json();
return (body.data?.results ?? []).map((r) => r.canonical_id).filter((s) => !!s);
} catch {
return [];
}
}
__name(searchRegistryIds, "searchRegistryIds");
async function searchSimilarComponents(registryBase, nodeName) {
const direct = await searchRegistryIds(registryBase, nodeName);
if (direct.length > 0) return direct.slice(0, 3);
const tokens = extractTokens(nodeName);
if (tokens.length === 0) return [];
const hits = await Promise.all(tokens.map((t) => searchRegistryIds(registryBase, t)));
const count3 = /* @__PURE__ */ new Map();
for (const ids of hits) {
for (const id of ids) count3.set(id, (count3.get(id) ?? 0) + 1);
}
return [...count3.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([id]) => id);
}
__name(searchSimilarComponents, "searchSimilarComponents");
// src/actions/graph-builder.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
function buildExecutionGraph(parsed, nodeResults, graphId, graphName, config2) {
const nodes = [...parsed.nodeNames].map((name) => {
const nr = nodeResults[name];
const id = name.toLowerCase().replace(/\s+/g, "-");
const nodeConfig = config2?.[name] ?? {};
const componentId = nodeConfig.component ?? nr.componentId;
const { component: _component, ...staticParams } = nodeConfig;
const data = Object.keys(staticParams).length > 0 ? staticParams : void 0;
return { id, type: nr.type, componentId, label: name, data };
});
const edges = parsed.edges.map((e) => {
let iterator;
let label = e.label;
const foreachMatch = label.match(/^(?:對每個|FOREACH)\s+(\w+)$/i);
if (foreachMatch) {
iterator = foreachMatch[1];
label = "\u5C0D\u6BCF\u500B";
}
let branch;
const branchMatch = label.match(/^(?:ON_BRANCH|分支)\s*[((]\s*([\w-]+)\s*[))]$/i);
if (branchMatch) {
branch = branchMatch[1];
label = "ON_BRANCH";
}
const edge = {
from: e.from.toLowerCase().replace(/\s+/g, "-"),
to: e.to.toLowerCase().replace(/\s+/g, "-"),
type: toEdgeType(label)
};
if (iterator) edge.iterator = iterator;
if (branch) edge.branch = branch;
return edge;
});
return { id: graphId, name: graphName, nodes, edges };
}
__name(buildExecutionGraph, "buildExecutionGraph");
// src/actions/cypher-handlers.ts
async function handleCypherSearch(triplets, env2, mode = "discover", target) {
const parsed = parseTriplets(triplets);
if (!parsed) {
throw new Error("\u7121\u6CD5\u89E3\u6790\u4EFB\u4F55\u7BC0\u9EDE");
}
const { nodeResults, missingNodes } = await searchNodes(parsed, void 0, env2, mode, target);
const graph = buildExecutionGraph(parsed, nodeResults, "cypher-search-result", "Cypher Search Result");
return { nodes: nodeResults, cypher: { nodes: graph.nodes, edges: graph.edges }, missing: missingNodes };
}
__name(handleCypherSearch, "handleCypherSearch");
async function handleCypherExecute(triplets, context2, graphId, graphName, config2, env2, waitUntil, apiKey) {
const parsed = parseTriplets(triplets);
if (!parsed) {
throw new Error("\u7121\u6CD5\u89E3\u6790\u4EFB\u4F55\u7BC0\u9EDE");
}
const { nodeResults } = await searchNodes(parsed, config2, env2, "compile");
const graph = buildExecutionGraph(parsed, nodeResults, graphId, graphName, config2);
const parseResult = graphSchema.safeParse(graph);
if (!parseResult.success) {
throw new Error("\u5716\u5B9A\u7FA9\u7522\u751F\u5931\u6557");
}
const loader = createComponentLoader(env2);
const executor = new GraphExecutor(loader, void 0, env2, apiKey);
const start = Date.now();
try {
const result = await executor.execute(parseResult.data, context2 ?? {}, env2.EXEC_CONTEXT);
const duration_ms = Date.now() - start;
waitUntil(recordComponentStats(env2, graph.nodes, result.trace));
return { success: true, data: result.data, trace: result.trace, duration_ms, graph };
} catch (err) {
const duration_ms = Date.now() - start;
if (err instanceof WorkflowPaused) {
return {
success: true,
paused: true,
task_id: err.task_id,
run_id: err.run_id,
paused_node_id: err.paused_node_id,
trace: err.trace_so_far,
duration_ms,
graph
};
}
const errMsg = err instanceof Error ? err.message : String(err);
if (err instanceof ExecutionError) {
waitUntil(recordComponentStats(env2, graph.nodes, err.trace));
const traceFormatted = err.trace.map((s) => ({
node: s.nodeId,
status: s.error ? "failed" : "success",
...s.error ? { error: s.error } : {}
}));
throw new Error(JSON.stringify({
success: false,
error: errMsg,
failed_node: err.failed_node,
failed_input: err.failed_input,
trace: traceFormatted,
duration_ms
}));
}
throw err;
}
}
__name(handleCypherExecute, "handleCypherExecute");
// src/actions/target-search.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_component_loader();
// src/lib/workflow-search.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
async function fetchTenantWorkflowSearch(env2, apiKey, q, mode = "semantic") {
const base = (env2.KBDB_BASE_URL ?? "https://arcrun-kbdb.uncle6-me.workers.dev").replace(/\/$/, "");
const headers = { "Content-Type": "application/json" };
if (env2.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env2.KBDB_INTERNAL_TOKEN}`;
const params = new URLSearchParams({
q,
owner_id: apiKey,
// 租戶隔離(只搜本租戶的 workflow)
entry_type: "workflow",
// base 通用 filter(Q4),只回 workflow entry
mode
});
return fetch(`${base}/entries/search?${params.toString()}`, { headers });
}
__name(fetchTenantWorkflowSearch, "fetchTenantWorkflowSearch");
// src/actions/target-search.ts
async function searchByTarget(target, query, env2, apiKey) {
if (target === "component") {
const sub = env2.WORKER_SUBDOMAIN;
const registryBase = env2.REGISTRY_BASE_URL ?? (sub ? wasmWorkerUrl("registry", sub) : void 0);
if (!registryBase) return { ok: false, status: 502, error: "registry \u4F4D\u7F6E\u672A\u8A2D\u5B9A\uFF08WORKER_SUBDOMAIN\uFF0FREGISTRY_BASE_URL \u7686\u7F3A\uFF09" };
try {
const res2 = await fetch(
`${registryBase}/components/search?q=${encodeURIComponent(query)}`,
{ signal: AbortSignal.timeout(1e4) }
);
if (!res2.ok) return { ok: false, status: 502, error: `registry \u641C\u5C0B\u5931\u6557\uFF08HTTP ${res2.status}\uFF09` };
const body2 = await res2.json();
const results = (body2.data?.results ?? []).map((r) => {
if (!r || typeof r !== "object") return r;
const rec = r;
const hint = branchHintFor(typeof rec.canonical_id === "string" ? rec.canonical_id : void 0);
return hint ? { ...rec, branch_hint: hint } : rec;
});
return {
ok: true,
body: {
target,
query,
results,
count: body2.data?.count ?? 0
}
};
} catch (e) {
return { ok: false, status: 502, error: `registry \u67E5\u4E0D\u901A\uFF1A${e instanceof Error ? e.message : String(e)}` };
}
}
if (target === "recipe") {
if (!env2.RECIPES) return { ok: false, status: 502, error: "RECIPES KV \u672A\u7D81\u5B9A" };
const all = await listAllRecipes2(env2.RECIPES);
const q = query.toLowerCase();
const seen = /* @__PURE__ */ new Set();
const results = [];
for (const r of all) {
if (seen.has(r.canonical_id)) continue;
const hay = `${r.canonical_id} ${r.display_name ?? ""} ${r.description ?? ""}`.toLowerCase();
if (!hay.includes(q)) continue;
seen.add(r.canonical_id);
results.push({
canonical_id: r.canonical_id,
display_name: r.display_name,
description: r.description,
endpoint: r.endpoint,
// 3.12:逐顆查 recipe 時也要說得出「payload 怎麼填、回應怎麼取值」
payload_hint: buildPayloadHint(r)
});
}
return {
ok: true,
body: {
target,
query,
results,
count: results.length,
note: "\u641C\u7684\u662F\u672C\u90E8\u7F72\u79C1\u5EAB\uFF08workflow \u53EF\u76F4\u63A5 component: \u5F15\u7528\uFF09\u3002\u516C\u5EAB\uFF08\u591A\u4F5C\u8005\u5E02\u5834\uFF09\u8D70 MCP arcrun_recipe_search\uFF0FGET /public-recipes\u3002"
}
};
}
if (!apiKey) return { ok: false, status: 401, error: "target=workflow \u9700\u8981 X-Arcrun-API-Key header\uFF08workflow \u641C\u5C0B\u9650\u672C\u79DF\u6236\uFF09" };
const res = await fetchTenantWorkflowSearch(env2, apiKey, query);
if (!res.ok) return { ok: false, status: 502, error: `workflow \u641C\u5C0B\u5931\u6557\uFF08KBDB HTTP ${res.status}\uFF09` };
const body = await res.json();
return { ok: true, body: { target, query, ...body } };
}
__name(searchByTarget, "searchByTarget");
// src/routes/cypher.ts
var cypherRouter = new Hono2();
var VALID_TARGETS = /* @__PURE__ */ new Set(["component", "recipe", "workflow"]);
cypherRouter.post("/cypher/search", async (c) => {
const body = await c.req.json();
const rawTriplets = body?.triplets;
const target = typeof body?.target === "string" ? body.target : void 0;
if (target !== void 0 && !VALID_TARGETS.has(target)) {
return c.json({ error: `target \u53EA\u63A5\u53D7 component\uFF0Frecipe\uFF0Fworkflow\uFF0C\u6536\u5230\u300C${target}\u300D` }, 400);
}
const query = typeof body?.query === "string" ? body.query.trim() : "";
if (query) {
if (!target) {
return c.json({ error: "\u7D66 query \u5FC5\u9808\u540C\u6642\u7D66 target\uFF08component\uFF0Frecipe\uFF0Fworkflow\uFF09\uFF0C\u6307\u660E\u8981\u641C\u54EA\u500B\u5EAB" }, 400);
}
const apiKey = c.req.header("X-Arcrun-API-Key") ?? void 0;
const r = await searchByTarget(target, query, c.env, apiKey);
if (!r.ok) return c.json({ error: r.error }, r.status);
return c.json(r.body);
}
if (!Array.isArray(rawTriplets) || rawTriplets.length === 0) {
return c.json({ error: "triplets \u5FC5\u9808\u70BA\u975E\u7A7A\u5B57\u4E32\u9663\u5217\uFF08\u6216\u7D66 query + target \u505A\u540D\u5B57\u641C\u5C0B\uFF09" }, 400);
}
const mode = body?.mode === "compile" ? "compile" : "discover";
if (target && mode === "compile") {
return c.json({ error: "mode=compile\uFF08\u8907\u88FD\u8DEF\u5F91\uFF09\u4E0D\u67E5\u5EAB\uFF0C\u4E0D\u63A5\u53D7 target\uFF1B\u8981\u6307\u5B9A\u641C\u5C0B\u5C0D\u8C61\u8ACB\u7528 discover\uFF08\u9810\u8A2D\uFF09" }, 400);
}
if (target === "workflow") {
return c.json({ error: 'target=workflow \u662F\u540D\u5B57\u641C\u5C0B\uFF0C\u8ACB\u6539\u5E36 { target: "workflow", query: "..." }\uFF08\u4E0D\u5403 triplets\uFF09' }, 400);
}
try {
const now2 = /* @__PURE__ */ new Date();
const timestamp = now2.toISOString();
const versionId = `search-v1-${now2.getFullYear()}${String(now2.getMonth() + 1).padStart(2, "0")}${String(now2.getDate()).padStart(2, "0")}-${String(now2.getHours()).padStart(2, "0")}${String(now2.getMinutes()).padStart(2, "0")}${String(now2.getSeconds()).padStart(2, "0")}`;
const result = await handleCypherSearch(rawTriplets, c.env, mode, target);
const response = {
version: versionId,
timestamp,
triplets: rawTriplets,
nodes: result.nodes,
cypher: result.cypher,
missing: result.missing
};
return c.json(response);
} catch (err) {
const errMsg = err instanceof Error ? err.message : String(err);
return c.json({ error: errMsg }, 400);
}
});
cypherRouter.post("/cypher/execute", async (c) => {
const body = await c.req.json();
if (!Array.isArray(body?.triplets) || body.triplets.length === 0) {
return c.json({ error: "triplets \u5FC5\u9808\u70BA\u975E\u7A7A\u5B57\u4E32\u9663\u5217" }, 400);
}
const graphId = typeof body.graph_id === "string" ? body.graph_id : `triplet-exec-${Date.now()}`;
const graphName = typeof body.graph_name === "string" ? body.graph_name : "Triplet Execution";
const now2 = /* @__PURE__ */ new Date();
const timestamp = now2.toISOString();
const versionId = `execute-v1-${now2.getFullYear()}${String(now2.getMonth() + 1).padStart(2, "0")}${String(now2.getDate()).padStart(2, "0")}-${String(now2.getHours()).padStart(2, "0")}${String(now2.getMinutes()).padStart(2, "0")}${String(now2.getSeconds()).padStart(2, "0")}`;
const apiKey = c.req.header("X-Arcrun-API-Key") ?? void 0;
try {
const result = await handleCypherExecute(
body.triplets,
body.context,
graphId,
graphName,
body.config,
c.env,
(p) => c.executionCtx.waitUntil(p),
apiKey
);
const response = {
version: versionId,
timestamp,
...result
};
return c.json(response);
} catch (err) {
const errMsg = err instanceof Error ? err.message : String(err);
try {
const parsed = JSON.parse(errMsg);
const response = {
version: versionId,
timestamp,
...parsed
};
return c.json(response, 500);
} catch {
return c.json({ version: versionId, timestamp, success: false, error: errMsg, duration_ms: 0 }, 500);
}
}
});
// src/routes/validate.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
init_schemas();
init_telemetry();
var validateRouter = new Hono2();
validateRouter.post("/validate", async (c) => {
const start = Date.now();
const apiKey = c.req.header("X-Arcrun-API-Key");
const userAgent = c.req.header("User-Agent") ?? void 0;
const body = await c.req.json();
const parsed = graphSchema.safeParse(body);
if (!parsed.success) {
recordTelemetry(c.env, apiKey, {
event_type: "validation_error",
error_code: "schema_failed",
duration_ms: Date.now() - start,
agent_user_agent: userAgent
}, c.executionCtx);
return c.json({ valid: false, errors: parsed.error.issues }, 400);
}
const nodeIds = new Set(parsed.data.nodes.map((n) => n.id));
const invalidEdges = parsed.data.edges.filter((e) => !nodeIds.has(e.from) || !nodeIds.has(e.to));
if (invalidEdges.length > 0) {
recordTelemetry(c.env, apiKey, {
event_type: "validation_error",
error_code: "edge_node_missing",
duration_ms: Date.now() - start,
agent_user_agent: userAgent
}, c.executionCtx);
return c.json({
valid: false,
errors: invalidEdges.map((e) => `\u908A ${e.from} \u2192 ${e.to} \u6307\u5411\u4E0D\u5B58\u5728\u7684\u7BC0\u9EDE`)
}, 400);
}
return c.json({ valid: true, nodeCount: parsed.data.nodes.length, edgeCount: parsed.data.edges.length });
});
// src/routes/docs.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
init_dist();
// src/lib/openapi.ts
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_process();
init_virtual_unenv_global_polyfill_cloudflare_unenv_preset_node_console();
init_performance2();
var OPENAPI_SPEC = {
openapi: "3.0.3",
info: {
title: "arcrun cypher-executor API",
description: "AI Workflow Execution Engine \u2014 \u900F\u904E\u4E09\u5143\u7D44 Triplet \u6216\u5716 Graph \u5B9A\u7FA9\u5DE5\u4F5C\u6D41\uFF0C\u7CFB\u7D71\u57F7\u884C\u4E26\u56DE\u50B3\u7D50\u679C",
version: "1.0.0",
contact: {
name: "arcrun",
url: "https://github.com/arcrun/arcrun"
}
},
servers: [
{ url: "https://cypher.arcrun.dev", description: "arcrun.dev Hosted" },
{ url: "http://localhost:8787", description: "Local Development" }
],
paths: {
"/": {
get: {
summary: "Health Check",
tags: ["Health"],
responses: {
"200": {
description: "Service is running",
content: {
"application/json": {
schema: {
type: "object",
properties: {
service: { type: "string" },
version: { type: "string" },
status: { type: "string" }
}
}
}
}
}
}
}
},
"/cypher/search": {
post: {
summary: "\u641C\u5C0B\u5DE5\u4F5C\u6D41\u9700\u8981\u7684\u96F6\u4EF6",
tags: ["Cypher"],
description: "\u7528\u4E09\u5143\u7D44\u63CF\u8FF0\u5DE5\u4F5C\u6D41\uFF0C\u7CFB\u7D71\u89E3\u6790\u4E26\u5F9E Registry \u67E5\u8A62\u5C0D\u61C9\u96F6\u4EF6",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
triplets: {
type: "array",
items: { type: "string" },
example: ["start >> \u5B8C\u6210\u5F8C >> get-data", "get-data >> \u5B8C\u6210\u5F8C >> done"],
description: '\u4E09\u5143\u7D44\u9663\u5217\uFF0C\u683C\u5F0F\uFF1A"FROM >> ACTION >> TO"'
},
auto_publish: {
type: "boolean",
default: true,
description: "\u7F3A\u5931\u7684\u96F6\u4EF6\u662F\u5426\u81EA\u52D5\u7522\u751F\u767C\u4F48"
}
},
required: ["triplets"]
}
}
}
},
responses: {
"200": {
description: "\u96F6\u4EF6\u641C\u5C0B\u6210\u529F\uFF08\u542B\u7248\u672C\u865F\u548C\u6642\u6233\uFF0C\u9069\u5408 Markdown \u6587\u6A94\u8FFD\u8E64\uFF09",
content: {
"application/json": {
schema: {
type: "object",
properties: {
version: { type: "string", example: "search-v1-20260327-143022", description: "\u7248\u672C\u865F\uFF08endpoint-v{major}-{timestamp}\uFF09" },
timestamp: { type: "string", format: "date-time", description: "ISO 8601 \u6642\u6233" },
triplets: { type: "array", items: { type: "string" }, description: "\u56DE\u9001\u7684\u4E09\u5143\u7D44\u5217\u8868" },
nodes: { type: "object", description: "\u641C\u5C0B\u5230\u7684\u96F6\u4EF6\u53CA\u5176\u72C0\u614B" },
cypher: { type: "object", description: "\u5DE5\u4F5C\u6D41\u5716\uFF08null \u82E5\u6709\u7F3A\u5931\u96F6\u4EF6\uFF09" },
missing: { type: "array", items: { type: "string" }, description: "\u7F3A\u5931\u96F6\u4EF6\u5217\u8868" },
auto_published: { type: "object", description: "\u81EA\u52D5\u767C\u4F48\u7684\u96F6\u4EF6\uFF08\u82E5 auto_publish=true\uFF09" }
}
}
}
}
},
"400": { description: "\u7121\u6CD5\u89E3\u6790\u4E09\u5143\u7D44" }
}
}
},
"/cypher/execute": {
post: {
summary: "\u57F7\u884C\u5DE5\u4F5C\u6D41",
tags: ["Cypher"],
description: "\u76F4\u63A5\u57F7\u884C triplets\uFF0C\u56DE\u50B3\u5B8C\u6574\u57F7\u884C\u7D50\u679C\u3002\u652F\u63F4\u81EA\u52D5\u767C\u4F48\u7F3A\u5931\u96F6\u4EF6\u3002",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
triplets: {
type: "array",
items: { type: "string" },
description: '\u4E09\u5143\u7D44\u9663\u5217\uFF0C\u683C\u5F0F\uFF1A"FROM >> ACTION >> TO"'
},
context: {
type: "object",
description: "\u57F7\u884C\u4E0A\u4E0B\u6587\uFF0C\u50B3\u5165\u5404\u7BC0\u9EDE\u4F5C\u70BA\u521D\u59CB\u53C3\u6578"
},
auto_publish: {
type: "boolean",
default: true,
description: "\u7F3A\u5931\u7684\u96F6\u4EF6\u662F\u5426\u81EA\u52D5\u7522\u751F\u81E8\u6642\u5BE6\u4F5C"
}
},
required: ["triplets"]
}
}
}
},
responses: {
"200": {
description: "\u57F7\u884C\u6210\u529F\uFF08\u542B\u7248\u672C\u865F\u548C\u6642\u6233\uFF09",
content: {
"application/json": {
schema: {
type: "object",
properties: {
version: { type: "string", example: "execute-v1-20260327-143022", description: "\u7248\u672C\u865F\uFF08endpoint-v{major}-{timestamp}\uFF09" },
timestamp: { type: "string", format: "date-time", description: "ISO 8601 \u6642\u6233" },
success: { type: "boolean", enum: [true] },
data: { type: "object", description: "\u57F7\u884C\u7D50\u679C" },
trace: { type: "array", description: "\u57F7\u884C\u8DDF\u8E64" },
duration_ms: { type: "number" }
}
}
}
}
},
"500": {
description: "\u57F7\u884C\u5931\u6557\u6216\u90E8\u4EFD\u96F6\u4EF6\u7F3A\u5931\uFF08\u542B\u7248\u672C\u865F\u548C\u6642\u6233\uFF09",
content: {
"application/json": {
schema: {
type: "object",
properties: {
version: { type: "string", example: "execute-v1-20260327-143022", description: "\u7248\u672C\u865F\uFF08endpoint-v{major}-{timestamp}\uFF09" },
timestamp: { type: "string", format: "date-time", description: "ISO 8601 \u6642\u6233" },
success: { type: "boolean", enum: [false] },
error: { type: "string" },
missing: { type: "array", items: { type: "string" }, description: "\u7121\u6CD5\u81EA\u52D5\u767C\u4F48\u7684\u7F3A\u5931\u96F6\u4EF6" },
auto_published: {
type: "object",
description: "\u81EA\u52D5\u767C\u4F48\u7684\u96F6\u4EF6\u8CC7\u8A0A",
additionalProperties: {
type: "object",
properties: {
ok: { type: "boolean" },
componentId: { type: "string" },
temporary_endpoint: { type: "string", format: "uri", description: "\u81E8\u6642\u5BE6\u4F5C\u7684 URL" },
implement_by: { type: "string", format: "date-time", description: "\u5BE6\u4F5C\u622A\u6B62\u6642\u9593" }
}
}
},
duration_ms: { type: "number" }
}
}
}
}
}
}
}
},
"/webhooks": {
post: {
summary: "\u5EFA\u7ACB Webhook",
tags: ["Webhooks"],
description: "\u5C07\u5DE5\u4F5C\u6D41\u8A3B\u518A\u6210 Webhook\uFF0C\u5F97\u5230\u516C\u958B URL",
requestBody: {
required: true,
content: {
"application/json": {
schema: {
type: "object",
properties: {
triplets: {
type: "array",
items: { type: "string" }
},
description: { type: "string" }
}
}
}
}
},
responses: {
"201": {
description: "Webhook \u5EFA\u7ACB\u6210\u529F",
content: {
"application/json": {
schema: {
type: "object",
properties: {
token: { type: "string" },
webhook_url: { type: "string", format: "uri" },
description: { type: "string" },
created_at: { type: "string", format: "date-time" }
}
}
}
}
}
}
},
get: {
summary: "\u5217\u51FA\u6240\u6709 Webhooks",
tags: ["Webhooks"],
parameters: [
{
name: "Authorization",
in: "header",
required: true,
schema: { type: "string", example: "Bearer u6u_xxxxx" },
description: "API Key \u8A8D\u8B49"
}
],
responses: {
"200": {
description: "Webhooks \u5217\u8868",
content: {
"application/json": {
schema: {
type: "object",
properties: {
webhooks: {
type: "array",
items: {
type: "object",
properties: {
token: { type: "string" },
description: { type: "string" },
created_at: { type: "string", format: "date-time" }
}
}
},
total: { type: "number" }
}
}
}
}
},
"401": { description: "\u672A\u6388\u6B0A" }
}
}
},
"/webhooks/{token}": {
get: {
summary: "\u67E5\u8A62\u55AE\u500B Webhook",
tags: ["Webhooks"],
parameters: [
{
name: "token",
in: "path",
required: true,
schema: { type: "string" }
}
],
responses: {
"200": {
description: "Webhook \u8CC7\u8A0A"
},
"404": { description: "Webhook \u4E0D\u5B58\u5728" }
}
},
delete: {
summary: "\u522A\u9664 Webhook",
tags: ["Webhooks"],
parameters: [
{
name: "token",
in: "path",
required: true,
schema: { type: "string" }
}
],
responses: {
"200": { description: "Webhook \u5DF2\u522A\u9664" },
"404": { description: "Webhook \u4E0D\u5B58\u5728" }
}
}
}
},
components: {
securitySchemes: {
ApiKeyAuth: {
type: "apiKey",
in: "header",
name: "Authorization"
}
}
}
};
// src/routes/docs.ts
var docsRouter = new Hono2();
docsRouter.get("/openapi.json", (c) => {
return c.json(OPENAPI_SPEC);
});
docsRouter.get("/docs", (c) => {
const specStr = JSON.stringify(OPENAPI_SPEC);
const htmlStr = `
Cypher Executor API Docs