diff --git a/.gitignore b/.gitignore index 6bb0488..290ebcf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,10 @@ dist/ # 例外:放行 .component-builds 的部署物 wasm — self-host 用戶 / acr init 從 repo 直接拿這份部署 # (推翻 rule 05 原「wasm 不 commit」慣例,見 .agents/specs/arcrun/sdk-and-website/self-hosted-init.md §6) !.component-builds/**/component.wasm +# 例外:Arcrun#80 tier2 worker 官方編譯成品(cypher-executor/kbdb/http_request/code/mcp 的 +# esbuild bundle + 隨附 wasm part)——commit 進 repo 同一套理由:固定位置、any clone 都拿得到, +# 不必自己再編一次(見 scripts/build-worker-artifacts.mjs)。 +!.worker-builds/**/*.wasm # 例外:code 零件(自足 Worker)的 vendored quickjs.wasm 同屬部署物 —— acr init/update 從 # repo archive 直接部署(同上 .component-builds 放行邏輯)。來源=npm 套件 # @jitl/quickjs-wasmfile-release-sync 的 emscripten-module.wasm,由 postinstall vendor-wasm.mjs diff --git a/.worker-builds/arcrun-code/quickjs.wasm b/.worker-builds/arcrun-code/quickjs.wasm new file mode 100644 index 0000000..1815757 Binary files /dev/null and b/.worker-builds/arcrun-code/quickjs.wasm differ diff --git a/.worker-builds/arcrun-code/worker.mjs b/.worker-builds/arcrun-code/worker.mjs new file mode 100644 index 0000000..4096fc7 --- /dev/null +++ b/.worker-builds/arcrun-code/worker.mjs @@ -0,0 +1,4014 @@ +var __defProp = Object.defineProperty; +var __getOwnPropNames = Object.getOwnPropertyNames; +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 }); +}; + +// registry/components/code/node_modules/@jitl/quickjs-ffi-types/dist/index.mjs +var EvalFlags, IntrinsicsFlags, JSPromiseStateEnum, GetOwnPropertyNamesFlags, IsEqualOp; +var init_dist = __esm({ + "registry/components/code/node_modules/@jitl/quickjs-ffi-types/dist/index.mjs"() { + EvalFlags = { JS_EVAL_TYPE_GLOBAL: 0, JS_EVAL_TYPE_MODULE: 1, JS_EVAL_TYPE_DIRECT: 2, JS_EVAL_TYPE_INDIRECT: 3, JS_EVAL_TYPE_MASK: 3, JS_EVAL_FLAG_STRICT: 8, JS_EVAL_FLAG_STRIP: 16, JS_EVAL_FLAG_COMPILE_ONLY: 32, JS_EVAL_FLAG_BACKTRACE_BARRIER: 64 }; + IntrinsicsFlags = { BaseObjects: 1, Date: 2, Eval: 4, StringNormalize: 8, RegExp: 16, RegExpCompiler: 32, JSON: 64, Proxy: 128, MapSet: 256, TypedArrays: 512, Promise: 1024, BigInt: 2048, BigFloat: 4096, BigDecimal: 8192, OperatorOverloading: 16384, BignumExt: 32768 }; + JSPromiseStateEnum = { Pending: 0, Fulfilled: 1, Rejected: 2 }; + GetOwnPropertyNamesFlags = { JS_GPN_STRING_MASK: 1, JS_GPN_SYMBOL_MASK: 2, JS_GPN_PRIVATE_MASK: 4, JS_GPN_ENUM_ONLY: 16, JS_GPN_SET_ENUM: 32, QTS_GPN_NUMBER_MASK: 64, QTS_STANDARD_COMPLIANT_NUMBER: 128 }; + IsEqualOp = { IsStrictlyEqual: 0, IsSameValue: 1, IsSameValueZero: 2 }; + } +}); + +// registry/components/code/node_modules/quickjs-emscripten-core/dist/chunk-JTKJZQYV.mjs +function debugLog(...args) { + QTS_DEBUG && console.log("quickjs-emscripten:", ...args); +} +function* awaitYield(value) { + return yield value; +} +function awaitYieldOf(generator) { + return awaitYield(awaitEachYieldedPromise(generator)); +} +function maybeAsyncFn(that, fn) { + return (...args) => { + let generator = fn.call(that, AwaitYield, ...args); + return awaitEachYieldedPromise(generator); + }; +} +function maybeAsync(that, startGenerator) { + let generator = startGenerator.call(that, AwaitYield); + return awaitEachYieldedPromise(generator); +} +function awaitEachYieldedPromise(gen) { + function handleNextStep(step) { + return step.done ? step.value : step.value instanceof Promise ? step.value.then((value) => handleNextStep(gen.next(value)), (error) => handleNextStep(gen.throw(error))) : handleNextStep(gen.next(step.value)); + } + return handleNextStep(gen.next()); +} +function scopeFinally(scope, blockError) { + let disposeError; + try { + scope.dispose(); + } catch (error) { + disposeError = error; + } + if (blockError && disposeError) throw Object.assign(blockError, { message: `${blockError.message} + Then, failed to dispose scope: ${disposeError.message}`, disposeError }), blockError; + if (blockError || disposeError) throw blockError || disposeError; +} +function createDisposableArray(items) { + let array = items ? Array.from(items) : []; + function disposeAlive() { + return array.forEach((disposable) => disposable.alive ? disposable.dispose() : void 0); + } + function someIsAlive() { + return array.some((disposable) => disposable.alive); + } + return Object.defineProperty(array, SymbolDispose, { configurable: true, enumerable: false, value: disposeAlive }), Object.defineProperty(array, "dispose", { configurable: true, enumerable: false, value: disposeAlive }), Object.defineProperty(array, "alive", { configurable: true, enumerable: false, get: someIsAlive }), array; +} +function isDisposable(value) { + return !!(value && (typeof value == "object" || typeof value == "function") && "alive" in value && typeof value.alive == "boolean" && "dispose" in value && typeof value.dispose == "function"); +} +function intrinsicsToFlags(intrinsics) { + if (!intrinsics) return 0; + let result = 0; + for (let [maybeIntrinsicName, enabled] of Object.entries(intrinsics)) { + if (!(maybeIntrinsicName in IntrinsicsFlags)) throw new QuickJSUnknownIntrinsic(maybeIntrinsicName); + enabled && (result |= IntrinsicsFlags[maybeIntrinsicName]); + } + return result; +} +function evalOptionsToFlags(evalOptions) { + if (typeof evalOptions == "number") return evalOptions; + if (evalOptions === void 0) return 0; + let { type, strict, strip, compileOnly, backtraceBarrier } = evalOptions, flags = 0; + return type === "global" && (flags |= EvalFlags.JS_EVAL_TYPE_GLOBAL), type === "module" && (flags |= EvalFlags.JS_EVAL_TYPE_MODULE), strict && (flags |= EvalFlags.JS_EVAL_FLAG_STRICT), strip && (flags |= EvalFlags.JS_EVAL_FLAG_STRIP), compileOnly && (flags |= EvalFlags.JS_EVAL_FLAG_COMPILE_ONLY), backtraceBarrier && (flags |= EvalFlags.JS_EVAL_FLAG_BACKTRACE_BARRIER), flags; +} +function getOwnPropertyNamesOptionsToFlags(options) { + if (typeof options == "number") return options; + if (options === void 0) return 0; + let { strings: includeStrings, symbols: includeSymbols, quickjsPrivate: includePrivate, onlyEnumerable, numbers: includeNumbers, numbersAsStrings } = options, flags = 0; + return includeStrings && (flags |= GetOwnPropertyNamesFlags.JS_GPN_STRING_MASK), includeSymbols && (flags |= GetOwnPropertyNamesFlags.JS_GPN_SYMBOL_MASK), includePrivate && (flags |= GetOwnPropertyNamesFlags.JS_GPN_PRIVATE_MASK), onlyEnumerable && (flags |= GetOwnPropertyNamesFlags.JS_GPN_ENUM_ONLY), includeNumbers && (flags |= GetOwnPropertyNamesFlags.QTS_GPN_NUMBER_MASK), numbersAsStrings && (flags |= GetOwnPropertyNamesFlags.QTS_STANDARD_COMPLIANT_NUMBER), flags; +} +function concat(...values) { + let result = []; + for (let value of values) value !== void 0 && (result = result.concat(value)); + return result; +} +function applyBaseRuntimeOptions(runtime, options) { + options.interruptHandler && runtime.setInterruptHandler(options.interruptHandler), options.maxStackSizeBytes !== void 0 && runtime.setMaxStackSize(options.maxStackSizeBytes), options.memoryLimitBytes !== void 0 && runtime.setMemoryLimit(options.memoryLimitBytes); +} +function applyModuleEvalRuntimeOptions(runtime, options) { + options.moduleLoader && runtime.setModuleLoader(options.moduleLoader), options.shouldInterrupt && runtime.setInterruptHandler(options.shouldInterrupt), options.memoryLimitBytes !== void 0 && runtime.setMemoryLimit(options.memoryLimitBytes), options.maxStackSizeBytes !== void 0 && runtime.setMaxStackSize(options.maxStackSizeBytes); +} +var __defProp2, __export2, QTS_DEBUG, errors_exports, QuickJSUnwrapError, QuickJSWrongOwner, QuickJSUseAfterFree, QuickJSNotImplemented, QuickJSAsyncifyError, QuickJSAsyncifySuspended, QuickJSMemoryLeakDetected, QuickJSEmscriptenModuleError, QuickJSUnknownIntrinsic, QuickJSPromisePending, QuickJSEmptyGetOwnPropertyNames, AwaitYield, UsingDisposable, SymbolDispose, prototypeAsAny, Lifetime, StaticLifetime, WeakLifetime, Scope, AbstractDisposableResult, DisposableSuccess, DisposableFail, DisposableResult, QuickJSDeferredPromise, ModuleMemory, UnstableSymbol, DefaultIntrinsics, QuickJSIterator, ContextMemory, QuickJSContext, QuickJSRuntime, QuickJSEmscriptenModuleCallbacks, QuickJSModuleCallbacks, QuickJSWASMModule; +var init_chunk_JTKJZQYV = __esm({ + "registry/components/code/node_modules/quickjs-emscripten-core/dist/chunk-JTKJZQYV.mjs"() { + init_dist(); + init_dist(); + __defProp2 = Object.defineProperty; + __export2 = (target, all) => { + for (var name in all) __defProp2(target, name, { get: all[name], enumerable: true }); + }; + QTS_DEBUG = false; + errors_exports = {}; + __export2(errors_exports, { QuickJSAsyncifyError: () => QuickJSAsyncifyError, QuickJSAsyncifySuspended: () => QuickJSAsyncifySuspended, QuickJSEmptyGetOwnPropertyNames: () => QuickJSEmptyGetOwnPropertyNames, QuickJSEmscriptenModuleError: () => QuickJSEmscriptenModuleError, QuickJSMemoryLeakDetected: () => QuickJSMemoryLeakDetected, QuickJSNotImplemented: () => QuickJSNotImplemented, QuickJSPromisePending: () => QuickJSPromisePending, QuickJSUnknownIntrinsic: () => QuickJSUnknownIntrinsic, QuickJSUnwrapError: () => QuickJSUnwrapError, QuickJSUseAfterFree: () => QuickJSUseAfterFree, QuickJSWrongOwner: () => QuickJSWrongOwner }); + QuickJSUnwrapError = class extends Error { + constructor(cause, context) { + let message = typeof cause == "object" && cause && "message" in cause ? String(cause.message) : String(cause); + super(message); + this.cause = cause; + this.context = context; + this.name = "QuickJSUnwrapError"; + } + }; + QuickJSWrongOwner = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSWrongOwner"; + } + }; + QuickJSUseAfterFree = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSUseAfterFree"; + } + }; + QuickJSNotImplemented = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSNotImplemented"; + } + }; + QuickJSAsyncifyError = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSAsyncifyError"; + } + }; + QuickJSAsyncifySuspended = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSAsyncifySuspended"; + } + }; + QuickJSMemoryLeakDetected = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSMemoryLeakDetected"; + } + }; + QuickJSEmscriptenModuleError = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSEmscriptenModuleError"; + } + }; + QuickJSUnknownIntrinsic = class extends TypeError { + constructor() { + super(...arguments); + this.name = "QuickJSUnknownIntrinsic"; + } + }; + QuickJSPromisePending = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSPromisePending"; + } + }; + QuickJSEmptyGetOwnPropertyNames = class extends Error { + constructor() { + super(...arguments); + this.name = "QuickJSEmptyGetOwnPropertyNames"; + } + }; + AwaitYield = awaitYield; + AwaitYield.of = awaitYieldOf; + UsingDisposable = class { + [Symbol.dispose]() { + return this.dispose(); + } + }; + SymbolDispose = Symbol.dispose ?? Symbol.for("Symbol.dispose"); + prototypeAsAny = UsingDisposable.prototype; + prototypeAsAny[SymbolDispose] || (prototypeAsAny[SymbolDispose] = function() { + return this.dispose(); + }); + Lifetime = class _Lifetime extends UsingDisposable { + constructor(_value, copier, disposer, _owner) { + super(); + this._value = _value; + this.copier = copier; + this.disposer = disposer; + this._owner = _owner; + this._alive = true; + this._constructorStack = QTS_DEBUG ? new Error("Lifetime constructed").stack : void 0; + } + get alive() { + return this._alive; + } + get value() { + return this.assertAlive(), this._value; + } + get owner() { + return this._owner; + } + get dupable() { + return !!this.copier; + } + dup() { + if (this.assertAlive(), !this.copier) throw new Error("Non-dupable lifetime"); + return new _Lifetime(this.copier(this._value), this.copier, this.disposer, this._owner); + } + consume(map) { + this.assertAlive(); + let result = map(this); + return this.dispose(), result; + } + map(map) { + return this.assertAlive(), map(this); + } + tap(fn) { + return fn(this), this; + } + dispose() { + this.assertAlive(), this.disposer && this.disposer(this._value), this._alive = false; + } + assertAlive() { + if (!this.alive) throw this._constructorStack ? new QuickJSUseAfterFree(`Lifetime not alive +${this._constructorStack} +Lifetime used`) : new QuickJSUseAfterFree("Lifetime not alive"); + } + }; + StaticLifetime = class extends Lifetime { + constructor(value, owner) { + super(value, void 0, void 0, owner); + } + get dupable() { + return true; + } + dup() { + return this; + } + dispose() { + } + }; + WeakLifetime = class extends Lifetime { + constructor(value, copier, disposer, owner) { + super(value, copier, disposer, owner); + } + dispose() { + this._alive = false; + } + }; + Scope = class _Scope extends UsingDisposable { + constructor() { + super(...arguments); + this._disposables = new Lifetime(/* @__PURE__ */ new Set()); + this.manage = (lifetime) => (this._disposables.value.add(lifetime), lifetime); + } + static withScope(block) { + let scope = new _Scope(), blockError; + try { + return block(scope); + } catch (error) { + throw blockError = error, error; + } finally { + scopeFinally(scope, blockError); + } + } + static withScopeMaybeAsync(_this, block) { + return maybeAsync(void 0, function* (awaited) { + let scope = new _Scope(), blockError; + try { + return yield* awaited.of(block.call(_this, awaited, scope)); + } catch (error) { + throw blockError = error, error; + } finally { + scopeFinally(scope, blockError); + } + }); + } + static async withScopeAsync(block) { + let scope = new _Scope(), blockError; + try { + return await block(scope); + } catch (error) { + throw blockError = error, error; + } finally { + scopeFinally(scope, blockError); + } + } + get alive() { + return this._disposables.alive; + } + dispose() { + let lifetimes = Array.from(this._disposables.value.values()).reverse(); + for (let lifetime of lifetimes) lifetime.alive && lifetime.dispose(); + this._disposables.dispose(); + } + }; + AbstractDisposableResult = class _AbstractDisposableResult extends UsingDisposable { + static success(value) { + return new DisposableSuccess(value); + } + static fail(error, onUnwrap) { + return new DisposableFail(error, onUnwrap); + } + static is(result) { + return result instanceof _AbstractDisposableResult; + } + }; + DisposableSuccess = class extends AbstractDisposableResult { + constructor(value) { + super(); + this.value = value; + } + get alive() { + return isDisposable(this.value) ? this.value.alive : true; + } + dispose() { + isDisposable(this.value) && this.value.dispose(); + } + unwrap() { + return this.value; + } + unwrapOr(_fallback) { + return this.value; + } + }; + DisposableFail = class extends AbstractDisposableResult { + constructor(error, onUnwrap) { + super(); + this.error = error; + this.onUnwrap = onUnwrap; + } + get alive() { + return isDisposable(this.error) ? this.error.alive : true; + } + dispose() { + isDisposable(this.error) && this.error.dispose(); + } + unwrap() { + throw this.onUnwrap(this), this.error; + } + unwrapOr(fallback) { + return fallback; + } + }; + DisposableResult = AbstractDisposableResult; + QuickJSDeferredPromise = class extends UsingDisposable { + constructor(args) { + super(); + this.resolve = (value) => { + this.resolveHandle.alive && (this.context.unwrapResult(this.context.callFunction(this.resolveHandle, this.context.undefined, value || this.context.undefined)).dispose(), this.disposeResolvers(), this.onSettled()); + }; + this.reject = (value) => { + this.rejectHandle.alive && (this.context.unwrapResult(this.context.callFunction(this.rejectHandle, this.context.undefined, value || this.context.undefined)).dispose(), this.disposeResolvers(), this.onSettled()); + }; + this.dispose = () => { + this.handle.alive && this.handle.dispose(), this.disposeResolvers(); + }; + this.context = args.context, this.owner = args.context.runtime, this.handle = args.promiseHandle, this.settled = new Promise((resolve) => { + this.onSettled = resolve; + }), this.resolveHandle = args.resolveHandle, this.rejectHandle = args.rejectHandle; + } + get alive() { + return this.handle.alive || this.resolveHandle.alive || this.rejectHandle.alive; + } + disposeResolvers() { + this.resolveHandle.alive && this.resolveHandle.dispose(), this.rejectHandle.alive && this.rejectHandle.dispose(); + } + }; + ModuleMemory = class { + constructor(module) { + this.module = module; + } + toPointerArray(handleArray) { + let typedArray = new Int32Array(handleArray.map((handle) => handle.value)), numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT, ptr = this.module._malloc(numBytes); + return new Uint8Array(this.module.HEAPU8.buffer, ptr, numBytes).set(new Uint8Array(typedArray.buffer)), new Lifetime(ptr, void 0, (ptr2) => this.module._free(ptr2)); + } + newTypedArray(kind, length) { + let zeros = new kind(new Array(length).fill(0)), numBytes = zeros.length * zeros.BYTES_PER_ELEMENT, ptr = this.module._malloc(numBytes), typedArray = new kind(this.module.HEAPU8.buffer, ptr, length); + return typedArray.set(zeros), new Lifetime({ typedArray, ptr }, void 0, (value) => this.module._free(value.ptr)); + } + newMutablePointerArray(length) { + return this.newTypedArray(Int32Array, length); + } + newHeapCharPointer(string) { + let strlen = this.module.lengthBytesUTF8(string), dataBytes = strlen + 1, ptr = this.module._malloc(dataBytes); + return this.module.stringToUTF8(string, ptr, dataBytes), new Lifetime({ ptr, strlen }, void 0, (value) => this.module._free(value.ptr)); + } + newHeapBufferPointer(buffer) { + let numBytes = buffer.byteLength, ptr = this.module._malloc(numBytes); + return this.module.HEAPU8.set(buffer, ptr), new Lifetime({ pointer: ptr, numBytes }, void 0, (value) => this.module._free(value.pointer)); + } + consumeHeapCharPointer(ptr) { + let str = this.module.UTF8ToString(ptr); + return this.module._free(ptr), str; + } + }; + UnstableSymbol = Symbol("Unstable"); + DefaultIntrinsics = Object.freeze({ BaseObjects: true, Date: true, Eval: true, StringNormalize: true, RegExp: true, JSON: true, Proxy: true, MapSet: true, TypedArrays: true, Promise: true }); + QuickJSIterator = class extends UsingDisposable { + constructor(handle, context) { + super(); + this.handle = handle; + this.context = context; + this._isDone = false; + this.owner = context.runtime; + } + [Symbol.iterator]() { + return this; + } + next(value) { + if (!this.alive || this._isDone) return { done: true, value: void 0 }; + let nextMethod = this._next ?? (this._next = this.context.getProp(this.handle, "next")); + return this.callIteratorMethod(nextMethod, value); + } + return(value) { + if (!this.alive) return { done: true, value: void 0 }; + let returnMethod = this.context.getProp(this.handle, "return"); + if (returnMethod === this.context.undefined && value === void 0) return this.dispose(), { done: true, value: void 0 }; + let result = this.callIteratorMethod(returnMethod, value); + return returnMethod.dispose(), this.dispose(), result; + } + throw(e) { + if (!this.alive) return { done: true, value: void 0 }; + let errorHandle = e instanceof Lifetime ? e : this.context.newError(e), throwMethod = this.context.getProp(this.handle, "throw"), result = this.callIteratorMethod(throwMethod, e); + return errorHandle.alive && errorHandle.dispose(), throwMethod.dispose(), this.dispose(), result; + } + get alive() { + return this.handle.alive; + } + dispose() { + this._isDone = true, this.handle.dispose(), this._next?.dispose(); + } + callIteratorMethod(method, input) { + let callResult = input ? this.context.callFunction(method, this.handle, input) : this.context.callFunction(method, this.handle); + if (callResult.error) return this.dispose(), { value: callResult }; + let done = this.context.getProp(callResult.value, "done").consume((v) => this.context.dump(v)); + if (done) return callResult.value.dispose(), this.dispose(), { done, value: void 0 }; + let value = this.context.getProp(callResult.value, "value"); + return callResult.value.dispose(), { value: DisposableResult.success(value), done }; + } + }; + ContextMemory = class extends ModuleMemory { + constructor(args) { + super(args.module); + this.scope = new Scope(); + this.copyJSValue = (ptr) => this.ffi.QTS_DupValuePointer(this.ctx.value, ptr); + this.freeJSValue = (ptr) => { + this.ffi.QTS_FreeValuePointer(this.ctx.value, ptr); + }; + args.ownedLifetimes?.forEach((lifetime) => this.scope.manage(lifetime)), this.owner = args.owner, this.module = args.module, this.ffi = args.ffi, this.rt = args.rt, this.ctx = this.scope.manage(args.ctx); + } + get alive() { + return this.scope.alive; + } + dispose() { + return this.scope.dispose(); + } + [Symbol.dispose]() { + return this.dispose(); + } + manage(lifetime) { + return this.scope.manage(lifetime); + } + consumeJSCharPointer(ptr) { + let str = this.module.UTF8ToString(ptr); + return this.ffi.QTS_FreeCString(this.ctx.value, ptr), str; + } + heapValueHandle(ptr) { + return new Lifetime(ptr, this.copyJSValue, this.freeJSValue, this.owner); + } + staticHeapValueHandle(ptr) { + return this.manage(this.heapValueHandle(ptr)), new StaticLifetime(ptr, this.owner); + } + }; + QuickJSContext = class extends UsingDisposable { + constructor(args) { + super(); + this._undefined = void 0; + this._null = void 0; + this._false = void 0; + this._true = void 0; + this._global = void 0; + this._BigInt = void 0; + this._Symbol = void 0; + this._SymbolIterator = void 0; + this._SymbolAsyncIterator = void 0; + this.fnNextId = -32768; + this.fnMaps = /* @__PURE__ */ new Map(); + this.cToHostCallbacks = { callFunction: (ctx, this_ptr, argc, argv, fn_id) => { + if (ctx !== this.ctx.value) throw new Error("QuickJSContext instance received C -> JS call with mismatched ctx"); + let fn = this.getFunction(fn_id); + if (!fn) throw new Error(`QuickJSContext had no callback with id ${fn_id}`); + return Scope.withScopeMaybeAsync(this, function* (awaited, scope) { + let thisHandle = scope.manage(new WeakLifetime(this_ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime)), argHandles = new Array(argc); + for (let i = 0; i < argc; i++) { + let ptr = this.ffi.QTS_ArgvGetJSValueConstPointer(argv, i); + argHandles[i] = scope.manage(new WeakLifetime(ptr, this.memory.copyJSValue, this.memory.freeJSValue, this.runtime)); + } + try { + let result = yield* awaited(fn.apply(thisHandle, argHandles)); + if (result) { + if ("error" in result && result.error) throw this.runtime.debugLog("throw error", result.error), result.error; + let handle = scope.manage(result instanceof Lifetime ? result : result.value); + return this.ffi.QTS_DupValuePointer(this.ctx.value, handle.value); + } + return 0; + } catch (error) { + return this.errorToHandle(error).consume((errorHandle) => this.ffi.QTS_Throw(this.ctx.value, errorHandle.value)); + } + }); + } }; + this.runtime = args.runtime, this.module = args.module, this.ffi = args.ffi, this.rt = args.rt, this.ctx = args.ctx, this.memory = new ContextMemory({ ...args, owner: this.runtime }), args.callbacks.setContextCallbacks(this.ctx.value, this.cToHostCallbacks), this.dump = this.dump.bind(this), this.getString = this.getString.bind(this), this.getNumber = this.getNumber.bind(this), this.resolvePromise = this.resolvePromise.bind(this), this.uint32Out = this.memory.manage(this.memory.newTypedArray(Uint32Array, 1)); + } + get alive() { + return this.memory.alive; + } + dispose() { + this.memory.dispose(); + } + get undefined() { + if (this._undefined) return this._undefined; + let ptr = this.ffi.QTS_GetUndefined(); + return this._undefined = new StaticLifetime(ptr); + } + get null() { + if (this._null) return this._null; + let ptr = this.ffi.QTS_GetNull(); + return this._null = new StaticLifetime(ptr); + } + get true() { + if (this._true) return this._true; + let ptr = this.ffi.QTS_GetTrue(); + return this._true = new StaticLifetime(ptr); + } + get false() { + if (this._false) return this._false; + let ptr = this.ffi.QTS_GetFalse(); + return this._false = new StaticLifetime(ptr); + } + get global() { + if (this._global) return this._global; + let ptr = this.ffi.QTS_GetGlobalObject(this.ctx.value); + return this._global = this.memory.staticHeapValueHandle(ptr), this._global; + } + newNumber(num) { + return this.memory.heapValueHandle(this.ffi.QTS_NewFloat64(this.ctx.value, num)); + } + newString(str) { + let ptr = this.memory.newHeapCharPointer(str).consume((charHandle) => this.ffi.QTS_NewString(this.ctx.value, charHandle.value.ptr)); + return this.memory.heapValueHandle(ptr); + } + newUniqueSymbol(description) { + let key = (typeof description == "symbol" ? description.description : description) ?? "", ptr = this.memory.newHeapCharPointer(key).consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value.ptr, 0)); + return this.memory.heapValueHandle(ptr); + } + newSymbolFor(key) { + let description = (typeof key == "symbol" ? key.description : key) ?? "", ptr = this.memory.newHeapCharPointer(description).consume((charHandle) => this.ffi.QTS_NewSymbol(this.ctx.value, charHandle.value.ptr, 1)); + return this.memory.heapValueHandle(ptr); + } + getWellKnownSymbol(name) { + return this._Symbol ?? (this._Symbol = this.memory.manage(this.getProp(this.global, "Symbol"))), this.getProp(this._Symbol, name); + } + newBigInt(num) { + if (!this._BigInt) { + let bigIntHandle2 = this.getProp(this.global, "BigInt"); + this.memory.manage(bigIntHandle2), this._BigInt = new StaticLifetime(bigIntHandle2.value, this.runtime); + } + let bigIntHandle = this._BigInt, asString = String(num); + return this.newString(asString).consume((handle) => this.unwrapResult(this.callFunction(bigIntHandle, this.undefined, handle))); + } + newObject(prototype) { + prototype && this.runtime.assertOwned(prototype); + let ptr = prototype ? this.ffi.QTS_NewObjectProto(this.ctx.value, prototype.value) : this.ffi.QTS_NewObject(this.ctx.value); + return this.memory.heapValueHandle(ptr); + } + newArray() { + let ptr = this.ffi.QTS_NewArray(this.ctx.value); + return this.memory.heapValueHandle(ptr); + } + newArrayBuffer(buffer) { + let array = new Uint8Array(buffer), handle = this.memory.newHeapBufferPointer(array), ptr = this.ffi.QTS_NewArrayBuffer(this.ctx.value, handle.value.pointer, array.length); + return this.memory.heapValueHandle(ptr); + } + newPromise(value) { + let deferredPromise = Scope.withScope((scope) => { + let mutablePointerArray = scope.manage(this.memory.newMutablePointerArray(2)), promisePtr = this.ffi.QTS_NewPromiseCapability(this.ctx.value, mutablePointerArray.value.ptr), promiseHandle = this.memory.heapValueHandle(promisePtr), [resolveHandle, rejectHandle] = Array.from(mutablePointerArray.value.typedArray).map((jsvaluePtr) => this.memory.heapValueHandle(jsvaluePtr)); + return new QuickJSDeferredPromise({ context: this, promiseHandle, resolveHandle, rejectHandle }); + }); + return value && typeof value == "function" && (value = new Promise(value)), value && Promise.resolve(value).then(deferredPromise.resolve, (error) => error instanceof Lifetime ? deferredPromise.reject(error) : this.newError(error).consume(deferredPromise.reject)), deferredPromise; + } + newFunction(name, fn) { + let fnId = ++this.fnNextId; + return this.setFunction(fnId, fn), this.memory.heapValueHandle(this.ffi.QTS_NewFunction(this.ctx.value, fnId, name)); + } + newError(error) { + let errorHandle = this.memory.heapValueHandle(this.ffi.QTS_NewError(this.ctx.value)); + return error && typeof error == "object" ? (error.name !== void 0 && this.newString(error.name).consume((handle) => this.setProp(errorHandle, "name", handle)), error.message !== void 0 && this.newString(error.message).consume((handle) => this.setProp(errorHandle, "message", handle))) : typeof error == "string" ? this.newString(error).consume((handle) => this.setProp(errorHandle, "message", handle)) : error !== void 0 && this.newString(String(error)).consume((handle) => this.setProp(errorHandle, "message", handle)), errorHandle; + } + typeof(handle) { + return this.runtime.assertOwned(handle), this.memory.consumeHeapCharPointer(this.ffi.QTS_Typeof(this.ctx.value, handle.value)); + } + getNumber(handle) { + return this.runtime.assertOwned(handle), this.ffi.QTS_GetFloat64(this.ctx.value, handle.value); + } + getString(handle) { + return this.runtime.assertOwned(handle), this.memory.consumeJSCharPointer(this.ffi.QTS_GetString(this.ctx.value, handle.value)); + } + getSymbol(handle) { + this.runtime.assertOwned(handle); + let key = this.memory.consumeJSCharPointer(this.ffi.QTS_GetSymbolDescriptionOrKey(this.ctx.value, handle.value)); + return this.ffi.QTS_IsGlobalSymbol(this.ctx.value, handle.value) ? Symbol.for(key) : Symbol(key); + } + getBigInt(handle) { + this.runtime.assertOwned(handle); + let asString = this.getString(handle); + return BigInt(asString); + } + getArrayBuffer(handle) { + this.runtime.assertOwned(handle); + let len = this.ffi.QTS_GetArrayBufferLength(this.ctx.value, handle.value), ptr = this.ffi.QTS_GetArrayBuffer(this.ctx.value, handle.value); + if (!ptr) throw new Error("Couldn't allocate memory to get ArrayBuffer"); + return new Lifetime(this.module.HEAPU8.subarray(ptr, ptr + len), void 0, () => this.module._free(ptr)); + } + getPromiseState(handle) { + this.runtime.assertOwned(handle); + let state = this.ffi.QTS_PromiseState(this.ctx.value, handle.value); + if (state < 0) return { type: "fulfilled", value: handle, notAPromise: true }; + if (state === JSPromiseStateEnum.Pending) return { type: "pending", get error() { + return new QuickJSPromisePending("Cannot unwrap a pending promise"); + } }; + let ptr = this.ffi.QTS_PromiseResult(this.ctx.value, handle.value), result = this.memory.heapValueHandle(ptr); + if (state === JSPromiseStateEnum.Fulfilled) return { type: "fulfilled", value: result }; + if (state === JSPromiseStateEnum.Rejected) return { type: "rejected", error: result }; + throw result.dispose(), new Error(`Unknown JSPromiseStateEnum: ${state}`); + } + resolvePromise(promiseLikeHandle) { + this.runtime.assertOwned(promiseLikeHandle); + let vmResolveResult = Scope.withScope((scope) => { + let vmPromise = scope.manage(this.getProp(this.global, "Promise")), vmPromiseResolve = scope.manage(this.getProp(vmPromise, "resolve")); + return this.callFunction(vmPromiseResolve, vmPromise, promiseLikeHandle); + }); + return vmResolveResult.error ? Promise.resolve(vmResolveResult) : new Promise((resolve) => { + Scope.withScope((scope) => { + let resolveHandle = scope.manage(this.newFunction("resolve", (value) => { + resolve(this.success(value && value.dup())); + })), rejectHandle = scope.manage(this.newFunction("reject", (error) => { + resolve(this.fail(error && error.dup())); + })), promiseHandle = scope.manage(vmResolveResult.value), promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then")); + this.callFunction(promiseThenHandle, promiseHandle, resolveHandle, rejectHandle).unwrap().dispose(); + }); + }); + } + isEqual(a, b, equalityType = IsEqualOp.IsStrictlyEqual) { + if (a === b) return true; + this.runtime.assertOwned(a), this.runtime.assertOwned(b); + let result = this.ffi.QTS_IsEqual(this.ctx.value, a.value, b.value, equalityType); + if (result === -1) throw new QuickJSNotImplemented("WASM variant does not expose equality"); + return !!result; + } + eq(handle, other) { + return this.isEqual(handle, other, IsEqualOp.IsStrictlyEqual); + } + sameValue(handle, other) { + return this.isEqual(handle, other, IsEqualOp.IsSameValue); + } + sameValueZero(handle, other) { + return this.isEqual(handle, other, IsEqualOp.IsSameValueZero); + } + getProp(handle, key) { + this.runtime.assertOwned(handle); + let ptr; + return typeof key == "number" && key >= 0 ? ptr = this.ffi.QTS_GetPropNumber(this.ctx.value, handle.value, key) : ptr = this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_GetProp(this.ctx.value, handle.value, quickJSKey.value)), this.memory.heapValueHandle(ptr); + } + getLength(handle) { + if (this.runtime.assertOwned(handle), !(this.ffi.QTS_GetLength(this.ctx.value, this.uint32Out.value.ptr, handle.value) < 0)) return this.uint32Out.value.typedArray[0]; + } + getOwnPropertyNames(handle, options = { strings: true, numbersAsStrings: true }) { + this.runtime.assertOwned(handle), handle.value; + let flags = getOwnPropertyNamesOptionsToFlags(options); + if (flags === 0) throw new QuickJSEmptyGetOwnPropertyNames("No options set, will return an empty array"); + return Scope.withScope((scope) => { + let outPtr = scope.manage(this.memory.newMutablePointerArray(1)), errorPtr = this.ffi.QTS_GetOwnPropertyNames(this.ctx.value, outPtr.value.ptr, this.uint32Out.value.ptr, handle.value, flags); + if (errorPtr) return this.fail(this.memory.heapValueHandle(errorPtr)); + let len = this.uint32Out.value.typedArray[0], ptr = outPtr.value.typedArray[0], pointerArray = new Uint32Array(this.module.HEAP8.buffer, ptr, len), handles = Array.from(pointerArray).map((ptr2) => this.memory.heapValueHandle(ptr2)); + return this.ffi.QTS_FreeVoidPointer(this.ctx.value, ptr), this.success(createDisposableArray(handles)); + }); + } + getIterator(iterableHandle) { + let SymbolIterator = this._SymbolIterator ?? (this._SymbolIterator = this.memory.manage(this.getWellKnownSymbol("iterator"))); + return Scope.withScope((scope) => { + let methodHandle = scope.manage(this.getProp(iterableHandle, SymbolIterator)), iteratorCallResult = this.callFunction(methodHandle, iterableHandle); + return iteratorCallResult.error ? iteratorCallResult : this.success(new QuickJSIterator(iteratorCallResult.value, this)); + }); + } + setProp(handle, key, value) { + this.runtime.assertOwned(handle), this.borrowPropertyKey(key).consume((quickJSKey) => this.ffi.QTS_SetProp(this.ctx.value, handle.value, quickJSKey.value, value.value)); + } + defineProp(handle, key, descriptor) { + this.runtime.assertOwned(handle), Scope.withScope((scope) => { + let quickJSKey = scope.manage(this.borrowPropertyKey(key)), value = descriptor.value || this.undefined, configurable = !!descriptor.configurable, enumerable = !!descriptor.enumerable, hasValue = !!descriptor.value, get = descriptor.get ? scope.manage(this.newFunction(descriptor.get.name, descriptor.get)) : this.undefined, set = descriptor.set ? scope.manage(this.newFunction(descriptor.set.name, descriptor.set)) : this.undefined; + this.ffi.QTS_DefineProp(this.ctx.value, handle.value, quickJSKey.value, value.value, get.value, set.value, configurable, enumerable, hasValue); + }); + } + callFunction(func, thisVal, ...restArgs) { + this.runtime.assertOwned(func); + let args, firstArg = restArgs[0]; + firstArg === void 0 || Array.isArray(firstArg) ? args = firstArg ?? [] : args = restArgs; + let resultPtr = this.memory.toPointerArray(args).consume((argsArrayPtr) => this.ffi.QTS_Call(this.ctx.value, func.value, thisVal.value, args.length, argsArrayPtr.value)), errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr); + return errorPtr ? (this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr), this.fail(this.memory.heapValueHandle(errorPtr))) : this.success(this.memory.heapValueHandle(resultPtr)); + } + callMethod(thisHandle, key, args = []) { + return this.getProp(thisHandle, key).consume((func) => this.callFunction(func, thisHandle, args)); + } + evalCode(code, filename = "eval.js", options) { + let detectModule = options === void 0 ? 1 : 0, flags = evalOptionsToFlags(options), resultPtr = this.memory.newHeapCharPointer(code).consume((charHandle) => this.ffi.QTS_Eval(this.ctx.value, charHandle.value.ptr, charHandle.value.strlen, filename, detectModule, flags)), errorPtr = this.ffi.QTS_ResolveException(this.ctx.value, resultPtr); + return errorPtr ? (this.ffi.QTS_FreeValuePointer(this.ctx.value, resultPtr), this.fail(this.memory.heapValueHandle(errorPtr))) : this.success(this.memory.heapValueHandle(resultPtr)); + } + throw(error) { + return this.errorToHandle(error).consume((handle) => this.ffi.QTS_Throw(this.ctx.value, handle.value)); + } + borrowPropertyKey(key) { + return typeof key == "number" ? this.newNumber(key) : typeof key == "string" ? this.newString(key) : new StaticLifetime(key.value, this.runtime); + } + getMemory(rt) { + if (rt === this.rt.value) return this.memory; + throw new Error("Private API. Cannot get memory from a different runtime"); + } + dump(handle) { + this.runtime.assertOwned(handle); + let type = this.typeof(handle); + if (type === "string") return this.getString(handle); + if (type === "number") return this.getNumber(handle); + if (type === "bigint") return this.getBigInt(handle); + if (type === "undefined") return; + if (type === "symbol") return this.getSymbol(handle); + let asPromiseState = this.getPromiseState(handle); + if (asPromiseState.type === "fulfilled" && !asPromiseState.notAPromise) return handle.dispose(), { type: asPromiseState.type, value: asPromiseState.value.consume(this.dump) }; + if (asPromiseState.type === "pending") return handle.dispose(), { type: asPromiseState.type }; + if (asPromiseState.type === "rejected") return handle.dispose(), { type: asPromiseState.type, error: asPromiseState.error.consume(this.dump) }; + let str = this.memory.consumeJSCharPointer(this.ffi.QTS_Dump(this.ctx.value, handle.value)); + try { + return JSON.parse(str); + } catch { + return str; + } + } + unwrapResult(result) { + if (result.error) { + let context = "context" in result.error ? result.error.context : this, cause = result.error.consume((error) => this.dump(error)); + if (cause && typeof cause == "object" && typeof cause.message == "string") { + let { message, name, stack, ...rest } = cause, exception = new QuickJSUnwrapError(cause, context); + typeof name == "string" && (exception.name = cause.name), exception.message = message; + let hostStack = exception.stack; + throw typeof stack == "string" && (exception.stack = `${name}: ${message} +${cause.stack}Host: ${hostStack}`), Object.assign(exception, rest), exception; + } + throw new QuickJSUnwrapError(cause); + } + return result.value; + } + [Symbol.for("nodejs.util.inspect.custom")]() { + return this.alive ? `${this.constructor.name} { ctx: ${this.ctx.value} rt: ${this.rt.value} }` : `${this.constructor.name} { disposed }`; + } + getFunction(fn_id) { + let map_id = fn_id >> 8, fnMap = this.fnMaps.get(map_id); + if (fnMap) return fnMap.get(fn_id); + } + setFunction(fn_id, handle) { + let map_id = fn_id >> 8, fnMap = this.fnMaps.get(map_id); + return fnMap || (fnMap = /* @__PURE__ */ new Map(), this.fnMaps.set(map_id, fnMap)), fnMap.set(fn_id, handle); + } + errorToHandle(error) { + return error instanceof Lifetime ? error : this.newError(error); + } + encodeBinaryJSON(handle) { + let ptr = this.ffi.QTS_bjson_encode(this.ctx.value, handle.value); + return this.memory.heapValueHandle(ptr); + } + decodeBinaryJSON(handle) { + let ptr = this.ffi.QTS_bjson_decode(this.ctx.value, handle.value); + return this.memory.heapValueHandle(ptr); + } + success(value) { + return DisposableResult.success(value); + } + fail(error) { + return DisposableResult.fail(error, (error2) => this.unwrapResult(error2)); + } + }; + QuickJSRuntime = class extends UsingDisposable { + constructor(args) { + super(); + this.scope = new Scope(); + this.contextMap = /* @__PURE__ */ new Map(); + this._debugMode = false; + this.cToHostCallbacks = { shouldInterrupt: (rt) => { + if (rt !== this.rt.value) throw new Error("QuickJSContext instance received C -> JS interrupt with mismatched rt"); + let fn = this.interruptHandler; + if (!fn) throw new Error("QuickJSContext had no interrupt handler"); + return fn(this) ? 1 : 0; + }, loadModuleSource: maybeAsyncFn(this, function* (awaited, rt, ctx, moduleName) { + let moduleLoader = this.moduleLoader; + if (!moduleLoader) throw new Error("Runtime has no module loader"); + if (rt !== this.rt.value) throw new Error("Runtime pointer mismatch"); + let context = this.contextMap.get(ctx) ?? this.newContext({ contextPointer: ctx }); + try { + let result = yield* awaited(moduleLoader(moduleName, context)); + if (typeof result == "object" && "error" in result && result.error) throw this.debugLog("cToHostLoadModule: loader returned error", result.error), result.error; + let moduleSource = typeof result == "string" ? result : "value" in result ? result.value : result; + return this.memory.newHeapCharPointer(moduleSource).value.ptr; + } catch (error) { + return this.debugLog("cToHostLoadModule: caught error", error), context.throw(error), 0; + } + }), normalizeModule: maybeAsyncFn(this, function* (awaited, rt, ctx, baseModuleName, moduleNameRequest) { + let moduleNormalizer = this.moduleNormalizer; + if (!moduleNormalizer) throw new Error("Runtime has no module normalizer"); + if (rt !== this.rt.value) throw new Error("Runtime pointer mismatch"); + let context = this.contextMap.get(ctx) ?? this.newContext({ contextPointer: ctx }); + try { + let result = yield* awaited(moduleNormalizer(baseModuleName, moduleNameRequest, context)); + if (typeof result == "object" && "error" in result && result.error) throw this.debugLog("cToHostNormalizeModule: normalizer returned error", result.error), result.error; + let name = typeof result == "string" ? result : result.value; + return context.getMemory(this.rt.value).newHeapCharPointer(name).value.ptr; + } catch (error) { + return this.debugLog("normalizeModule: caught error", error), context.throw(error), 0; + } + }) }; + args.ownedLifetimes?.forEach((lifetime) => this.scope.manage(lifetime)), this.module = args.module, this.memory = new ModuleMemory(this.module), this.ffi = args.ffi, this.rt = args.rt, this.callbacks = args.callbacks, this.scope.manage(this.rt), this.callbacks.setRuntimeCallbacks(this.rt.value, this.cToHostCallbacks), this.executePendingJobs = this.executePendingJobs.bind(this), QTS_DEBUG && this.setDebugMode(true); + } + get alive() { + return this.scope.alive; + } + dispose() { + return this.scope.dispose(); + } + newContext(options = {}) { + let intrinsics = intrinsicsToFlags(options.intrinsics), ctx = new Lifetime(options.contextPointer || this.ffi.QTS_NewContext(this.rt.value, intrinsics), void 0, (ctx_ptr) => { + this.contextMap.delete(ctx_ptr), this.callbacks.deleteContext(ctx_ptr), this.ffi.QTS_FreeContext(ctx_ptr); + }), context = new QuickJSContext({ module: this.module, ctx, ffi: this.ffi, rt: this.rt, ownedLifetimes: options.ownedLifetimes, runtime: this, callbacks: this.callbacks }); + return this.contextMap.set(ctx.value, context), context; + } + setModuleLoader(moduleLoader, moduleNormalizer) { + this.moduleLoader = moduleLoader, this.moduleNormalizer = moduleNormalizer, this.ffi.QTS_RuntimeEnableModuleLoader(this.rt.value, this.moduleNormalizer ? 1 : 0); + } + removeModuleLoader() { + this.moduleLoader = void 0, this.ffi.QTS_RuntimeDisableModuleLoader(this.rt.value); + } + hasPendingJob() { + return !!this.ffi.QTS_IsJobPending(this.rt.value); + } + setInterruptHandler(cb) { + let prevInterruptHandler = this.interruptHandler; + this.interruptHandler = cb, prevInterruptHandler || this.ffi.QTS_RuntimeEnableInterruptHandler(this.rt.value); + } + removeInterruptHandler() { + this.interruptHandler && (this.ffi.QTS_RuntimeDisableInterruptHandler(this.rt.value), this.interruptHandler = void 0); + } + executePendingJobs(maxJobsToExecute = -1) { + let ctxPtrOut = this.memory.newMutablePointerArray(1), valuePtr = this.ffi.QTS_ExecutePendingJob(this.rt.value, maxJobsToExecute ?? -1, ctxPtrOut.value.ptr), ctxPtr = ctxPtrOut.value.typedArray[0]; + if (ctxPtrOut.dispose(), ctxPtr === 0) return this.ffi.QTS_FreeValuePointerRuntime(this.rt.value, valuePtr), DisposableResult.success(0); + let context = this.contextMap.get(ctxPtr) ?? this.newContext({ contextPointer: ctxPtr }), resultValue = context.getMemory(this.rt.value).heapValueHandle(valuePtr); + if (context.typeof(resultValue) === "number") { + let executedJobs = context.getNumber(resultValue); + return resultValue.dispose(), DisposableResult.success(executedJobs); + } else { + let error = Object.assign(resultValue, { context }); + return DisposableResult.fail(error, (error2) => context.unwrapResult(error2)); + } + } + setMemoryLimit(limitBytes) { + if (limitBytes < 0 && limitBytes !== -1) throw new Error("Cannot set memory limit to negative number. To unset, pass -1"); + this.ffi.QTS_RuntimeSetMemoryLimit(this.rt.value, limitBytes); + } + computeMemoryUsage() { + let serviceContextMemory = this.getSystemContext().getMemory(this.rt.value); + return serviceContextMemory.heapValueHandle(this.ffi.QTS_RuntimeComputeMemoryUsage(this.rt.value, serviceContextMemory.ctx.value)); + } + dumpMemoryUsage() { + return this.memory.consumeHeapCharPointer(this.ffi.QTS_RuntimeDumpMemoryUsage(this.rt.value)); + } + setMaxStackSize(stackSize) { + if (stackSize < 0) throw new Error("Cannot set memory limit to negative number. To unset, pass 0."); + this.ffi.QTS_RuntimeSetMaxStackSize(this.rt.value, stackSize); + } + assertOwned(handle) { + if (handle.owner && handle.owner.rt !== this.rt) throw new QuickJSWrongOwner(`Handle is not owned by this runtime: ${handle.owner.rt.value} != ${this.rt.value}`); + } + setDebugMode(enabled) { + this._debugMode = enabled, this.ffi.DEBUG && this.rt.alive && this.ffi.QTS_SetDebugLogEnabled(this.rt.value, enabled ? 1 : 0); + } + isDebugMode() { + return this._debugMode; + } + debugLog(...msg) { + this._debugMode && console.log("quickjs-emscripten:", ...msg); + } + [Symbol.for("nodejs.util.inspect.custom")]() { + return this.alive ? `${this.constructor.name} { rt: ${this.rt.value} }` : `${this.constructor.name} { disposed }`; + } + getSystemContext() { + return this.context || (this.context = this.scope.manage(this.newContext())), this.context; + } + }; + QuickJSEmscriptenModuleCallbacks = class { + constructor(args) { + this.callFunction = args.callFunction, this.shouldInterrupt = args.shouldInterrupt, this.loadModuleSource = args.loadModuleSource, this.normalizeModule = args.normalizeModule; + } + }; + QuickJSModuleCallbacks = class { + constructor(module) { + this.contextCallbacks = /* @__PURE__ */ new Map(); + this.runtimeCallbacks = /* @__PURE__ */ new Map(); + this.suspendedCount = 0; + this.cToHostCallbacks = new QuickJSEmscriptenModuleCallbacks({ callFunction: (asyncify, ctx, this_ptr, argc, argv, fn_id) => this.handleAsyncify(asyncify, () => { + try { + let vm = this.contextCallbacks.get(ctx); + if (!vm) throw new Error(`QuickJSContext(ctx = ${ctx}) not found for C function call "${fn_id}"`); + return vm.callFunction(ctx, this_ptr, argc, argv, fn_id); + } catch (error) { + return console.error("[C to host error: returning null]", error), 0; + } + }), shouldInterrupt: (asyncify, rt) => this.handleAsyncify(asyncify, () => { + try { + let vm = this.runtimeCallbacks.get(rt); + if (!vm) throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C interrupt`); + return vm.shouldInterrupt(rt); + } catch (error) { + return console.error("[C to host interrupt: returning error]", error), 1; + } + }), loadModuleSource: (asyncify, rt, ctx, moduleName) => this.handleAsyncify(asyncify, () => { + try { + let runtimeCallbacks = this.runtimeCallbacks.get(rt); + if (!runtimeCallbacks) throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C module loader`); + let loadModule = runtimeCallbacks.loadModuleSource; + if (!loadModule) throw new Error(`QuickJSRuntime(rt = ${rt}) does not support module loading`); + return loadModule(rt, ctx, moduleName); + } catch (error) { + return console.error("[C to host module loader error: returning null]", error), 0; + } + }), normalizeModule: (asyncify, rt, ctx, moduleBaseName, moduleName) => this.handleAsyncify(asyncify, () => { + try { + let runtimeCallbacks = this.runtimeCallbacks.get(rt); + if (!runtimeCallbacks) throw new Error(`QuickJSRuntime(rt = ${rt}) not found for C module loader`); + let normalizeModule = runtimeCallbacks.normalizeModule; + if (!normalizeModule) throw new Error(`QuickJSRuntime(rt = ${rt}) does not support module loading`); + return normalizeModule(rt, ctx, moduleBaseName, moduleName); + } catch (error) { + return console.error("[C to host module loader error: returning null]", error), 0; + } + }) }); + this.module = module, this.module.callbacks = this.cToHostCallbacks; + } + setRuntimeCallbacks(rt, callbacks) { + this.runtimeCallbacks.set(rt, callbacks); + } + deleteRuntime(rt) { + this.runtimeCallbacks.delete(rt); + } + setContextCallbacks(ctx, callbacks) { + this.contextCallbacks.set(ctx, callbacks); + } + deleteContext(ctx) { + this.contextCallbacks.delete(ctx); + } + handleAsyncify(asyncify, fn) { + if (asyncify) return asyncify.handleSleep((done) => { + try { + let result = fn(); + if (!(result instanceof Promise)) { + debugLog("asyncify.handleSleep: not suspending:", result), done(result); + return; + } + if (this.suspended) throw new QuickJSAsyncifyError(`Already suspended at: ${this.suspended.stack} +Attempted to suspend at:`); + this.suspended = new QuickJSAsyncifySuspended(`(${this.suspendedCount++})`), debugLog("asyncify.handleSleep: suspending:", this.suspended), result.then((resolvedResult) => { + this.suspended = void 0, debugLog("asyncify.handleSleep: resolved:", resolvedResult), done(resolvedResult); + }, (error) => { + debugLog("asyncify.handleSleep: rejected:", error), console.error("QuickJS: cannot handle error in suspended function", error), this.suspended = void 0; + }); + } catch (error) { + throw debugLog("asyncify.handleSleep: error:", error), this.suspended = void 0, error; + } + }); + let value = fn(); + if (value instanceof Promise) throw new Error("Promise return value not supported in non-asyncify context."); + return value; + } + }; + QuickJSWASMModule = class { + constructor(module, ffi) { + this.module = module, this.ffi = ffi, this.callbacks = new QuickJSModuleCallbacks(module); + } + newRuntime(options = {}) { + let rt = new Lifetime(this.ffi.QTS_NewRuntime(), void 0, (rt_ptr) => { + this.callbacks.deleteRuntime(rt_ptr), this.ffi.QTS_FreeRuntime(rt_ptr); + }), runtime = new QuickJSRuntime({ module: this.module, callbacks: this.callbacks, ffi: this.ffi, rt }); + return applyBaseRuntimeOptions(runtime, options), options.moduleLoader && runtime.setModuleLoader(options.moduleLoader), runtime; + } + newContext(options = {}) { + let runtime = this.newRuntime(), context = runtime.newContext({ ...options, ownedLifetimes: concat(runtime, options.ownedLifetimes) }); + return runtime.context = context, context; + } + evalCode(code, options = {}) { + return Scope.withScope((scope) => { + let vm = scope.manage(this.newContext()); + applyModuleEvalRuntimeOptions(vm.runtime, options); + let result = vm.evalCode(code, "eval.js"); + if (options.memoryLimitBytes !== void 0 && vm.runtime.setMemoryLimit(-1), result.error) throw vm.dump(scope.manage(result.error)); + return vm.dump(scope.manage(result.value)); + }); + } + getWasmMemory() { + let memory = this.module.quickjsEmscriptenInit?.(() => { + })?.getWasmMemory?.(); + if (!memory) throw new Error("Variant does not support getting WebAssembly.Memory"); + return memory; + } + getFFI() { + return this.ffi; + } + }; + } +}); + +// registry/components/code/node_modules/quickjs-emscripten-core/dist/module-6F3E5H7Y.mjs +var module_6F3E5H7Y_exports = {}; +__export(module_6F3E5H7Y_exports, { + QuickJSModuleCallbacks: () => QuickJSModuleCallbacks, + QuickJSWASMModule: () => QuickJSWASMModule, + applyBaseRuntimeOptions: () => applyBaseRuntimeOptions, + applyModuleEvalRuntimeOptions: () => applyModuleEvalRuntimeOptions +}); +var init_module_6F3E5H7Y = __esm({ + "registry/components/code/node_modules/quickjs-emscripten-core/dist/module-6F3E5H7Y.mjs"() { + init_chunk_JTKJZQYV(); + } +}); + +// registry/components/code/node_modules/@jitl/quickjs-wasmfile-release-sync/dist/ffi.mjs +var ffi_exports = {}; +__export(ffi_exports, { + QuickJSFFI: () => QuickJSFFI +}); +var QuickJSFFI; +var init_ffi = __esm({ + "registry/components/code/node_modules/@jitl/quickjs-wasmfile-release-sync/dist/ffi.mjs"() { + QuickJSFFI = class { + constructor(module) { + this.module = module; + this.DEBUG = false; + this.QTS_Throw = this.module.cwrap("QTS_Throw", "number", ["number", "number"]); + this.QTS_NewError = this.module.cwrap("QTS_NewError", "number", ["number"]); + this.QTS_RuntimeSetMemoryLimit = this.module.cwrap("QTS_RuntimeSetMemoryLimit", null, ["number", "number"]); + this.QTS_RuntimeComputeMemoryUsage = this.module.cwrap("QTS_RuntimeComputeMemoryUsage", "number", ["number", "number"]); + this.QTS_RuntimeDumpMemoryUsage = this.module.cwrap("QTS_RuntimeDumpMemoryUsage", "number", ["number"]); + this.QTS_RecoverableLeakCheck = this.module.cwrap("QTS_RecoverableLeakCheck", "number", []); + this.QTS_BuildIsSanitizeLeak = this.module.cwrap("QTS_BuildIsSanitizeLeak", "number", []); + this.QTS_RuntimeSetMaxStackSize = this.module.cwrap("QTS_RuntimeSetMaxStackSize", null, ["number", "number"]); + this.QTS_GetUndefined = this.module.cwrap("QTS_GetUndefined", "number", []); + this.QTS_GetNull = this.module.cwrap("QTS_GetNull", "number", []); + this.QTS_GetFalse = this.module.cwrap("QTS_GetFalse", "number", []); + this.QTS_GetTrue = this.module.cwrap("QTS_GetTrue", "number", []); + this.QTS_NewHostRef = this.module.cwrap("QTS_NewHostRef", "number", ["number", "number"]); + this.QTS_GetHostRefId = this.module.cwrap("QTS_GetHostRefId", "number", ["number"]); + this.QTS_NewRuntime = this.module.cwrap("QTS_NewRuntime", "number", []); + this.QTS_FreeRuntime = this.module.cwrap("QTS_FreeRuntime", null, ["number"]); + this.QTS_NewContext = this.module.cwrap("QTS_NewContext", "number", ["number", "number"]); + this.QTS_FreeContext = this.module.cwrap("QTS_FreeContext", null, ["number"]); + this.QTS_FreeValuePointer = this.module.cwrap("QTS_FreeValuePointer", null, ["number", "number"]); + this.QTS_FreeValuePointerRuntime = this.module.cwrap("QTS_FreeValuePointerRuntime", null, ["number", "number"]); + this.QTS_FreeVoidPointer = this.module.cwrap("QTS_FreeVoidPointer", null, ["number", "number"]); + this.QTS_FreeCString = this.module.cwrap("QTS_FreeCString", null, ["number", "number"]); + this.QTS_DupValuePointer = this.module.cwrap("QTS_DupValuePointer", "number", ["number", "number"]); + this.QTS_NewObject = this.module.cwrap("QTS_NewObject", "number", ["number"]); + this.QTS_NewObjectProto = this.module.cwrap("QTS_NewObjectProto", "number", ["number", "number"]); + this.QTS_NewArray = this.module.cwrap("QTS_NewArray", "number", ["number"]); + this.QTS_NewArrayBuffer = this.module.cwrap("QTS_NewArrayBuffer", "number", ["number", "number", "number"]); + this.QTS_NewFloat64 = this.module.cwrap("QTS_NewFloat64", "number", ["number", "number"]); + this.QTS_GetFloat64 = this.module.cwrap("QTS_GetFloat64", "number", ["number", "number"]); + this.QTS_NewString = this.module.cwrap("QTS_NewString", "number", ["number", "number"]); + this.QTS_GetString = this.module.cwrap("QTS_GetString", "number", ["number", "number"]); + this.QTS_GetArrayBuffer = this.module.cwrap("QTS_GetArrayBuffer", "number", ["number", "number"]); + this.QTS_GetArrayBufferLength = this.module.cwrap("QTS_GetArrayBufferLength", "number", ["number", "number"]); + this.QTS_NewSymbol = this.module.cwrap("QTS_NewSymbol", "number", ["number", "number", "number"]); + this.QTS_GetSymbolDescriptionOrKey = this.module.cwrap("QTS_GetSymbolDescriptionOrKey", "number", ["number", "number"]); + this.QTS_IsGlobalSymbol = this.module.cwrap("QTS_IsGlobalSymbol", "number", ["number", "number"]); + this.QTS_IsJobPending = this.module.cwrap("QTS_IsJobPending", "number", ["number"]); + this.QTS_ExecutePendingJob = this.module.cwrap("QTS_ExecutePendingJob", "number", ["number", "number", "number"]); + this.QTS_GetProp = this.module.cwrap("QTS_GetProp", "number", ["number", "number", "number"]); + this.QTS_GetPropNumber = this.module.cwrap("QTS_GetPropNumber", "number", ["number", "number", "number"]); + this.QTS_SetProp = this.module.cwrap("QTS_SetProp", null, ["number", "number", "number", "number"]); + this.QTS_DefineProp = this.module.cwrap("QTS_DefineProp", null, ["number", "number", "number", "number", "number", "number", "boolean", "boolean", "boolean"]); + this.QTS_GetOwnPropertyNames = this.module.cwrap("QTS_GetOwnPropertyNames", "number", ["number", "number", "number", "number", "number"]); + this.QTS_Call = this.module.cwrap("QTS_Call", "number", ["number", "number", "number", "number", "number"]); + this.QTS_ResolveException = this.module.cwrap("QTS_ResolveException", "number", ["number", "number"]); + this.QTS_Dump = this.module.cwrap("QTS_Dump", "number", ["number", "number"]); + this.QTS_Eval = this.module.cwrap("QTS_Eval", "number", ["number", "number", "number", "string", "number", "number"]); + this.QTS_GetModuleNamespace = this.module.cwrap("QTS_GetModuleNamespace", "number", ["number", "number"]); + this.QTS_Typeof = this.module.cwrap("QTS_Typeof", "number", ["number", "number"]); + this.QTS_GetLength = this.module.cwrap("QTS_GetLength", "number", ["number", "number", "number"]); + this.QTS_IsEqual = this.module.cwrap("QTS_IsEqual", "number", ["number", "number", "number", "number"]); + this.QTS_GetGlobalObject = this.module.cwrap("QTS_GetGlobalObject", "number", ["number"]); + this.QTS_NewPromiseCapability = this.module.cwrap("QTS_NewPromiseCapability", "number", ["number", "number"]); + this.QTS_PromiseState = this.module.cwrap("QTS_PromiseState", "number", ["number", "number"]); + this.QTS_PromiseResult = this.module.cwrap("QTS_PromiseResult", "number", ["number", "number"]); + this.QTS_TestStringArg = this.module.cwrap("QTS_TestStringArg", null, ["string"]); + this.QTS_GetDebugLogEnabled = this.module.cwrap("QTS_GetDebugLogEnabled", "number", ["number"]); + this.QTS_SetDebugLogEnabled = this.module.cwrap("QTS_SetDebugLogEnabled", null, ["number", "number"]); + this.QTS_BuildIsDebug = this.module.cwrap("QTS_BuildIsDebug", "number", []); + this.QTS_BuildIsAsyncify = this.module.cwrap("QTS_BuildIsAsyncify", "number", []); + this.QTS_NewFunction = this.module.cwrap("QTS_NewFunction", "number", ["number", "string", "number", "boolean", "number"]); + this.QTS_ArgvGetJSValueConstPointer = this.module.cwrap("QTS_ArgvGetJSValueConstPointer", "number", ["number", "number"]); + this.QTS_RuntimeEnableInterruptHandler = this.module.cwrap("QTS_RuntimeEnableInterruptHandler", null, ["number"]); + this.QTS_RuntimeDisableInterruptHandler = this.module.cwrap("QTS_RuntimeDisableInterruptHandler", null, ["number"]); + this.QTS_RuntimeEnableModuleLoader = this.module.cwrap("QTS_RuntimeEnableModuleLoader", null, ["number", "number"]); + this.QTS_RuntimeDisableModuleLoader = this.module.cwrap("QTS_RuntimeDisableModuleLoader", null, ["number"]); + this.QTS_bjson_encode = this.module.cwrap("QTS_bjson_encode", "number", ["number", "number"]); + this.QTS_bjson_decode = this.module.cwrap("QTS_bjson_decode", "number", ["number", "number"]); + } + }; + } +}); + +// registry/components/code/node_modules/@jitl/quickjs-wasmfile-release-sync/dist/emscripten-module.browser.mjs +var emscripten_module_browser_exports = {}; +__export(emscripten_module_browser_exports, { + default: () => emscripten_module_browser_default +}); +async function QuickJSRaw(moduleArg = {}) { + var moduleRtn; + var c = moduleArg, aa = !!globalThis.window, n = !!globalThis.WorkerGlobalScope; + function q(a) { + a = { log: a || function() { + } }; + for (const d of q.Pa) d(a); + return c.quickJSEmscriptenExtensions = a; + } + q.Pa = []; + c.quickjsEmscriptenInit = q; + q.Pa.push((a) => { + a.getWasmMemory = function() { + return r; + }; + }); + var t = "./this.program", ba = import.meta.url, u = "", v, w; + if (aa || n) { + try { + u = new URL(".", ba).href; + } catch { + } + n && (w = (a) => { + var d = new XMLHttpRequest(); + d.open("GET", a, false); + d.responseType = "arraybuffer"; + d.send(null); + return new Uint8Array(d.response); + }); + v = async (a) => { + a = await fetch(a, { credentials: "same-origin" }); + if (a.ok) return a.arrayBuffer(); + throw Error(a.status + " : " + a.url); + }; + } + var y = console.log.bind(console), z = console.error.bind(console), A, B = false, C, D, E, F, G, H, I, J = false; + function K() { + var a = r.buffer; + c.HEAP8 = F = new Int8Array(a); + new Int16Array(a); + c.HEAPU8 = G = new Uint8Array(a); + new Uint16Array(a); + H = new Int32Array(a); + I = new Uint32Array(a); + new Float32Array(a); + new Float64Array(a); + new BigInt64Array(a); + new BigUint64Array(a); + } + function L(a) { + c.onAbort?.(a); + a = "Aborted(" + a + ")"; + z(a); + B = true; + a = new WebAssembly.RuntimeError(a + ". Build with -sASSERTIONS for more info."); + E?.(a); + throw a; + } + var M; + async function ca(a) { + if (!A) try { + var d = await v(a); + return new Uint8Array(d); + } catch { + } + if (a == M && A) a = new Uint8Array(A); + else if (w) a = w(a); + else throw "both async and sync fetching of the wasm failed"; + return a; + } + async function da(a, d) { + try { + var b = await ca(a); + return await WebAssembly.instantiate(b, d); + } catch (e) { + z(`failed to asynchronously prepare wasm: ${e}`), L(e); + } + } + async function ea(a) { + var d = M; + if (!A) try { + var b = fetch(d, { credentials: "same-origin" }); + return await WebAssembly.instantiateStreaming(b, a); + } catch (e) { + z(`wasm streaming compile failed: ${e}`), z("falling back to ArrayBuffer instantiation"); + } + return da(d, a); + } + class N { + name = "ExitStatus"; + constructor(a) { + this.message = `Program terminated with exit(${a})`; + this.status = a; + } + } + var O = (a) => { + for (; 0 < a.length; ) a.shift()(c); + }, P = [], fa = [], ha = () => { + var a = c.preRun.shift(); + fa.push(a); + }, Q = true, r, ia = new TextDecoder(), ja = (a, d, b, e) => { + b = d + b; + if (e) return b; + for (; a[d] && !(d >= b); ) ++d; + return d; + }, R = (a, d, b) => a ? ia.decode(G.subarray(a, ja(G, a, d, b))) : "", S = 0, ka = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335], la = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334], T = {}, ma = (a) => { + if (!(a instanceof N || "unwind" == a)) throw a; + }, na = (a) => { + C = a; + Q || 0 < S || (c.onExit?.(a), B = true); + throw new N(a); + }, oa = (a) => { + if (!B) try { + a(); + } catch (d) { + ma(d); + } finally { + if (!(Q || 0 < S)) try { + C = a = C, na(a); + } catch (d) { + ma(d); + } + } + }, U = (a, d, b) => { + var e = G; + if (!(0 < b)) return 0; + var f = d; + b = d + b - 1; + for (var g = 0; g < a.length; ++g) { + var h = a.codePointAt(g); + if (127 >= h) { + if (d >= b) break; + e[d++] = h; + } else if (2047 >= h) { + if (d + 1 >= b) break; + e[d++] = 192 | h >> 6; + e[d++] = 128 | h & 63; + } else if (65535 >= h) { + if (d + 2 >= b) break; + e[d++] = 224 | h >> 12; + e[d++] = 128 | h >> 6 & 63; + e[d++] = 128 | h & 63; + } else { + if (d + 3 >= b) break; + e[d++] = 240 | h >> 18; + e[d++] = 128 | h >> 12 & 63; + e[d++] = 128 | h >> 6 & 63; + e[d++] = 128 | h & 63; + g++; + } + } + e[d] = 0; + return d - f; + }, V = {}, pa = () => { + if (!W) { + var a = { + USER: "web_user", + LOGNAME: "web_user", + PATH: "/", + PWD: "/", + HOME: "/home/web_user", + LANG: (globalThis.navigator?.language ?? "C").replace("-", "_") + ".UTF-8", + _: t || "./this.program" + }, d; + for (d in V) void 0 === V[d] ? delete a[d] : a[d] = V[d]; + var b = []; + for (d in a) b.push(`${d}=${a[d]}`); + W = b; + } + return W; + }, W, X = (a) => { + for (var d = 0, b = 0; b < a.length; ++b) { + var e = a.charCodeAt(b); + 127 >= e ? d++ : 2047 >= e ? d += 2 : 55296 <= e && 57343 >= e ? (d += 4, ++b) : d += 3; + } + return d; + }, qa = [null, [], []], ta = (a, d, b, e) => { + var f = { string: (k) => { + var l = 0; + if (null !== k && void 0 !== k && 0 !== k) { + l = X(k) + 1; + var p = Y(l); + U(k, p, l); + l = p; + } + return l; + }, array: (k) => { + var l = Y(k.length); + F.set(k, l); + return l; + } }; + a = c["_" + a]; + var g = [], h = 0; + if (e) for (var m = 0; m < e.length; m++) { + var x = f[b[m]]; + x ? (0 === h && (h = ra()), g[m] = x(e[m])) : g[m] = e[m]; + } + b = a(...g); + return b = function(k) { + 0 !== h && sa(h); + return "string" === d ? R(k) : "boolean" === d ? !!k : k; + }(b); + }; + c.wasmMemory ? r = c.wasmMemory : r = new WebAssembly.Memory({ initial: (c.INITIAL_MEMORY || 16777216) / 65536, maximum: 32768 }); + K(); + c.noExitRuntime && (Q = c.noExitRuntime); + c.print && (y = c.print); + c.printErr && (z = c.printErr); + c.wasmBinary && (A = c.wasmBinary); + c.thisProgram && (t = c.thisProgram); + if (c.preInit) for ("function" == typeof c.preInit && (c.preInit = [c.preInit]); 0 < c.preInit.length; ) c.preInit.shift()(); + c.cwrap = (a, d, b, e) => { + var f = !b || b.every((g) => "number" === g || "boolean" === g); + return "string" !== d && f && !e ? c["_" + a] : (...g) => ta(a, d, b, g); + }; + c.UTF8ToString = R; + c.stringToUTF8 = (a, d, b) => U(a, d, b); + c.lengthBytesUTF8 = X; + var ua, sa, Y, ra, va = { b: (a, d, b, e) => L(`Assertion failed: ${R(a)}, at: ` + [d ? R(d) : "unknown filename", b, e ? R(e) : "unknown function"]), q: () => L(""), l: () => { + Q = false; + S = 0; + }, m: function(a, d) { + a = -9007199254740992 > a || 9007199254740992 < a ? NaN : Number(a); + a = new Date(1e3 * a); + H[d >> 2] = a.getSeconds(); + H[d + 4 >> 2] = a.getMinutes(); + H[d + 8 >> 2] = a.getHours(); + H[d + 12 >> 2] = a.getDate(); + H[d + 16 >> 2] = a.getMonth(); + H[d + 20 >> 2] = a.getFullYear() - 1900; + H[d + 24 >> 2] = a.getDay(); + var b = a.getFullYear(); + H[d + 28 >> 2] = (0 !== b % 4 || 0 === b % 100 && 0 !== b % 400 ? la : ka)[a.getMonth()] + a.getDate() - 1 | 0; + H[d + 36 >> 2] = -(60 * a.getTimezoneOffset()); + b = new Date(a.getFullYear(), 6, 1).getTimezoneOffset(); + var e = new Date(a.getFullYear(), 0, 1).getTimezoneOffset(); + H[d + 32 >> 2] = (b != e && a.getTimezoneOffset() == Math.min(e, b)) | 0; + }, j: (a, d) => { + T[a] && (clearTimeout(T[a].id), delete T[a]); + if (!d) return 0; + var b = setTimeout(() => { + delete T[a]; + oa(() => ua(a, performance.now())); + }, d); + T[a] = { id: b, Qa: d }; + return 0; + }, n: (a, d, b, e) => { + var f = (/* @__PURE__ */ new Date()).getFullYear(), g = new Date(f, 0, 1).getTimezoneOffset(); + f = new Date(f, 6, 1).getTimezoneOffset(); + I[a >> 2] = 60 * Math.max(g, f); + H[d >> 2] = Number(g != f); + d = (h) => { + var m = Math.abs(h); + return `UTC${0 <= h ? "-" : "+"}${String(Math.floor(m / 60)).padStart(2, "0")}${String(m % 60).padStart(2, "0")}`; + }; + a = d(g); + d = d(f); + f < g ? (U(a, b, 17), U(d, e, 17)) : (U(a, e, 17), U(d, b, 17)); + }, p: () => Date.now(), k: (a) => { + var d = G.length; + a >>>= 0; + if (2147483648 < a) return false; + for (var b = 1; 4 >= b; b *= 2) { + var e = d * (1 + 0.2 / b); + e = Math.min(e, a + 100663296); + a: { + e = (Math.min(2147483648, 65536 * Math.ceil(Math.max(a, e) / 65536)) - r.buffer.byteLength + 65535) / 65536 | 0; + try { + r.grow(e); + K(); + var f = 1; + break a; + } catch (g) { + } + f = void 0; + } + if (f) return true; + } + return false; + }, e: (a, d) => { + var b = 0, e = 0, f; + for (f of pa()) { + var g = d + b; + I[a + e >> 2] = g; + b += U(f, g, Infinity) + 1; + e += 4; + } + return 0; + }, f: (a, d) => { + var b = pa(); + I[a >> 2] = b.length; + a = 0; + for (var e of b) a += X(e) + 1; + I[d >> 2] = a; + return 0; + }, d: () => 52, o: function() { + return 70; + }, c: (a, d, b, e) => { + for (var f = 0, g = 0; g < b; g++) { + var h = I[d >> 2], m = I[d + 4 >> 2]; + d += 8; + for (var x = 0; x < m; x++) { + var k = a, l = G[h + x], p = qa[k]; + 0 === l || 10 === l ? (k = 1 === k ? y : z, l = ja(p, 0), l = ia.decode(p.buffer ? p.subarray(0, l) : new Uint8Array(p.slice(0, l))), k(l), p.length = 0) : p.push(l); + } + f += m; + } + I[e >> 2] = f; + return 0; + }, a: r, r: na, s: function(a, d, b, e, f) { + return c.callbacks.callFunction(void 0, a, d, b, e, f); + }, i: function(a) { + return c.callbacks.shouldInterrupt(void 0, a); + }, h: function(a, d, b) { + b = R(b); + return c.callbacks.loadModuleSource(void 0, a, d, b); + }, g: function(a, d, b, e) { + b = R(b); + e = R(e); + return c.callbacks.normalizeModule(void 0, a, d, b, e); + }, t: function(a, d) { + c.callbacks.freeHostRef(void 0, a, d); + } }, Z; + Z = await async function() { + function a(b) { + b = Z = b.exports; + c._malloc = b.v; + c._QTS_Throw = b.w; + c._QTS_NewError = b.x; + c._QTS_RuntimeSetMemoryLimit = b.y; + c._QTS_RuntimeComputeMemoryUsage = b.z; + c._QTS_RuntimeDumpMemoryUsage = b.A; + c._QTS_RecoverableLeakCheck = b.B; + c._QTS_BuildIsSanitizeLeak = b.C; + c._QTS_RuntimeSetMaxStackSize = b.D; + c._QTS_GetUndefined = b.E; + c._QTS_GetNull = b.F; + c._QTS_GetFalse = b.G; + c._QTS_GetTrue = b.H; + c._QTS_NewHostRef = b.I; + c._QTS_GetHostRefId = b.J; + c._QTS_NewRuntime = b.K; + c._QTS_FreeRuntime = b.L; + c._free = b.M; + c._QTS_NewContext = b.N; + c._QTS_FreeContext = b.O; + c._QTS_FreeValuePointer = b.P; + c._QTS_FreeValuePointerRuntime = b.Q; + c._QTS_FreeVoidPointer = b.R; + c._QTS_FreeCString = b.S; + c._QTS_DupValuePointer = b.T; + c._QTS_NewObject = b.U; + c._QTS_NewObjectProto = b.V; + c._QTS_NewArray = b.W; + c._QTS_NewArrayBuffer = b.X; + c._QTS_NewFloat64 = b.Y; + c._QTS_GetFloat64 = b.Z; + c._QTS_NewString = b._; + c._QTS_GetString = b.$; + c._QTS_GetArrayBuffer = b.aa; + c._QTS_GetArrayBufferLength = b.ba; + c._QTS_NewSymbol = b.ca; + c._QTS_GetSymbolDescriptionOrKey = b.da; + c._QTS_IsGlobalSymbol = b.ea; + c._QTS_IsJobPending = b.fa; + c._QTS_ExecutePendingJob = b.ga; + c._QTS_GetProp = b.ha; + c._QTS_GetPropNumber = b.ia; + c._QTS_SetProp = b.ja; + c._QTS_DefineProp = b.ka; + c._QTS_GetOwnPropertyNames = b.la; + c._QTS_Call = b.ma; + c._QTS_ResolveException = b.na; + c._QTS_Dump = b.oa; + c._QTS_Eval = b.pa; + c._QTS_GetModuleNamespace = b.qa; + c._QTS_Typeof = b.ra; + c._QTS_GetLength = b.sa; + c._QTS_IsEqual = b.ta; + c._QTS_GetGlobalObject = b.ua; + c._QTS_NewPromiseCapability = b.va; + c._QTS_PromiseState = b.wa; + c._QTS_PromiseResult = b.xa; + c._QTS_TestStringArg = b.ya; + c._QTS_GetDebugLogEnabled = b.za; + c._QTS_SetDebugLogEnabled = b.Aa; + c._QTS_BuildIsDebug = b.Ba; + c._QTS_BuildIsAsyncify = b.Ca; + c._QTS_NewFunction = b.Da; + c._QTS_ArgvGetJSValueConstPointer = b.Ea; + c._QTS_RuntimeEnableInterruptHandler = b.Fa; + c._QTS_RuntimeDisableInterruptHandler = b.Ga; + c._QTS_RuntimeEnableModuleLoader = b.Ha; + c._QTS_RuntimeDisableModuleLoader = b.Ia; + c._QTS_bjson_encode = b.Ja; + c._QTS_bjson_decode = b.Ka; + ua = b.La; + sa = b.Ma; + Y = b.Na; + ra = b.Oa; + return Z; + } + var d = { a: va }; + if (c.instantiateWasm) return new Promise((b) => { + c.instantiateWasm(d, (e, f) => { + b(a(e, f)); + }); + }); + M ??= c.locateFile ? c.locateFile ? c.locateFile("emscripten-module.wasm", u) : u + "emscripten-module.wasm" : new URL("emscripten-module.wasm", import.meta.url).href; + return a((await ea(d)).instance); + }(); + (function() { + function a() { + c.calledRun = true; + if (!B) { + J = true; + Z.u(); + D?.(c); + c.onRuntimeInitialized?.(); + if (c.postRun) for ("function" == typeof c.postRun && (c.postRun = [c.postRun]); c.postRun.length; ) { + var d = c.postRun.shift(); + P.push(d); + } + O(P); + } + } + if (c.preRun) for ("function" == typeof c.preRun && (c.preRun = [c.preRun]); c.preRun.length; ) ha(); + O(fa); + c.setStatus ? (c.setStatus("Running..."), setTimeout(() => { + setTimeout(() => c.setStatus(""), 1); + a(); + }, 1)) : a(); + })(); + J ? moduleRtn = c : moduleRtn = new Promise((a, d) => { + D = a; + E = d; + }); + ; + return moduleRtn; +} +var emscripten_module_browser_default; +var init_emscripten_module_browser = __esm({ + "registry/components/code/node_modules/@jitl/quickjs-wasmfile-release-sync/dist/emscripten-module.browser.mjs"() { + emscripten_module_browser_default = QuickJSRaw; + } +}); + +// registry/components/code/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err2) { + if (err2 instanceof Error && onError) { + context.error = err2; + res = await onError(err2, context); + isError = true; + } else { + throw err2; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// registry/components/code/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// registry/components/code/node_modules/hono/dist/utils/body.js +var parseBody = 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 {}; +}; +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 handleParsingAllValues = (form, key, value) => { + if (form[key] !== void 0) { + if (Array.isArray(form[key])) { + ; + form[key].push(value); + } else { + form[key] = [form[key], value]; + } + } else { + if (!key.endsWith("[]")) { + form[key] = value; + } else { + form[key] = [value]; + } + } +}; +var handleParsingNestedValues = (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]; + } + }); +}; + +// registry/components/code/node_modules/hono/dist/utils/url.js +var splitPath = (path) => { + const paths = path.split("/"); + if (paths[0] === "") { + paths.shift(); + } + return paths; +}; +var splitRoutingPath = (routePath) => { + const { groups, path } = extractGroupsFromPath(routePath); + const paths = splitPath(path); + return replaceGroupMarks(paths, groups); +}; +var extractGroupsFromPath = (path) => { + const groups = []; + path = path.replace(/\{[^}]+\}/g, (match2, index) => { + const mark = `@${index}`; + groups.push([mark, match2]); + return mark; + }); + return { groups, path }; +}; +var replaceGroupMarks = (paths, groups) => { + for (let i = groups.length - 1; i >= 0; i--) { + const [mark] = groups[i]; + for (let j = paths.length - 1; j >= 0; j--) { + if (paths[j].includes(mark)) { + paths[j] = paths[j].replace(mark, groups[i][1]); + break; + } + } + } + return paths; +}; +var patternCache = {}; +var getPattern = (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; +}; +var tryDecode = (str, decoder) => { + try { + return decoder(str); + } catch { + return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => { + try { + return decoder(match2); + } catch { + return match2; + } + }); + } +}; +var tryDecodeURI = (str) => tryDecode(str, decodeURI); +var getPath = (request) => { + const url = request.url; + const start = url.indexOf("/", url.indexOf(":") + 4); + let i = start; + for (; i < url.length; i++) { + const charCode = url.charCodeAt(i); + if (charCode === 37) { + const queryIndex = url.indexOf("?", i); + const hashIndex = url.indexOf("#", i); + const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex); + const 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); +}; +var getPathNoStrict = (request) => { + const result = getPath(request); + return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result; +}; +var mergePath = (base, sub, ...rest) => { + if (rest.length) { + sub = mergePath(sub, ...rest); + } + return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; +}; +var checkOptionalParameter = (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); +}; +var _decodeURI = (value) => { + if (!/[%+]/.test(value)) { + return value; + } + if (value.indexOf("+") !== -1) { + value = value.replace(/\+/g, " "); + } + return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value; +}; +var _getQueryParam = (url, key, multiple) => { + let encoded; + if (!multiple && key && !/[%+]/.test(key)) { + let keyIndex2 = url.indexOf("?", 8); + if (keyIndex2 === -1) { + return void 0; + } + if (!url.startsWith(key, keyIndex2 + 1)) { + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + while (keyIndex2 !== -1) { + const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1); + if (trailingKeyCode === 61) { + const valueIndex = keyIndex2 + key.length + 2; + const endIndex = url.indexOf("&", valueIndex); + return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex)); + } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) { + return ""; + } + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + encoded = /[%+]/.test(url); + if (!encoded) { + return void 0; + } + } + 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; +}; +var getQueryParam = _getQueryParam; +var getQueryParams = (url, key) => { + return _getQueryParam(url, key, true); +}; +var decodeURIComponent_ = decodeURIComponent; + +// registry/components/code/node_modules/hono/dist/request.js +var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_); +var HonoRequest = class { + /** + * `.raw` can get the raw Request object. + * + * @see {@link https://hono.dev/docs/api/request#raw} + * + * @example + * ```ts + * // For Cloudflare Workers + * app.post('/', async (c) => { + * const metadata = c.req.raw.cf?.hostMetadata? + * ... + * }) + * ``` + */ + raw; + #validatedData; + // Short name of validatedData + #matchResult; + routeIndex = 0; + /** + * `.path` can get the pathname of the request. + * + * @see {@link https://hono.dev/docs/api/request#path} + * + * @example + * ```ts + * app.get('/about/me', (c) => { + * const pathname = c.req.path // `/about/me` + * }) + * ``` + */ + path; + bodyCache = {}; + constructor(request, 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 = (key) => { + const { bodyCache, raw: raw2 } = this; + const cachedBody = bodyCache[key]; + if (cachedBody) { + return cachedBody; + } + const anyCachedKey = Object.keys(bodyCache)[0]; + if (anyCachedKey) { + return bodyCache[anyCachedKey].then((body) => { + if (anyCachedKey === "json") { + body = JSON.stringify(body); + } + return new Response(body)[key](); + }); + } + return bodyCache[key] = raw2[key](); + }; + /** + * `.json()` can parse Request body of type `application/json` + * + * @see {@link https://hono.dev/docs/api/request#json} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.json() + * }) + * ``` + */ + json() { + return this.#cachedBody("text").then((text) => JSON.parse(text)); + } + /** + * `.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"); + } + /** + * `.bytes()` parses the request body as a `Uint8Array`. + * + * @see {@link https://hono.dev/docs/api/request#bytes} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.bytes() + * }) + * ``` + */ + bytes() { + return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer)); + } + /** + * 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; + } +}; + +// registry/components/code/node_modules/hono/dist/utils/html.js +var HtmlEscapedCallbackPhase = { + Stringify: 1, + BeforeStream: 2, + Stream: 3 +}; +var raw = (value, callbacks) => { + const escapedString = new String(value); + escapedString.isEscaped = true; + escapedString.callbacks = callbacks; + return escapedString; +}; +var resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => { + if (typeof str === "object" && !(str instanceof String)) { + if (!(str instanceof Promise)) { + str = str.toString(); + } + if (str instanceof Promise) { + str = await str; + } + } + const callbacks = str.callbacks; + if (!callbacks?.length) { + return Promise.resolve(str); + } + if (buffer) { + buffer[0] += str; + } else { + buffer = [str]; + } + const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then( + (res) => Promise.all( + res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer)) + ).then(() => buffer[0]) + ); + if (preserveCallbacks) { + return raw(await resStr, callbacks); + } else { + return resStr; + } +}; + +// registry/components/code/node_modules/hono/dist/context.js +var TEXT_PLAIN = "text/plain; charset=UTF-8"; +var setDefaultContentType = (contentType, headers) => { + return { + "Content-Type": contentType, + ...headers + }; +}; +var createResponseInstance = (body, init) => new Response(body, init); +var Context = class { + #rawRequest; + #req; + /** + * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers. + * + * @see {@link https://hono.dev/docs/api/context#env} + * + * @example + * ```ts + * // Environment object for Cloudflare Workers + * app.get('*', async c => { + * const counter = c.env.COUNTER + * }) + * ``` + */ + env = {}; + #var; + finalized = false; + /** + * `.error` can get the error object from the middleware if the Handler throws an error. + * + * @see {@link https://hono.dev/docs/api/context#error} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * await next() + * if (c.error) { + * // do something... + * } + * }) + * ``` + */ + error; + #status; + #executionCtx; + #res; + #layout; + #renderer; + #notFoundHandler; + #preparedHeaders; + #matchResult; + #path; + /** + * Creates an instance of the Context class. + * + * @param req - The Request object. + * @param options - Optional configuration options for the context. + */ + constructor(req, options) { + this.#rawRequest = req; + if (options) { + this.#executionCtx = options.executionCtx; + this.env = options.env; + this.#notFoundHandler = options.notFoundHandler; + this.#path = options.path; + this.#matchResult = options.matchResult; + } + } + /** + * `.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 = (...args) => { + this.#renderer ??= (content) => this.html(content); + return this.#renderer(...args); + }; + /** + * Sets the layout for the response. + * + * @param layout - The layout to set. + * @returns The layout function. + */ + setLayout = (layout) => this.#layout = layout; + /** + * Gets the current layout for the response. + * + * @returns The current layout function. + */ + getLayout = () => this.#layout; + /** + * `.setRenderer()` can set the layout in the custom middleware. + * + * @see {@link https://hono.dev/docs/api/context#render-setrenderer} + * + * @example + * ```tsx + * app.use('*', async (c, next) => { + * c.setRenderer((content) => { + * return c.html( + * + * + *

{content}

+ * + * + * ) + * }) + * await next() + * }) + * ``` + */ + setRenderer = (renderer) => { + this.#renderer = renderer; + }; + /** + * `.header()` can set headers. + * + * @see {@link https://hono.dev/docs/api/context#header} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * + * return c.body('Thank you for coming') + * }) + * ``` + */ + header = (name, value, options) => { + if (this.finalized) { + this.#res = createResponseInstance(this.#res.body, this.#res); + } + const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers(); + if (value === void 0) { + headers.delete(name); + } else if (options?.append) { + headers.append(name, value); + } else { + headers.set(name, value); + } + }; + status = (status) => { + this.#status = status; + }; + /** + * `.set()` can set the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * c.set('message', 'Hono is hot!!') + * await next() + * }) + * ``` + */ + set = (key, value) => { + this.#var ??= /* @__PURE__ */ new Map(); + this.#var.set(key, value); + }; + /** + * `.get()` can use the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.get('/', (c) => { + * const message = c.get('message') + * return c.text(`The message is "${message}"`) + * }) + * ``` + */ + get = (key) => { + return this.#var ? this.#var.get(key) : void 0; + }; + /** + * `.var` can access the value of a variable. + * + * @see {@link https://hono.dev/docs/api/context#var} + * + * @example + * ```ts + * const result = c.var.client.oneMethod() + * ``` + */ + // c.var.propName is a read-only + get var() { + if (!this.#var) { + return {}; + } + return Object.fromEntries(this.#var); + } + #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 = (...args) => this.#newResponse(...args); + /** + * `.body()` can return the HTTP response. + * You can set headers with `.header()` and set HTTP status code with `.status`. + * This can also be set in `.text()`, `.json()` and so on. + * + * @see {@link https://hono.dev/docs/api/context#body} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * // Set HTTP status code + * c.status(201) + * + * // Return the response body + * return c.body('Thank you for coming') + * }) + * ``` + */ + body = (data, arg, headers) => this.#newResponse(data, arg, headers); + /** + * `.text()` can render text as `Content-Type:text/plain`. + * + * @see {@link https://hono.dev/docs/api/context#text} + * + * @example + * ```ts + * app.get('/say', (c) => { + * return c.text('Hello!') + * }) + * ``` + */ + text = (text, arg, headers) => { + return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse( + text, + arg, + setDefaultContentType(TEXT_PLAIN, headers) + ); + }; + /** + * `.json()` can render JSON as `Content-Type:application/json`. + * + * @see {@link https://hono.dev/docs/api/context#json} + * + * @example + * ```ts + * app.get('/api', (c) => { + * return c.json({ message: 'Hello!' }) + * }) + * ``` + */ + json = (object, arg, headers) => { + return this.#newResponse( + JSON.stringify(object), + arg, + setDefaultContentType("application/json", headers) + ); + }; + html = (html, arg, headers) => { + const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers)); + return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html); + }; + /** + * `.redirect()` can Redirect, default status code is 302. + * + * @see {@link https://hono.dev/docs/api/context#redirect} + * + * @example + * ```ts + * app.get('/redirect', (c) => { + * return c.redirect('/') + * }) + * app.get('/redirect-permanently', (c) => { + * return c.redirect('/', 301) + * }) + * ``` + */ + redirect = (location, status) => { + const locationString = String(location); + this.header( + "Location", + // Multibyes should be encoded + // eslint-disable-next-line no-control-regex + !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString) + ); + return this.newResponse(null, status ?? 302); + }; + /** + * `.notFound()` can return the Not Found Response. + * + * @see {@link https://hono.dev/docs/api/context#notfound} + * + * @example + * ```ts + * app.get('/notfound', (c) => { + * return c.notFound() + * }) + * ``` + */ + notFound = () => { + this.#notFoundHandler ??= () => createResponseInstance(); + return this.#notFoundHandler(this); + }; +}; + +// registry/components/code/node_modules/hono/dist/router.js +var METHOD_NAME_ALL = "ALL"; +var METHOD_NAME_ALL_LOWERCASE = "all"; +var METHODS = ["get", "post", "put", "delete", "options", "patch"]; +var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built."; +var UnsupportedPathError = class extends Error { +}; + +// registry/components/code/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// registry/components/code/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err2, c) => { + if ("getResponse" in err2) { + const res = err2.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err2); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + args.forEach((handler) => { + this.#addRoute(method, this.#path, handler); + }); + return this; + }; + }); + this.on = (method, 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 = async (c, next) => (await compose([], app2.errorHandler)(c, () => r.handler(c, next))).res; + handler[COMPOSED_HANDLER] = r.handler; + } + subApp.#addRoute(r.method, r.path, handler, r.basePath); + }); + 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 = (handler) => { + this.errorHandler = handler; + return this; + }; + /** + * `.notFound()` allows you to customize a Not Found Response. + * + * @see {@link https://hono.dev/docs/api/hono#not-found} + * + * @param {NotFoundHandler} handler - request handler for not-found + * @returns {Hono} changed Hono instance + * + * @example + * ```ts + * app.notFound((c) => { + * return c.text('Custom 404 Message', 404) + * }) + * ``` + */ + notFound = (handler) => { + this.#notFoundHandler = handler; + return this; + }; + /** + * `.mount()` allows you to mount applications built with other frameworks into your Hono application. + * + * @see {@link https://hono.dev/docs/api/hono#mount} + * + * @param {string} path - base Path + * @param {Function} applicationHandler - other Request Handler + * @param {MountOptions} [options] - options of `.mount()` + * @returns {Hono} mounted Hono instance + * + * @example + * ```ts + * import { Router as IttyRouter } from 'itty-router' + * import { Hono } from 'hono' + * // Create itty-router application + * const ittyRouter = IttyRouter() + * // GET /itty-router/hello + * ittyRouter.get('/hello', () => new Response('Hello from itty-router')) + * + * const app = new Hono() + * app.mount('/itty-router', ittyRouter.handle) + * ``` + * + * @example + * ```ts + * const app = new Hono() + * // Send the request to another application without modification. + * app.mount('/app', anotherApp, { + * replaceRequest: (req) => req, + * }) + * ``` + */ + mount(path, applicationHandler, options) { + let replaceRequest; + let optionHandler; + if (options) { + if (typeof options === "function") { + optionHandler = options; + } else { + optionHandler = options.optionHandler; + if (options.replaceRequest === false) { + replaceRequest = (request) => request; + } else { + replaceRequest = options.replaceRequest; + } + } + } + const getOptions = optionHandler ? (c) => { + const options2 = optionHandler(c); + return Array.isArray(options2) ? options2 : [options2]; + } : (c) => { + let executionContext = void 0; + try { + executionContext = c.executionCtx; + } catch { + } + return [c.env, executionContext]; + }; + replaceRequest ||= (() => { + const mergedPath = mergePath(this._basePath, path); + const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length; + return (request) => { + const url = new URL(request.url); + url.pathname = this.getPath(request).slice(pathPrefixLength) || "/"; + return new Request(url, request); + }; + })(); + const handler = async (c, next) => { + const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c)); + if (res) { + return res; + } + await next(); + }; + this.#addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler); + return this; + } + #addRoute(method, path, handler, baseRoutePath) { + method = method.toUpperCase(); + path = mergePath(this._basePath, path); + const r = { + basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath, + path, + method, + handler + }; + this.router.add(method, path, [handler, r]); + this.routes.push(r); + } + #handleError(err2, c) { + if (err2 instanceof Error) { + return this.errorHandler(err2, c); + } + throw err2; + } + #dispatch(request, executionCtx, env, method) { + if (method === "HEAD") { + return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))(); + } + const path = this.getPath(request, { env }); + const matchResult = this.router.match(method, path); + const c = new Context(request, { + path, + matchResult, + env, + 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 (err2) { + return this.#handleError(err2, c); + } + return res instanceof Promise ? res.then( + (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c)) + ).catch((err2) => this.#handleError(err2, c)) : res ?? this.#notFoundHandler(c); + } + const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler); + return (async () => { + try { + const context = await composed(c); + if (!context.finalized) { + throw new Error( + "Context is not finalized. Did you forget to return a Response object or `await next()`?" + ); + } + return context.res; + } catch (err2) { + return this.#handleError(err2, c); + } + })(); + } + /** + * `.fetch()` will be entry point of your app. + * + * @see {@link https://hono.dev/docs/api/hono#fetch} + * + * @param {Request} request - request Object of request + * @param {Env} Env - env Object + * @param {ExecutionContext} - context of execution + * @returns {Response | Promise} response of request + * + */ + fetch = (request, ...rest) => { + return this.#dispatch(request, rest[1], rest[0], request.method); + }; + /** + * `.request()` is a useful method for testing. + * You can pass a URL or pathname to send a GET request. + * app will return a Response object. + * ```ts + * test('GET /hello is ok', async () => { + * const res = await app.request('/hello') + * expect(res.status).toBe(200) + * }) + * ``` + * @see https://hono.dev/docs/api/hono#request + */ + request = (input, requestInit, Env, executionCtx) => { + if (input instanceof Request) { + return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx); + } + input = input.toString(); + return this.fetch( + new Request( + /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`, + requestInit + ), + Env, + executionCtx + ); + }; + /** + * `.fire()` automatically adds a global fetch event listener. + * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers. + * @deprecated + * Use `fire` from `hono/service-worker` instead. + * ```ts + * import { Hono } from 'hono' + * import { fire } from 'hono/service-worker' + * + * const app = new Hono() + * // ... + * fire(app) + * ``` + * @see https://hono.dev/docs/api/hono#fire + * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API + * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/ + */ + fire = () => { + addEventListener("fetch", (event) => { + event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method)); + }); + }; +}; + +// registry/components/code/node_modules/hono/dist/router/reg-exp-router/matcher.js +var emptyParam = []; +function match(method, path) { + const matchers = this.buildAllMatchers(); + const match2 = (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]; + }; + this.match = match2; + return match2(method, path); +} + +// registry/components/code/node_modules/hono/dist/router/reg-exp-router/node.js +var LABEL_REG_EXP_STR = "[^/]+"; +var ONLY_WILDCARD_REG_EXP_STR = ".*"; +var TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)"; +var PATH_ERROR = /* @__PURE__ */ Symbol(); +var regExpMetaChars = new Set(".\\+*[^]$()"); +function compareKey(a, b) { + if (a.length === 1) { + return b.length === 1 ? a < b ? -1 : 1 : -1; + } + if (b.length === 1) { + return 1; + } + if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) { + return 1; + } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) { + return -1; + } + if (a === LABEL_REG_EXP_STR) { + return 1; + } else if (b === LABEL_REG_EXP_STR) { + return -1; + } + return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length; +} +var Node = class _Node { + #index; + #varIndex; + #children = /* @__PURE__ */ Object.create(null); + insert(tokens, index, paramMap, context, pathErrorCheckOnly) { + if (tokens.length === 0) { + if (this.#index !== void 0) { + throw PATH_ERROR; + } + if (pathErrorCheckOnly) { + return; + } + this.#index = index; + return; + } + const [token, ...restTokens] = tokens; + const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); + let node; + if (pattern) { + const name = pattern[1]; + let regexpStr = pattern[2] || LABEL_REG_EXP_STR; + if (name && pattern[2]) { + if (regexpStr === ".*") { + throw PATH_ERROR; + } + regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:"); + if (/\((?!\?:)/.test(regexpStr)) { + throw PATH_ERROR; + } + } + node = this.#children[regexpStr]; + if (!node) { + if (Object.keys(this.#children).some( + (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR + )) { + throw PATH_ERROR; + } + if (pathErrorCheckOnly) { + return; + } + node = this.#children[regexpStr] = new _Node(); + if (name !== "") { + node.#varIndex = context.varIndex++; + } + } + if (!pathErrorCheckOnly && name !== "") { + paramMap.push([name, node.#varIndex]); + } + } 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, context, pathErrorCheckOnly); + } + buildRegExpStr() { + const childKeys = Object.keys(this.#children).sort(compareKey); + const strList = childKeys.map((k) => { + const c = this.#children[k]; + return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr(); + }); + if (typeof this.#index === "number") { + strList.unshift(`#${this.#index}`); + } + if (strList.length === 0) { + return ""; + } + if (strList.length === 1) { + return strList[0]; + } + return "(?:" + strList.join("|") + ")"; + } +}; + +// registry/components/code/node_modules/hono/dist/router/reg-exp-router/trie.js +var Trie = class { + #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]; + } +}; + +// registry/components/code/node_modules/hono/dist/router/reg-exp-router/router.js +var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)]; +var wildcardRegExpCache = /* @__PURE__ */ Object.create(null); +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 RegExpRouter = class { + name = "RegExpRouter"; + #middleware; + #routes; + constructor() { + this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) }; + this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) }; + } + add(method, 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); + } + } +}; + +// registry/components/code/node_modules/hono/dist/router/smart-router/router.js +var SmartRouter = class { + 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]; + } +}; + +// registry/components/code/node_modules/hono/dist/router/trie-router/node.js +var emptyParams = /* @__PURE__ */ Object.create(null); +var hasChildren = (children) => { + for (const _ in children) { + return true; + } + return false; +}; +var Node2 = class _Node2 { + #methods; + #children; + #patterns; + #order = 0; + #params = emptyParams; + constructor(method, handler, children) { + this.#children = children || /* @__PURE__ */ Object.create(null); + this.#methods = []; + if (method && handler) { + const m = /* @__PURE__ */ Object.create(null); + m[method] = { handler, possibleKeys: [], score: 0 }; + this.#methods = [m]; + } + 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])]; + } +}; + +// registry/components/code/node_modules/hono/dist/router/trie-router/router.js +var TrieRouter = class { + 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); + } +}; + +// registry/components/code/node_modules/hono/dist/hono.js +var Hono2 = class extends Hono { + /** + * Creates an instance of the Hono class. + * + * @param options - Optional configuration options for the Hono instance. + */ + constructor(options = {}) { + super(options); + this.router = options.router ?? new SmartRouter({ + routers: [new RegExpRouter(), new TrieRouter()] + }); + } +}; + +// registry/components/code/node_modules/hono/dist/middleware/cors/index.js +var cors = (options) => { + const opts = { + origin: "*", + allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"], + allowHeaders: [], + exposeHeaders: [], + ...options + }; + const findAllowOrigin = ((optsOrigin) => { + if (typeof optsOrigin === "string") { + if (optsOrigin === "*") { + 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 async function cors2(c, next) { + function set(key, value) { + c.res.headers.set(key, value); + } + 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 !== "*") { + 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 !== "*") { + c.header("Vary", "Origin", { append: true }); + } + }; +}; + +// registry/components/code/node_modules/quickjs-emscripten-core/dist/index.mjs +init_chunk_JTKJZQYV(); +init_dist(); +async function newQuickJSWASMModuleFromVariant(variantOrPromise) { + let variant2 = smartUnwrap(await variantOrPromise), [wasmModuleLoader, QuickJSFFI2, { QuickJSWASMModule: QuickJSWASMModule2 }] = await Promise.all([variant2.importModuleLoader().then(smartUnwrap), variant2.importFFI(), Promise.resolve().then(() => (init_module_6F3E5H7Y(), module_6F3E5H7Y_exports)).then(smartUnwrap)]), wasmModule2 = await wasmModuleLoader(); + wasmModule2.type = "sync"; + let ffi = new QuickJSFFI2(wasmModule2); + return new QuickJSWASMModule2(wasmModule2, ffi); +} +function smartUnwrap(val) { + return val && "default" in val && val.default ? val.default && "default" in val.default && val.default.default ? val.default.default : val.default : val; +} +function newVariant(baseVariant, options) { + return { ...baseVariant, async importModuleLoader() { + let moduleLoader = smartUnwrap(await baseVariant.importModuleLoader()); + return async function() { + let moduleLoaderArg = options.emscriptenModule ? { ...options.emscriptenModule } : {}, log = options.log ?? ((...args) => debugLog("newVariant moduleLoader:", ...args)), tapValue = (message, val) => (log(...message, val), val), force = (val) => typeof val == "function" ? val() : val; + (options.wasmLocation || options.wasmSourceMapLocation || options.locateFile) && (moduleLoaderArg.locateFile = (fileName, relativeTo) => { + let args = { fileName, relativeTo }; + if (fileName.endsWith(".wasm") && options.wasmLocation !== void 0) return tapValue(["locateFile .wasm: provide wasmLocation", args], options.wasmLocation); + if (fileName.endsWith(".map")) { + if (options.wasmSourceMapLocation !== void 0) return tapValue(["locateFile .map: provide wasmSourceMapLocation", args], options.wasmSourceMapLocation); + if (options.wasmLocation && !options.locateFile) return tapValue(["locateFile .map: infer from wasmLocation", args], options.wasmLocation + ".map"); + } + return options.locateFile ? tapValue(["locateFile: use provided fn", args], options.locateFile(fileName, relativeTo)) : tapValue(["locateFile: unhandled, passthrough", args], fileName); + }), options.wasmBinary && (moduleLoaderArg.wasmBinary = await force(options.wasmBinary)), options.wasmMemory && (moduleLoaderArg.wasmMemory = await force(options.wasmMemory)); + let optionsWasmModule = options.wasmModule, modulePromise; + optionsWasmModule && (moduleLoaderArg.instantiateWasm = async (imports, onSuccess) => { + modulePromise ?? (modulePromise = Promise.resolve(force(optionsWasmModule))); + let wasmModule2 = await modulePromise; + if (!wasmModule2) throw new QuickJSEmscriptenModuleError(`options.wasmModule returned ${String(wasmModule2)}`); + let instance = await WebAssembly.instantiate(wasmModule2, imports); + return onSuccess(instance), instance.exports; + }), moduleLoaderArg.monitorRunDependencies = (left) => { + log("monitorRunDependencies:", left); + }, moduleLoaderArg.quickjsEmscriptenInit = () => newMockExtensions(log); + let resultPromise = moduleLoader(moduleLoaderArg), extensions = moduleLoaderArg.quickjsEmscriptenInit?.(log); + if (optionsWasmModule && extensions?.receiveWasmOffsetConverter && !extensions.existingWasmOffsetConverter) { + let wasmBinary = await force(options.wasmBinary) ?? new ArrayBuffer(0); + modulePromise ?? (modulePromise = Promise.resolve(force(optionsWasmModule))); + let wasmModule2 = await modulePromise; + if (!wasmModule2) throw new QuickJSEmscriptenModuleError(`options.wasmModule returned ${String(wasmModule2)}`); + extensions.receiveWasmOffsetConverter(wasmBinary, wasmModule2); + } + if (extensions?.receiveSourceMapJSON) { + let loadedSourceMapData = await force(options.wasmSourceMapData); + typeof loadedSourceMapData == "string" ? extensions.receiveSourceMapJSON(JSON.parse(loadedSourceMapData)) : loadedSourceMapData ? extensions.receiveSourceMapJSON(loadedSourceMapData) : extensions.receiveSourceMapJSON({ version: 3, names: [], sources: [], mappings: "" }); + } + return resultPromise; + }; + } }; +} +function newMockExtensions(log) { + let mockMessage = "mock called, emscripten module may not be initialized yet"; + return { mock: true, removeRunDependency(name) { + log(`${mockMessage}: removeRunDependency called:`, name); + }, receiveSourceMapJSON(data) { + log(`${mockMessage}: receiveSourceMapJSON called:`, data); + }, WasmOffsetConverter: void 0, receiveWasmOffsetConverter(bytes, mod) { + log(`${mockMessage}: receiveWasmOffsetConverter called:`, bytes, mod); + } }; +} + +// registry/components/code/node_modules/@jitl/quickjs-wasmfile-release-sync/dist/index.mjs +var variant = { type: "sync", importFFI: () => Promise.resolve().then(() => (init_ffi(), ffi_exports)).then((mod) => mod.QuickJSFFI), importModuleLoader: () => Promise.resolve().then(() => (init_emscripten_module_browser(), emscripten_module_browser_exports)).then((mod) => mod.default) }; +var src_default = variant; + +// registry/components/code/index.ts +import wasmModule from "./quickjs.wasm"; + +// registry/components/code/sandbox.mjs +var _variant = null; +function setVariant(v) { + _variant = v; + _modulePromise = null; +} +var DEFAULT_LIMITS = { + timeout_ms: 1e3, + // 牆鐘上限(Node/本機保護;CF 同步執行會凍結 Date.now,故非主保護) + max_ticks: 500, + // ★ 指令計數上限(CF 主保護):interrupt 回呼被叫超過此數即中止。 + // CF Workers 凍結同步 Date.now → 純同步無窮迴圈只能靠此計數中止。 + // 校準(leo21c 實測):interrupt cadence ≈ 5000 指令/tick; + // 真實 card 解析 ≈ 4 ticks;CF CPU 1102 門檻 ≈ 1000+ ticks。 + // 500 ticks(≈ 2.5M 指令)= card 的 125× 餘裕、且穩在 CF 門檻下。 + // 需更多算力的 user code 可提高 limits.max_ticks(但別逼近 ~1000)。 + memory_bytes: 16 * 1024 * 1024, + // QuickJS runtime 記憶體硬上限 + max_stack_bytes: 512 * 1024, + // 遞迴/深堆疊上限 + max_output_bytes: 1024 * 1024, + // stdout JSON 大小上限(防跑飛) + max_code_bytes: 256 * 1024 + // user code 本身大小上限 +}; +var SHA256_PRELUDE = ` +function sha256(ascii) { + function rr(n, x) { return (x >>> n) | (x << (32 - n)); } + var mathPow = Math.pow, maxWord = mathPow(2, 32), result = ''; + var words = [], asciiBitLength; + var utf8 = []; + for (var ci = 0; ci < ascii.length; ci++) { + var code = ascii.charCodeAt(ci); + if (code < 0x80) utf8.push(code); + else if (code < 0x800) { utf8.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f)); } + else if (code < 0xd800 || code >= 0xe000) { utf8.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f)); } + else { + ci++; + code = 0x10000 + (((code & 0x3ff) << 10) | (ascii.charCodeAt(ci) & 0x3ff)); + utf8.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 0x3f), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f)); + } + } + asciiBitLength = utf8.length * 8; + var hash = sha256.h = sha256.h || []; + var k = sha256.k = sha256.k || []; + var primeCounter = k.length; + var isComposite = {}; + for (var candidate = 2; primeCounter < 64; candidate++) { + if (!isComposite[candidate]) { + for (var i2 = 0; i2 < 313; i2 += candidate) isComposite[i2] = candidate; + hash[primeCounter] = (mathPow(candidate, 0.5) * maxWord) | 0; + k[primeCounter++] = (mathPow(candidate, 1 / 3) * maxWord) | 0; + } + } + hash = hash.slice(0, 8); + var bytes = utf8.slice(); + bytes.push(0x80); + while (bytes.length % 64 - 56) bytes.push(0x00); + for (var b = 0; b < bytes.length; b++) { + words[b >> 2] |= bytes[b] << ((3 - b) % 4) * 8; + } + words[words.length] = (asciiBitLength / maxWord) | 0; + words[words.length] = asciiBitLength; + for (var j = 0; j < words.length;) { + var w = words.slice(j, j += 16); + var oldHash = hash; + hash = hash.slice(0, 8); + for (var i = 0; i < 64; i++) { + var w15 = w[i - 15], w2 = w[i - 2]; + var a = hash[0], e = hash[4]; + var temp1 = hash[7] + + (rr(6, e) ^ rr(11, e) ^ rr(25, e)) + + ((e & hash[5]) ^ ((~e) & hash[6])) + + k[i] + + (w[i] = (i < 16) ? w[i] : ( + w[i - 16] + + (rr(7, w15) ^ rr(18, w15) ^ (w15 >>> 3)) + + w[i - 7] + + (rr(17, w2) ^ rr(19, w2) ^ (w2 >>> 10)) + ) | 0); + var temp2 = (rr(2, a) ^ rr(13, a) ^ rr(22, a)) + + ((a & hash[1]) ^ (a & hash[2]) ^ (hash[1] & hash[2])); + hash = [(temp1 + temp2) | 0].concat(hash); + hash[4] = (hash[4] + temp1) | 0; + } + for (var i = 0; i < 8; i++) hash[i] = (hash[i] + oldHash[i]) | 0; + } + for (var i = 0; i < 8; i++) { + for (var j = 3; j + 1; j--) { + var b2 = (hash[i] >> (j * 8)) & 255; + result += ((b2 < 16) ? 0 : '') + b2.toString(16); + } + } + return result; +} +`; +var _modulePromise = null; +function getModule() { + if (!_variant) throw new Error("sandbox variant not set \u2014 \u547C\u53EB setVariant() \u6CE8\u5165\u9810\u7DE8 WebAssembly.Module"); + if (!_modulePromise) _modulePromise = newQuickJSWASMModuleFromVariant(_variant); + return _modulePromise; +} +async function runCode(code, input, opts = {}) { + const limits = { ...DEFAULT_LIMITS, ...opts.limits || {} }; + if (typeof code !== "string") return err("code must be a string", "ContractError"); + if (byteLen(code) > limits.max_code_bytes) { + return err(`code exceeds max_code_bytes (${limits.max_code_bytes})`, "ResourceError"); + } + const QuickJS = await getModule(); + const runtime = QuickJS.newRuntime(); + runtime.setMemoryLimit(limits.memory_bytes); + runtime.setMaxStackSize(limits.max_stack_bytes); + const deadline = Date.now() + limits.timeout_ms; + let interrupted = false; + let ticks = 0; + runtime.setInterruptHandler(() => { + if (++ticks > limits.max_ticks) { + interrupted = true; + return true; + } + if (Date.now() > deadline) { + interrupted = true; + return true; + } + return false; + }); + const ctx = runtime.newContext(); + try { + const inputJson = JSON.stringify(input === void 0 ? null : input); + const wrapped = `(() => { + "use strict"; + ${SHA256_PRELUDE} + const input = JSON.parse(${JSON.stringify(inputJson)}); + const __run = (input) => { ${code} + }; + const __out = __run(input); + return JSON.stringify(__out === undefined ? null : __out); + })()`; + const evalResult = ctx.evalCode(wrapped, "user-code.js"); + if (evalResult.error) { + const detail = ctx.dump(evalResult.error); + evalResult.error.dispose(); + if (interrupted) return err(`execution aborted: exceeded time (${limits.timeout_ms}ms) or instruction budget (${limits.max_ticks} ticks)`, "TimeoutError"); + const msg = typeof detail === "object" && detail ? `${detail.name || "Error"}: ${detail.message || ""}`.trim() : String(detail); + return err(msg, "UserCodeError"); + } + const outJson = ctx.getString(evalResult.value); + evalResult.value.dispose(); + if (byteLen(outJson) > limits.max_output_bytes) { + return err(`output exceeds max_output_bytes (${limits.max_output_bytes})`, "ResourceError"); + } + return { success: true, data: JSON.parse(outJson) }; + } catch (e) { + if (interrupted) return err(`execution aborted: exceeded time (${limits.timeout_ms}ms) or instruction budget (${limits.max_ticks} ticks)`, "TimeoutError"); + const m = e instanceof Error ? e.message : String(e); + if (/out of memory|memory/i.test(m)) return err("out of memory", "ResourceError"); + return err(m, "SandboxError"); + } finally { + ctx.dispose(); + runtime.dispose(); + } +} +function byteLen(s) { + if (typeof Buffer !== "undefined") return Buffer.byteLength(s, "utf8"); + return new TextEncoder().encode(s).length; +} +function err(message, error_type) { + return { success: false, error: message, error_type }; +} + +// registry/components/code/index.ts +setVariant(newVariant(src_default, { wasmModule })); +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: "code" })); +app.post("/", async (c) => { + let body; + try { + body = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON", error_type: "ContractError" }, 400); + } + if (typeof body.code !== "string") { + return c.json({ success: false, error: "code (string) is required", error_type: "ContractError" }, 400); + } + try { + const result = await runCode(body.code, body.input, { limits: body.limits }); + return c.json(result); + } catch (e) { + return c.json( + { success: false, error: e instanceof Error ? e.message : String(e), error_type: "SandboxError" }, + 500 + ); + } +}); +var code_default = app; +export { + code_default as default +}; diff --git a/.worker-builds/arcrun-cypher-executor/worker.mjs b/.worker-builds/arcrun-cypher-executor/worker.mjs new file mode 100644 index 0000000..2b2877c --- /dev/null +++ b/.worker-builds/arcrun-cypher-executor/worker.mjs @@ -0,0 +1,15266 @@ +var __defProp = Object.defineProperty; +var __getOwnPropNames = Object.getOwnPropertyNames; +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 }); +}; + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/compose.js +var compose; +var init_compose = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/compose.js"() { + compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/http-exception.js +var init_http_exception = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/http-exception.js"() { + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT; +var init_constants = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request/constants.js"() { + GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + } +}); + +// cypher-executor/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({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/body.js"() { + init_request(); + parseBody = 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 {}; + }; + handleParsingAllValues = (form, key, value) => { + if (form[key] !== void 0) { + if (Array.isArray(form[key])) { + ; + form[key].push(value); + } else { + form[key] = [form[key], value]; + } + } else { + if (!key.endsWith("[]")) { + form[key] = value; + } else { + form[key] = [value]; + } + } + }; + handleParsingNestedValues = (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]; + } + }); + }; + } +}); + +// cypher-executor/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({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/url.js"() { + splitPath = (path) => { + const paths = path.split("/"); + if (paths[0] === "") { + paths.shift(); + } + return paths; + }; + splitRoutingPath = (routePath) => { + const { groups, path } = extractGroupsFromPath(routePath); + const paths = splitPath(path); + return replaceGroupMarks(paths, groups); + }; + extractGroupsFromPath = (path) => { + const groups = []; + path = path.replace(/\{[^}]+\}/g, (match2, index) => { + const mark = `@${index}`; + groups.push([mark, match2]); + return mark; + }); + return { groups, path }; + }; + replaceGroupMarks = (paths, groups) => { + for (let i = groups.length - 1; i >= 0; i--) { + const [mark] = groups[i]; + for (let j = paths.length - 1; j >= 0; j--) { + if (paths[j].includes(mark)) { + paths[j] = paths[j].replace(mark, groups[i][1]); + break; + } + } + } + return paths; + }; + patternCache = {}; + getPattern = (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; + }; + tryDecode = (str2, decoder) => { + try { + return decoder(str2); + } catch { + return str2.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match2) => { + try { + return decoder(match2); + } catch { + return match2; + } + }); + } + }; + tryDecodeURI = (str2) => tryDecode(str2, decodeURI); + getPath = (request) => { + const url = request.url; + const start = url.indexOf("/", url.indexOf(":") + 4); + let i = start; + for (; i < url.length; i++) { + const charCode = url.charCodeAt(i); + if (charCode === 37) { + const queryIndex = url.indexOf("?", i); + const hashIndex = url.indexOf("#", i); + const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex); + const 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); + }; + getPathNoStrict = (request) => { + const result = getPath(request); + return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result; + }; + mergePath = (base, sub, ...rest) => { + if (rest.length) { + sub = mergePath(sub, ...rest); + } + return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`; + }; + checkOptionalParameter = (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); + }; + _decodeURI = (value) => { + if (!/[%+]/.test(value)) { + return value; + } + if (value.indexOf("+") !== -1) { + value = value.replace(/\+/g, " "); + } + return value.indexOf("%") !== -1 ? tryDecode(value, decodeURIComponent_) : value; + }; + _getQueryParam = (url, key, multiple) => { + let encoded; + if (!multiple && key && !/[%+]/.test(key)) { + let keyIndex2 = url.indexOf("?", 8); + if (keyIndex2 === -1) { + return void 0; + } + if (!url.startsWith(key, keyIndex2 + 1)) { + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + while (keyIndex2 !== -1) { + const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1); + if (trailingKeyCode === 61) { + const valueIndex = keyIndex2 + key.length + 2; + const endIndex = url.indexOf("&", valueIndex); + return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex)); + } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) { + return ""; + } + keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1); + } + encoded = /[%+]/.test(url); + if (!encoded) { + return void 0; + } + } + 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; + getQueryParams = (url, key) => { + return _getQueryParam(url, key, true); + }; + decodeURIComponent_ = decodeURIComponent; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request.js +var tryDecodeURIComponent, HonoRequest; +var init_request = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/request.js"() { + init_http_exception(); + init_constants(); + init_body(); + init_url(); + tryDecodeURIComponent = (str2) => tryDecode(str2, decodeURIComponent_); + HonoRequest = class { + /** + * `.raw` can get the raw Request object. + * + * @see {@link https://hono.dev/docs/api/request#raw} + * + * @example + * ```ts + * // For Cloudflare Workers + * app.post('/', async (c) => { + * const metadata = c.req.raw.cf?.hostMetadata? + * ... + * }) + * ``` + */ + raw; + #validatedData; + // Short name of validatedData + #matchResult; + routeIndex = 0; + /** + * `.path` can get the pathname of the request. + * + * @see {@link https://hono.dev/docs/api/request#path} + * + * @example + * ```ts + * app.get('/about/me', (c) => { + * const pathname = c.req.path // `/about/me` + * }) + * ``` + */ + path; + bodyCache = {}; + constructor(request, 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 = (key) => { + const { bodyCache, raw: raw2 } = this; + const cachedBody = bodyCache[key]; + if (cachedBody) { + return cachedBody; + } + const anyCachedKey = Object.keys(bodyCache)[0]; + if (anyCachedKey) { + return bodyCache[anyCachedKey].then((body) => { + if (anyCachedKey === "json") { + body = JSON.stringify(body); + } + return new Response(body)[key](); + }); + } + return bodyCache[key] = raw2[key](); + }; + /** + * `.json()` can parse Request body of type `application/json` + * + * @see {@link https://hono.dev/docs/api/request#json} + * + * @example + * ```ts + * app.post('/entry', async (c) => { + * const body = await c.req.json() + * }) + * ``` + */ + json() { + return this.#cachedBody("text").then((text) => JSON.parse(text)); + } + /** + * `.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; + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/html.js +var HtmlEscapedCallbackPhase, raw, resolveCallback; +var init_html = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/html.js"() { + HtmlEscapedCallbackPhase = { + Stringify: 1, + BeforeStream: 2, + Stream: 3 + }; + raw = (value, callbacks) => { + const escapedString = new String(value); + escapedString.isEscaped = true; + escapedString.callbacks = callbacks; + return escapedString; + }; + resolveCallback = async (str2, phase, preserveCallbacks, context, 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 }))).then( + (res) => Promise.all( + res.filter(Boolean).map((str22) => resolveCallback(str22, phase, false, context, buffer)) + ).then(() => buffer[0]) + ); + if (preserveCallbacks) { + return raw(await resStr, callbacks); + } else { + return resStr; + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/context.js +var TEXT_PLAIN, setDefaultContentType, createResponseInstance, Context; +var init_context = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/context.js"() { + init_request(); + init_html(); + TEXT_PLAIN = "text/plain; charset=UTF-8"; + setDefaultContentType = (contentType, headers) => { + return { + "Content-Type": contentType, + ...headers + }; + }; + createResponseInstance = (body, init) => new Response(body, init); + Context = class { + #rawRequest; + #req; + /** + * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers. + * + * @see {@link https://hono.dev/docs/api/context#env} + * + * @example + * ```ts + * // Environment object for Cloudflare Workers + * app.get('*', async c => { + * const counter = c.env.COUNTER + * }) + * ``` + */ + env = {}; + #var; + finalized = false; + /** + * `.error` can get the error object from the middleware if the Handler throws an error. + * + * @see {@link https://hono.dev/docs/api/context#error} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * await next() + * if (c.error) { + * // do something... + * } + * }) + * ``` + */ + error; + #status; + #executionCtx; + #res; + #layout; + #renderer; + #notFoundHandler; + #preparedHeaders; + #matchResult; + #path; + /** + * Creates an instance of the Context class. + * + * @param req - The Request object. + * @param options - Optional configuration options for the context. + */ + constructor(req, options) { + this.#rawRequest = req; + if (options) { + this.#executionCtx = options.executionCtx; + this.env = options.env; + this.#notFoundHandler = options.notFoundHandler; + this.#path = options.path; + this.#matchResult = options.matchResult; + } + } + /** + * `.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 = (...args) => { + this.#renderer ??= (content) => this.html(content); + return this.#renderer(...args); + }; + /** + * Sets the layout for the response. + * + * @param layout - The layout to set. + * @returns The layout function. + */ + setLayout = (layout) => this.#layout = layout; + /** + * Gets the current layout for the response. + * + * @returns The current layout function. + */ + getLayout = () => this.#layout; + /** + * `.setRenderer()` can set the layout in the custom middleware. + * + * @see {@link https://hono.dev/docs/api/context#render-setrenderer} + * + * @example + * ```tsx + * app.use('*', async (c, next) => { + * c.setRenderer((content) => { + * return c.html( + * + * + *

{content}

+ * + * + * ) + * }) + * await next() + * }) + * ``` + */ + setRenderer = (renderer) => { + this.#renderer = renderer; + }; + /** + * `.header()` can set headers. + * + * @see {@link https://hono.dev/docs/api/context#header} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * + * return c.body('Thank you for coming') + * }) + * ``` + */ + header = (name, value, options) => { + if (this.finalized) { + this.#res = createResponseInstance(this.#res.body, this.#res); + } + const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers(); + if (value === void 0) { + headers.delete(name); + } else if (options?.append) { + headers.append(name, value); + } else { + headers.set(name, value); + } + }; + status = (status) => { + this.#status = status; + }; + /** + * `.set()` can set the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.use('*', async (c, next) => { + * c.set('message', 'Hono is hot!!') + * await next() + * }) + * ``` + */ + set = (key, value) => { + this.#var ??= /* @__PURE__ */ new Map(); + this.#var.set(key, value); + }; + /** + * `.get()` can use the value specified by the key. + * + * @see {@link https://hono.dev/docs/api/context#set-get} + * + * @example + * ```ts + * app.get('/', (c) => { + * const message = c.get('message') + * return c.text(`The message is "${message}"`) + * }) + * ``` + */ + get = (key) => { + return this.#var ? this.#var.get(key) : void 0; + }; + /** + * `.var` can access the value of a variable. + * + * @see {@link https://hono.dev/docs/api/context#var} + * + * @example + * ```ts + * const result = c.var.client.oneMethod() + * ``` + */ + // c.var.propName is a read-only + get var() { + if (!this.#var) { + return {}; + } + return Object.fromEntries(this.#var); + } + #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 = (...args) => this.#newResponse(...args); + /** + * `.body()` can return the HTTP response. + * You can set headers with `.header()` and set HTTP status code with `.status`. + * This can also be set in `.text()`, `.json()` and so on. + * + * @see {@link https://hono.dev/docs/api/context#body} + * + * @example + * ```ts + * app.get('/welcome', (c) => { + * // Set headers + * c.header('X-Message', 'Hello!') + * c.header('Content-Type', 'text/plain') + * // Set HTTP status code + * c.status(201) + * + * // Return the response body + * return c.body('Thank you for coming') + * }) + * ``` + */ + body = (data, arg, headers) => this.#newResponse(data, arg, headers); + /** + * `.text()` can render text as `Content-Type:text/plain`. + * + * @see {@link https://hono.dev/docs/api/context#text} + * + * @example + * ```ts + * app.get('/say', (c) => { + * return c.text('Hello!') + * }) + * ``` + */ + text = (text, arg, headers) => { + return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse( + text, + arg, + setDefaultContentType(TEXT_PLAIN, headers) + ); + }; + /** + * `.json()` can render JSON as `Content-Type:application/json`. + * + * @see {@link https://hono.dev/docs/api/context#json} + * + * @example + * ```ts + * app.get('/api', (c) => { + * return c.json({ message: 'Hello!' }) + * }) + * ``` + */ + json = (object, arg, headers) => { + return this.#newResponse( + JSON.stringify(object), + arg, + setDefaultContentType("application/json", headers) + ); + }; + html = (html, arg, headers) => { + const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType("text/html; charset=UTF-8", headers)); + return typeof html === "object" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html); + }; + /** + * `.redirect()` can Redirect, default status code is 302. + * + * @see {@link https://hono.dev/docs/api/context#redirect} + * + * @example + * ```ts + * app.get('/redirect', (c) => { + * return c.redirect('/') + * }) + * app.get('/redirect-permanently', (c) => { + * return c.redirect('/', 301) + * }) + * ``` + */ + redirect = (location, status) => { + const locationString = String(location); + this.header( + "Location", + // Multibyes should be encoded + // eslint-disable-next-line no-control-regex + !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString) + ); + return this.newResponse(null, status ?? 302); + }; + /** + * `.notFound()` can return the Not Found Response. + * + * @see {@link https://hono.dev/docs/api/context#notfound} + * + * @example + * ```ts + * app.get('/notfound', (c) => { + * return c.notFound() + * }) + * ``` + */ + notFound = () => { + this.#notFoundHandler ??= () => createResponseInstance(); + return this.#notFoundHandler(this); + }; + }; + } +}); + +// cypher-executor/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({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router.js"() { + 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 { + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER; +var init_constants2 = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/utils/constants.js"() { + COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono-base.js +var notFoundHandler, errorHandler, Hono; +var init_hono_base = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono-base.js"() { + init_compose(); + init_context(); + init_router(); + init_constants2(); + init_url(); + notFoundHandler = (c) => { + return c.text("404 Not Found", 404); + }; + errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); + }; + Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + args.forEach((handler) => { + this.#addRoute(method, this.#path, handler); + }); + return this; + }; + }); + this.on = (method, 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 = async (c, next) => (await compose([], app2.errorHandler)(c, () => r.handler(c, next))).res; + 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 = (handler) => { + this.errorHandler = handler; + return this; + }; + /** + * `.notFound()` allows you to customize a Not Found Response. + * + * @see {@link https://hono.dev/docs/api/hono#not-found} + * + * @param {NotFoundHandler} handler - request handler for not-found + * @returns {Hono} changed Hono instance + * + * @example + * ```ts + * app.notFound((c) => { + * return c.text('Custom 404 Message', 404) + * }) + * ``` + */ + notFound = (handler) => { + this.#notFoundHandler = handler; + return this; + }; + /** + * `.mount()` allows you to mount applications built with other frameworks into your Hono application. + * + * @see {@link https://hono.dev/docs/api/hono#mount} + * + * @param {string} path - base Path + * @param {Function} applicationHandler - other Request Handler + * @param {MountOptions} [options] - options of `.mount()` + * @returns {Hono} mounted Hono instance + * + * @example + * ```ts + * import { Router as IttyRouter } from 'itty-router' + * import { Hono } from 'hono' + * // Create itty-router application + * const ittyRouter = IttyRouter() + * // GET /itty-router/hello + * ittyRouter.get('/hello', () => new Response('Hello from itty-router')) + * + * const app = new Hono() + * app.mount('/itty-router', ittyRouter.handle) + * ``` + * + * @example + * ```ts + * const app = new Hono() + * // Send the request to another application without modification. + * app.mount('/app', anotherApp, { + * replaceRequest: (req) => req, + * }) + * ``` + */ + mount(path, applicationHandler, options) { + let replaceRequest; + let optionHandler; + if (options) { + if (typeof options === "function") { + optionHandler = options; + } else { + optionHandler = options.optionHandler; + if (options.replaceRequest === false) { + replaceRequest = (request) => request; + } else { + replaceRequest = options.replaceRequest; + } + } + } + const getOptions = optionHandler ? (c) => { + const options2 = optionHandler(c); + return Array.isArray(options2) ? options2 : [options2]; + } : (c) => { + let executionContext = void 0; + try { + executionContext = c.executionCtx; + } catch { + } + return [c.env, executionContext]; + }; + replaceRequest ||= (() => { + const mergedPath = mergePath(this._basePath, 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 = async (c, next) => { + const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c)); + if (res) { + return res; + } + await next(); + }; + this.#addRoute(METHOD_NAME_ALL, mergePath(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, env, method) { + if (method === "HEAD") { + return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))(); + } + const path = this.getPath(request, { env }); + const matchResult = this.router.match(method, path); + const c = new Context(request, { + path, + matchResult, + env, + 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 context = await composed(c); + if (!context.finalized) { + throw new Error( + "Context is not finalized. Did you forget to return a Response object or `await next()`?" + ); + } + return context.res; + } catch (err) { + return this.#handleError(err, c); + } + })(); + } + /** + * `.fetch()` will be entry point of your app. + * + * @see {@link https://hono.dev/docs/api/hono#fetch} + * + * @param {Request} request - request Object of request + * @param {Env} Env - env Object + * @param {ExecutionContext} - context of execution + * @returns {Response | Promise} response of request + * + */ + fetch = (request, ...rest) => { + return this.#dispatch(request, rest[1], rest[0], request.method); + }; + /** + * `.request()` is a useful method for testing. + * You can pass a URL or pathname to send a GET request. + * app will return a Response object. + * ```ts + * test('GET /hello is ok', async () => { + * const res = await app.request('/hello') + * expect(res.status).toBe(200) + * }) + * ``` + * @see https://hono.dev/docs/api/hono#request + */ + request = (input, requestInit, Env, executionCtx) => { + if (input instanceof Request) { + return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx); + } + input = input.toString(); + return this.fetch( + new Request( + /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`, + requestInit + ), + Env, + executionCtx + ); + }; + /** + * `.fire()` automatically adds a global fetch event listener. + * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers. + * @deprecated + * Use `fire` from `hono/service-worker` instead. + * ```ts + * import { Hono } from 'hono' + * import { fire } from 'hono/service-worker' + * + * const app = new Hono() + * // ... + * fire(app) + * ``` + * @see https://hono.dev/docs/api/hono#fire + * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API + * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/ + */ + fire = () => { + addEventListener("fetch", (event) => { + event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method)); + }); + }; + }; + } +}); + +// cypher-executor/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 = (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]; + }; + this.match = match2; + return match2(method, path); +} +var emptyParam; +var init_matcher = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/matcher.js"() { + init_router(); + emptyParam = []; + } +}); + +// cypher-executor/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({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/node.js"() { + LABEL_REG_EXP_STR = "[^/]+"; + ONLY_WILDCARD_REG_EXP_STR = ".*"; + TAIL_WILDCARD_REG_EXP_STR = "(?:|/.*)"; + PATH_ERROR = /* @__PURE__ */ Symbol(); + regExpMetaChars = new Set(".\\+*[^]$()"); + Node = class _Node { + #index; + #varIndex; + #children = /* @__PURE__ */ Object.create(null); + insert(tokens, index, paramMap, context, pathErrorCheckOnly) { + if (tokens.length === 0) { + if (this.#index !== void 0) { + throw PATH_ERROR; + } + if (pathErrorCheckOnly) { + return; + } + this.#index = index; + return; + } + const [token, ...restTokens] = tokens; + const pattern = token === "*" ? restTokens.length === 0 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); + let node; + if (pattern) { + const name = pattern[1]; + let regexpStr = pattern[2] || LABEL_REG_EXP_STR; + if (name && pattern[2]) { + if (regexpStr === ".*") { + throw PATH_ERROR; + } + regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:"); + if (/\((?!\?:)/.test(regexpStr)) { + throw PATH_ERROR; + } + } + node = this.#children[regexpStr]; + if (!node) { + if (Object.keys(this.#children).some( + (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR + )) { + throw PATH_ERROR; + } + if (pathErrorCheckOnly) { + return; + } + node = this.#children[regexpStr] = new _Node(); + if (name !== "") { + node.#varIndex = context.varIndex++; + } + } + if (!pathErrorCheckOnly && name !== "") { + paramMap.push([name, node.#varIndex]); + } + } 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, context, pathErrorCheckOnly); + } + buildRegExpStr() { + const childKeys = Object.keys(this.#children).sort(compareKey); + const strList = childKeys.map((k) => { + const c = this.#children[k]; + return (typeof c.#varIndex === "number" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\${k}` : k) + c.buildRegExpStr(); + }); + if (typeof this.#index === "number") { + strList.unshift(`#${this.#index}`); + } + if (strList.length === 0) { + return ""; + } + if (strList.length === 1) { + return strList[0]; + } + return "(?:" + strList.join("|") + ")"; + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/trie.js +var Trie; +var init_trie = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/trie.js"() { + init_node(); + Trie = class { + #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]; + } + }; + } +}); + +// cypher-executor/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({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/router.js"() { + init_router(); + init_url(); + init_matcher(); + init_node(); + init_trie(); + nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)]; + wildcardRegExpCache = /* @__PURE__ */ Object.create(null); + RegExpRouter = class { + name = "RegExpRouter"; + #middleware; + #routes; + constructor() { + this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) }; + this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) }; + } + add(method, 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); + } + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/prepared-router.js +var init_prepared_router = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/prepared-router.js"() { + init_router(); + init_matcher(); + init_router2(); + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/index.js +var init_reg_exp_router = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/reg-exp-router/index.js"() { + init_router2(); + init_prepared_router(); + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/router.js +var SmartRouter; +var init_router3 = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/router.js"() { + init_router(); + SmartRouter = class { + 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]; + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/index.js +var init_smart_router = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/smart-router/index.js"() { + init_router3(); + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/node.js +var emptyParams, hasChildren, Node2; +var init_node2 = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/node.js"() { + init_router(); + init_url(); + emptyParams = /* @__PURE__ */ Object.create(null); + hasChildren = (children) => { + for (const _ in children) { + return true; + } + return false; + }; + Node2 = class _Node2 { + #methods; + #children; + #patterns; + #order = 0; + #params = emptyParams; + constructor(method, handler, children) { + this.#children = children || /* @__PURE__ */ Object.create(null); + this.#methods = []; + if (method && handler) { + const m = /* @__PURE__ */ Object.create(null); + m[method] = { handler, possibleKeys: [], score: 0 }; + this.#methods = [m]; + } + 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])]; + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/router.js +var TrieRouter; +var init_router4 = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/router.js"() { + init_url(); + init_node2(); + TrieRouter = class { + 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); + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/index.js +var init_trie_router = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/router/trie-router/index.js"() { + init_router4(); + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono.js +var Hono2; +var init_hono = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/hono.js"() { + init_hono_base(); + init_reg_exp_router(); + init_smart_router(); + init_trie_router(); + Hono2 = class extends Hono { + /** + * Creates an instance of the Hono class. + * + * @param options - Optional configuration options for the Hono instance. + */ + constructor(options = {}) { + super(options); + this.router = options.router ?? new SmartRouter({ + routers: [new RegExpRouter(), new TrieRouter()] + }); + } + }; + } +}); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/index.js +var init_dist = __esm({ + "cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/index.js"() { + init_hono(); + } +}); + +// cypher-executor/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({ + "cypher-executor/src/types.ts"() { + "use strict"; + WorkflowPaused = class extends Error { + 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 { + failed_node; + failed_input; + trace; + constructor(message, failed_node, failed_input, trace) { + super(message); + this.name = "ExecutionError"; + this.failed_node = failed_node; + this.failed_input = failed_input; + this.trace = trace; + } + }; + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/hash.ts"() { + "use strict"; + } +}); + +// cypher-executor/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(env, canonicalId) { + try { + const base = (env.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, ""); + const headers = {}; + if (env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env.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({ + "cypher-executor/src/routes/recipes.ts"() { + "use strict"; + init_dist(); + init_hash(); + recipesRouter = new Hono2(); + kIdxCanonical = (canonicalId) => `idx:canonical:${canonicalId}`; + kIdxInstalled = (canonicalId) => `idx:installed:${canonicalId}`; + 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 }); + }); + 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 versions = all.filter((r) => r.canonical_id === canonicalId); + if (author) versions = versions.filter((r) => r.author === author); + if (versions.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 = versions[0]; + let bestStat = null; + let bestScore = -1; + for (const v of versions) { + 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 }); + }); + 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 }); + }); + } +}); + +// cypher-executor/src/lib/constants.ts +var VALID_EDGE_TYPES, SEMANTIC_EDGE_MAP, BUILTIN_COMPONENTS; +var init_constants3 = __esm({ + "cypher-executor/src/lib/constants.ts"() { + "use strict"; + 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 }; + }] + ]); + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/recipe-payload.ts"() { + "use strict"; + } +}); + +// cypher-executor/src/lib/component-loader.ts +function wasmWorkerUrl(canonicalId, subdomain) { + const kebab = canonicalId.replace(/_/g, "-"); + return `https://arcrun-${kebab}.${subdomain}.workers.dev`; +} +function createComponentLoader(env) { + return async (componentId) => { + if (componentId === "trigger_workflow") { + return makeTriggerWorkflowRunner(env); + } + 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 env.WEBHOOKS.get(`idx:${componentId}`); + if (canonicalId) { + const runner = makeLogicRunner(canonicalId, env); + 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, env.RECIPES); + if (recipe) return pickRecipeRunner(recipe, env); + throw new Error(`\u627E\u4E0D\u5230 recipe hash "${componentId}"\uFF0C\u8ACB\u78BA\u8A8D\u5DF2\u900F\u904E acr push \u4E0A\u50B3`); + } + const logicRunner = makeLogicRunner(componentId, env); + if (logicRunner) return logicRunner; + const authRecipe = await resolveAuthRecipe(componentId, env.RECIPES); + if (authRecipe) return makeAuthRecipeRunner(authRecipe); + const kvRecipe = await resolveRecipe(componentId, env.RECIPES); + if (kvRecipe) return pickRecipeRunner(kvRecipe, env); + if (WASM_HTTP_RUNNER_IDS.has(componentId)) { + return makeHttpRunner(wasmWorkerUrl(componentId, env.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(env) { + 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 env.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(env, 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(env, 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, env) { + const bindingKey = LOGIC_BINDING_MAP[canonicalId]; + if (!bindingKey) return null; + const svc = env[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, env.WORKER_SUBDOMAIN)); +} +function pickRecipeRunner(recipe, env) { + return recipe.auth === "binding" ? makeBindingRecipeRunner(recipe, env) : makeRecipeRunner(recipe); +} +function makeBindingRecipeRunner(recipe, env) { + return async (ctx) => { + const ctxObj = ctx && typeof ctx === "object" ? ctx : {}; + const name = recipe.binding_name ?? "AI"; + const binding = env[name]; + if (!binding) { + 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 = binding; + 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 = (s) => s.replace( + /\{\{(auth\.)?(\w+)\}\}/g, + (_, authPrefix, k) => String(authPrefix ? authPath[k] ?? "" : ctxObj[k] ?? "") + ); + 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({ + "cypher-executor/src/lib/component-loader.ts"() { + "use strict"; + 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" + ]); + 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 才需要,因它沒大腦)。 + }; + } +}); + +// cypher-executor/src/lib/wasi-shim.ts +async function routedKvGet(env, apiKey, key) { + if (key.startsWith("auth_recipe:")) { + return env.RECIPES.get(key); + } + const credMatch = key.match(/^([^:]+):cred:.+$/); + if (credMatch) { + if (credMatch[1] !== apiKey) { + return null; + } + return env.CREDENTIALS_KV.get(key); + } + return null; +} +async function routedKvPut(env, apiKey, key, value, ttlSeconds) { + const oauth2Match = key.match(/^([^:]+):oauth2:.+$/); + if (oauth2Match && oauth2Match[1] === apiKey) { + const opts = ttlSeconds > 0 ? { expirationTtl: ttlSeconds } : void 0; + await env.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(env, ref) { + if (!/^CRED_/.test(ref)) return null; + const value = env[ref]; + return typeof value === "string" ? value : null; +} +function createArcrunHostFunctions(env, apiKey) { + return { + kv_get: (key) => routedKvGet(env, apiKey, key), + kv_put: (key, value, ttlSeconds) => routedKvPut(env, apiKey, key, value, ttlSeconds), + crypto_sign_rs256: (data, pkcs8) => rsaPkcs1Sha256Sign(data, pkcs8), + secret_get: async (ref) => secretGet(env, ref) + }; +} +var init_wasi_shim = __esm({ + "cypher-executor/src/lib/wasi-shim.ts"() { + "use strict"; + } +}); + +// cypher-executor/src/routes/kbdb-proxy.ts +function kbdbBase(env) { + const base = (env.KBDB_BASE_URL ?? "https://arcrun-kbdb.uncle6-me.workers.dev").replace(/\/$/, ""); + const headers = { "Content-Type": "application/json" }; + if (env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env.KBDB_INTERNAL_TOKEN}`; + return { base, headers }; +} +function tenant(c) { + return c.req.header("X-Arcrun-API-Key") ?? null; +} +function graphBase(env) { + if (env.KBDB_GRAPH_URL) return env.KBDB_GRAPH_URL.replace(/\/$/, ""); + return `https://kbdb-graph-plugin.${env.WORKER_SUBDOMAIN}.workers.dev`; +} +var kbdbProxyRouter, NEED_KEY; +var init_kbdb_proxy = __esm({ + "cypher-executor/src/routes/kbdb-proxy.ts"() { + "use strict"; + init_dist(); + kbdbProxyRouter = new Hono2(); + NEED_KEY = { error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }; + kbdbProxyRouter.post("/kbdb/templates", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const body = await c.req.json().catch(() => null); + if (!body || !body.name || !Array.isArray(body.slots)) { + return c.json({ error: "name \u8207 slots[] \u5FC5\u586B" }, 400); + } + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/templates`, { + method: "POST", + headers, + // created_by 帶上租戶當溯源,但 template 本身全域可見可用 + body: JSON.stringify({ name: body.name, slots: body.slots, description: body.description, created_by: owner }) + }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/templates", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/templates`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/templates/:idOrName", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/templates/${encodeURIComponent(c.req.param("idOrName"))}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.post("/kbdb/records", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const body = await c.req.json().catch(() => null); + if (!body || !body.template || !body.values) { + return c.json({ error: "template \u8207 values \u5FC5\u586B" }, 400); + } + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/records`, { + method: "POST", + headers, + // 強制以租戶身份隔離:忽略 caller 自帶 owner_id,一律用 header 身份(防跨租戶寫入) + body: JSON.stringify({ template: body.template, values: body.values, owner_id: owner }) + }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/records/by-template/:template", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const res = await fetch( + `${base}/records/by-template/${encodeURIComponent(c.req.param("template"))}?owner_id=${encodeURIComponent(owner)}`, + { headers } + ); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/records/:recordId", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/records/${encodeURIComponent(c.req.param("recordId"))}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/search", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const q = c.req.query("q"); + if (!q) return c.json({ error: "q \u5FC5\u586B" }, 400); + const { base, headers } = kbdbBase(c.env); + const params = new URLSearchParams({ q, owner_id: owner }); + for (const k of ["entry_type", "source", "library", "mode"]) { + const v = c.req.query(k); + if (v) params.set(k, v); + } + const res = await fetch(`${base}/entries/search?${params.toString()}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.post("/kbdb/entries", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const body = await c.req.json().catch(() => null); + if (!body || !body.entry_type) return c.json({ error: "entry_type \u5FC5\u586B" }, 400); + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/entries`, { + method: "POST", + headers, + // 強制以租戶身份隔離:忽略 caller 自帶 owner_id,一律用 header 身份(防跨租戶寫入) + body: JSON.stringify({ ...body, owner_id: owner }) + }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/entries", async (c) => { + const owner = tenant(c); + if (!owner) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const params = new URLSearchParams(); + params.set("owner_id", owner); + for (const k of ["entry_type", "parent_id", "page_name", "source", "library", "limit", "offset"]) { + const v = c.req.query(k); + if (v) params.set(k, v); + } + const q = c.req.query("q") || c.req.query("search"); + if (q) params.set("q", q); + const res = await fetch(`${base}/entries?${params.toString()}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/entries/:id", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/entries/${encodeURIComponent(c.req.param("id"))}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + kbdbProxyRouter.get("/kbdb/graph/neighbors/:name", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const base = graphBase(c.env); + const headers = {}; + if (c.env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${c.env.KBDB_INTERNAL_TOKEN}`; + try { + const res = await fetch(`${base}/graph/neighbors/${encodeURIComponent(c.req.param("name"))}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + } catch (e) { + return c.json({ error: `kbdb-graph-plugin \u4E0D\u53EF\u9054\uFF08${base}\uFF09\uFF1A${e instanceof Error ? e.message : String(e)}` }, 502); + } + }); + kbdbProxyRouter.get("/kbdb/map", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const owner = c.req.query("owner_id"); + const qs = owner ? `?owner_id=${encodeURIComponent(owner)}` : ""; + try { + const res = await fetch(`${base}/map${qs}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + } catch (e) { + return c.json({ success: false, error: `KBDB \u4E0D\u53EF\u9054\uFF08${base}\uFF09\uFF1A${e instanceof Error ? e.message : String(e)}` }, 502); + } + }); + kbdbProxyRouter.get("/kbdb/map/:library", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const { base, headers } = kbdbBase(c.env); + const owner = c.req.query("owner_id"); + const qs = owner ? `?owner_id=${encodeURIComponent(owner)}` : ""; + try { + const res = await fetch(`${base}/map/${encodeURIComponent(c.req.param("library"))}${qs}`, { headers }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + } catch (e) { + return c.json({ success: false, error: `KBDB \u4E0D\u53EF\u9054\uFF08${base}\uFF09\uFF1A${e instanceof Error ? e.message : String(e)}` }, 502); + } + }); + kbdbProxyRouter.patch("/kbdb/entries/:id", async (c) => { + if (!tenant(c)) return c.json(NEED_KEY, 401); + const body = await c.req.json().catch(() => ({})); + const { owner_id: _drop, ...patch } = body ?? {}; + const { base, headers } = kbdbBase(c.env); + const res = await fetch(`${base}/entries/${encodeURIComponent(c.req.param("id"))}`, { + method: "PATCH", + headers, + body: JSON.stringify(patch) + }); + return new Response(res.body, { status: res.status, headers: { "Content-Type": "application/json" } }); + }); + } +}); + +// cypher-executor/src/routes/credentials.ts +async function deriveSecretRef(apiKey, name) { + const hash8 = await sha256Prefix(apiKey); + return `CRED_${name.toUpperCase()}_${hash8.toUpperCase()}`; +} +async function storeCredential(env, apiKey, name, value, service) { + const secretRef = await deriveSecretRef(apiKey, name); + await putWorkerSecret(env, secretRef, value); + await upsertCredentialEntry(env, apiKey, name, service, "standard", secretRef); +} +function validateName(name) { + return typeof name === "string" && /^\w+$/.test(name); +} +function validSensitivity(s) { + return s === "standard" || s === "high"; +} +async function putWorkerSecret(env, secretRef, value) { + if (!env.CF_SECRETS_API_TOKEN || !env.CF_ACCOUNT_ID) { + throw new Error( + "\u6B64 worker \u7F3A CF_SECRETS_API_TOKEN / CF_ACCOUNT_ID \u8A2D\u5B9A\uFF0C\u5BEB\u5165\u8DEF\u5F91\u672A\u5C31\u7DD2\uFF08\u898B credential-store-migration.md T3\uFF1Aacr init/update \u61C9\u78BA\u4FDD\u9019\u5169\u9805\u5C31\u7DD2\uFF09" + ); + } + const url = `https://api.cloudflare.com/client/v4/accounts/${env.CF_ACCOUNT_ID}/workers/scripts/${CYPHER_SCRIPT_NAME}/secrets`; + const res = await fetch(url, { + method: "PUT", + headers: { + Authorization: `Bearer ${env.CF_SECRETS_API_TOKEN}`, + "Content-Type": "application/json" + }, + body: JSON.stringify({ name: secretRef, text: value, type: "secret_text" }) + }); + const body = await res.json().catch(() => null); + if (!res.ok || !body?.success) { + const detail = body?.errors?.map((e) => e.message).filter(Boolean).join("; ") || `HTTP ${res.status}`; + throw new Error(`CF Workers Secrets \u5BEB\u5165\u5931\u6557\uFF1A${detail}`); + } +} +async function deleteWorkerSecret(env, secretRef) { + if (!env.CF_SECRETS_API_TOKEN || !env.CF_ACCOUNT_ID) { + throw new Error("\u6B64 worker \u7F3A CF_SECRETS_API_TOKEN / CF_ACCOUNT_ID \u8A2D\u5B9A\uFF0C\u522A\u9664\u8DEF\u5F91\u672A\u5C31\u7DD2"); + } + const url = `https://api.cloudflare.com/client/v4/accounts/${env.CF_ACCOUNT_ID}/workers/scripts/${CYPHER_SCRIPT_NAME}/secrets/${secretRef}`; + const res = await fetch(url, { + method: "DELETE", + headers: { Authorization: `Bearer ${env.CF_SECRETS_API_TOKEN}` } + }); + if (res.status === 404) return; + const body = await res.json().catch(() => null); + if (!res.ok || !body?.success) { + const detail = body?.errors?.map((e) => e.message).filter(Boolean).join("; ") || `HTTP ${res.status}`; + throw new Error(`CF Workers Secrets \u522A\u9664\u5931\u6557\uFF1A${detail}`); + } +} +function parseMeta(row) { + try { + const m = row.metadata_json ? JSON.parse(row.metadata_json) : {}; + return { + service: typeof m.service === "string" ? m.service : null, + sensitivity: m.sensitivity === "high" ? "high" : "standard", + secret_ref: typeof m.secret_ref === "string" ? m.secret_ref : "", + last_used_at: typeof m.last_used_at === "number" ? m.last_used_at : null + }; + } catch { + return { service: null, sensitivity: "standard", secret_ref: "", last_used_at: null }; + } +} +async function kbdbCredFetch(env, path, init) { + const { base, headers } = kbdbBase(env); + return fetch(`${base}${path}`, { + ...init, + headers: { ...headers, ...init?.headers } + }); +} +function invalidateCredentialCache(apiKey) { + delete dirCache[apiKey]; +} +async function getCredentialDirectory(env, apiKey) { + const now2 = Date.now(); + const cached = dirCache[apiKey]; + if (cached && now2 - cached.fetchedAt < DIR_CACHE_TTL_MS) return cached.rows; + const qs = new URLSearchParams({ owner_id: apiKey, entry_type: CREDENTIAL_ENTRY_TYPE, limit: "200" }); + const res = await kbdbCredFetch(env, `/entries?${qs.toString()}`); + if (!res.ok) { + return []; + } + const body = await res.json().catch(() => null); + const rows = (body?.entries ?? []).filter((e) => !!e.page_name).map((e) => { + const meta = parseMeta(e); + return { + id: e.id, + name: e.page_name, + secret_ref: meta.secret_ref, + service: meta.service, + sensitivity: meta.sensitivity, + last_used_at: meta.last_used_at + }; + }); + dirCache[apiKey] = { rows, fetchedAt: now2 }; + return rows; +} +async function getCredentialSecretRefs(env, apiKey) { + const rows = await getCredentialDirectory(env, apiKey); + const out = {}; + for (const r of rows) { + if (r.secret_ref) out[r.name] = r.secret_ref; + } + return out; +} +function touchLastUsed(env, apiKey, names) { + const cached = dirCache[apiKey]; + if (!cached || names.length === 0) return; + const now2 = Math.floor(Date.now() / 1e3); + for (const r of cached.rows) { + if (!names.includes(r.name)) continue; + const meta = { + service: r.service, + sensitivity: r.sensitivity, + secret_ref: r.secret_ref, + last_used_at: now2 + }; + kbdbCredFetch(env, `/entries/${encodeURIComponent(r.id)}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ metadata_json: JSON.stringify(meta) }) + }).catch(() => { + }); + r.last_used_at = now2; + } +} +async function findCredentialEntry(env, apiKey, name) { + const qs = new URLSearchParams({ + owner_id: apiKey, + entry_type: CREDENTIAL_ENTRY_TYPE, + page_name: name, + limit: "1" + }); + const res = await kbdbCredFetch(env, `/entries?${qs.toString()}`); + if (!res.ok) throw new Error(`KBDB /entries \u67E5\u8A62\u5931\u6557\uFF1AHTTP ${res.status}`); + const body = await res.json().catch(() => null); + return body?.entries?.[0] ?? null; +} +async function upsertCredentialEntry(env, apiKey, name, service, sensitivity, secretRef) { + const existing = await findCredentialEntry(env, apiKey, name); + const meta = { + service, + sensitivity, + secret_ref: secretRef, + last_used_at: existing ? parseMeta(existing).last_used_at : null + }; + if (existing) { + const res = await kbdbCredFetch(env, `/entries/${encodeURIComponent(existing.id)}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ metadata_json: JSON.stringify(meta) }) + }); + if (!res.ok) throw new Error(`credential \u76EE\u9304\u66F4\u65B0\u5931\u6557\uFF1AHTTP ${res.status}`); + } else { + const res = await kbdbCredFetch(env, `/entries`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + entry_type: CREDENTIAL_ENTRY_TYPE, + owner_id: apiKey, + page_name: name, + metadata_json: JSON.stringify(meta) + }) + }); + if (!res.ok) throw new Error(`credential \u76EE\u9304\u5EFA\u7ACB\u5931\u6557\uFF1AHTTP ${res.status}`); + } + invalidateCredentialCache(apiKey); +} +async function listCredentialRows(env, apiKey) { + const qs = new URLSearchParams({ owner_id: apiKey, entry_type: CREDENTIAL_ENTRY_TYPE, limit: "200" }); + const res = await kbdbCredFetch(env, `/entries?${qs.toString()}`); + if (!res.ok) throw new Error(`credential \u76EE\u9304\u67E5\u8A62\u5931\u6557\uFF1AHTTP ${res.status}`); + const body = await res.json().catch(() => null); + const rows = (body?.entries ?? []).filter((e) => !!e.page_name).map((e) => { + const meta = parseMeta(e); + return { name: e.page_name, service: meta.service, sensitivity: meta.sensitivity, created_at: e.created_at, last_used_at: meta.last_used_at }; + }); + return rows; +} +async function hasCredential(env, apiKey, name) { + const entry = await findCredentialEntry(env, apiKey, name); + return entry !== null; +} +async function writeCredential(env, apiKey, name, value, service, sensitivityRaw) { + const sensitivity = validSensitivity(sensitivityRaw) ? sensitivityRaw : "standard"; + const secretRef = await deriveSecretRef(apiKey, name); + await putWorkerSecret(env, secretRef, value); + await upsertCredentialEntry(env, apiKey, name, service ?? null, sensitivity, secretRef); + return { secretRef, sensitivity }; +} +var credentialsRouter, CYPHER_SCRIPT_NAME, CREDENTIAL_ENTRY_TYPE, DIR_CACHE_TTL_MS, dirCache; +var init_credentials = __esm({ + "cypher-executor/src/routes/credentials.ts"() { + "use strict"; + init_dist(); + init_hash(); + init_kbdb_proxy(); + credentialsRouter = new Hono2(); + CYPHER_SCRIPT_NAME = "arcrun-cypher-executor"; + CREDENTIAL_ENTRY_TYPE = "credential"; + DIR_CACHE_TTL_MS = 6e4; + dirCache = {}; + credentialsRouter.post("/credentials", async (c) => { + const apiKey = c.req.header("X-Arcrun-API-Key"); + if (!apiKey) { + return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401); + } + const body = await c.req.json().catch(() => null); + if (!validateName(body?.name)) { + return c.json({ error: "name \u5FC5\u586B\uFF0C\u53EA\u80FD\u5305\u542B\u82F1\u6587\u5B57\u6BCD\u3001\u6578\u5B57\u548C\u5E95\u7DDA" }, 400); + } + if (!body?.value || typeof body.value !== "string") { + return c.json({ error: "value \u5FC5\u586B\uFF08credential \u660E\u6587\u503C\uFF0C\u7D93 TLS \u50B3\u8F38\uFF09" }, 400); + } + try { + const { secretRef, sensitivity } = await writeCredential( + c.env, + apiKey, + body.name, + body.value, + body.service, + body.sensitivity + ); + return c.json({ success: true, name: body.name, service: body.service ?? null, sensitivity, secret_ref: secretRef }); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 502); + } + }); + credentialsRouter.put("/credentials/:name", async (c) => { + const apiKey = c.req.header("X-Arcrun-API-Key"); + if (!apiKey) { + return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401); + } + const name = c.req.param("name"); + if (!validateName(name)) { + return c.json({ error: "name \u53EA\u80FD\u5305\u542B\u82F1\u6587\u5B57\u6BCD\u3001\u6578\u5B57\u548C\u5E95\u7DDA" }, 400); + } + const body = await c.req.json().catch(() => null); + if (!body?.value || typeof body.value !== "string") { + return c.json({ error: "value \u5FC5\u586B\uFF08credential \u660E\u6587\u503C\uFF0C\u7D93 TLS \u50B3\u8F38\uFF09" }, 400); + } + try { + const { secretRef, sensitivity } = await writeCredential( + c.env, + apiKey, + name, + body.value, + body.service, + body.sensitivity + ); + return c.json({ success: true, name, service: body.service ?? null, sensitivity, secret_ref: secretRef }); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 502); + } + }); + credentialsRouter.delete("/credentials/:name", async (c) => { + const apiKey = c.req.header("X-Arcrun-API-Key"); + if (!apiKey) { + return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401); + } + const name = c.req.param("name"); + try { + const entry = await findCredentialEntry(c.env, apiKey, name); + if (entry) { + const meta = parseMeta(entry); + if (meta.secret_ref) await deleteWorkerSecret(c.env, meta.secret_ref); + const res = await kbdbCredFetch(c.env, `/entries/${encodeURIComponent(entry.id)}`, { method: "DELETE" }); + if (!res.ok) throw new Error(`credential \u76EE\u9304\u522A\u9664\u5931\u6557\uFF1AHTTP ${res.status}`); + invalidateCredentialCache(apiKey); + return c.json({ success: true, name, source: "workers-secrets" }); + } + await c.env.CREDENTIALS_KV.delete(`${apiKey}:cred:${name}`); + return c.json({ success: true, name, source: "legacy-kv" }); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 502); + } + }); + credentialsRouter.get("/credentials/catalog", async (c) => { + const apiKey = c.req.header("X-Arcrun-API-Key"); + if (!apiKey) { + return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401); + } + try { + const rows = await listCredentialRows(c.env, apiKey); + return c.json({ success: true, credentials: rows, total: rows.length }); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 502); + } + }); + credentialsRouter.get("/credentials", async (c) => { + const apiKey = c.req.header("X-Arcrun-API-Key"); + if (!apiKey) { + return c.json({ error: "\u7F3A\u5C11 X-Arcrun-API-Key header" }, 401); + } + try { + const rows = await listCredentialRows(c.env, apiKey); + return c.json({ success: true, credentials: rows, total: rows.length }); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 502); + } + }); + } +}); + +// cypher-executor/src/actions/auth-dispatcher.ts +async function resolveSecretsFromNewHome(env, apiKey, names) { + const resolved = {}; + if (names.length === 0) return resolved; + const refs = await getCredentialSecretRefs(env, apiKey); + if (Object.keys(refs).length === 0) return resolved; + const secretGet2 = createArcrunHostFunctions(env, apiKey).secret_get; + if (!secretGet2) return resolved; + const resolvedNames = []; + for (const name of names) { + const ref = refs[name]; + if (!ref) continue; + const value = await secretGet2(ref); + if (value === null) continue; + resolved[name] = value; + resolvedNames.push(name); + } + if (resolvedNames.length > 0) touchLastUsed(env, apiKey, resolvedNames); + return resolved; +} +async function tryAuthDispatch(componentId, input, env, apiKey) { + if (AUTH_PRIMITIVE_IDS.has(componentId)) { + return null; + } + let service = componentId; + const apiRecipe = await resolveRecipe(componentId, env.RECIPES); + if (apiRecipe?.auth_service) { + service = apiRecipe.auth_service; + } + const recipe = await resolveAuthRecipe(service, env.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(env, apiKey, secretNames); + const primitiveUrl = wasmWorkerUrl(`auth_${recipe.primitive}`, env.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, env, apiKey) { + const names = /* @__PURE__ */ new Set(); + collectCredentialNames(data, names); + if (names.size === 0) return data; + const nameList = [...names]; + const resolvedSecrets = await resolveSecretsFromNewHome(env, apiKey, nameList); + const url = wasmWorkerUrl("auth_static_key", env.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({ + "cypher-executor/src/actions/auth-dispatcher.ts"() { + "use strict"; + init_recipes(); + init_component_loader(); + init_wasi_shim(); + init_credentials(); + 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" + ]); + CREDENTIAL_REF = /\{\{credential\.(\w+)\}\}/g; + } +}); + +// cypher-executor/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 = (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 }; + }; + 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, version) { + if ((version === "v4" || !version) && ipv4Regex.test(ip)) { + return true; + } + if ((version === "v6" || !version) && 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: () => newShape + }); + } else if (schema instanceof ZodArray) { + return new ZodArray({ + ...schema._def, + type: deepPartialify(schema.element) + }); + } else if (schema instanceof ZodOptional) { + return ZodOptional.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodNullable) { + return ZodNullable.create(deepPartialify(schema.unwrap())); + } else if (schema instanceof ZodTuple) { + return ZodTuple.create(schema.items.map((item) => deepPartialify(item))); + } else { + return schema; + } +} +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({ + "cypher-executor/node_modules/.pnpm/zod@3.23.8/node_modules/zod/lib/index.mjs"() { + (function(util2) { + util2.assertEqual = (val) => val; + function assertIs(_arg) { + } + util2.assertIs = assertIs; + function assertNever(_x) { + throw new Error(); + } + util2.assertNever = assertNever; + util2.arrayToEnum = (items) => { + const obj = {}; + for (const item of items) { + obj[item] = item; + } + return obj; + }; + util2.getValidEnumValues = (obj) => { + const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number"); + const filtered = {}; + for (const k of validKeys) { + filtered[k] = obj[k]; + } + return util2.objectValues(filtered); + }; + util2.objectValues = (obj) => { + return util2.objectKeys(obj).map(function(e) { + return obj[e]; + }); + }; + util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (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); + } + 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 = (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; + } + }; + 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 = (obj) => { + const json = JSON.stringify(obj, null, 2); + return json.replace(/"([^"]+)":/g, "$1:"); + }; + ZodError = class _ZodError extends Error { + 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 = (error) => { + for (const issue of error.issues) { + if (issue.code === "invalid_union") { + issue.unionErrors.map(processError); + } else if (issue.code === "invalid_return_type") { + processError(issue.returnTypeError); + } else if (issue.code === "invalid_arguments") { + processError(issue.argumentsError); + } else if (issue.path.length === 0) { + fieldErrors._errors.push(mapper(issue)); + } else { + let curr = fieldErrors; + let i = 0; + while (i < issue.path.length) { + const el = issue.path[i]; + const terminal = i === issue.path.length - 1; + if (!terminal) { + curr[el] = curr[el] || { _errors: [] }; + } else { + curr[el] = curr[el] || { _errors: [] }; + curr[el]._errors.push(mapper(issue)); + } + curr = curr[el]; + i++; + } + } + } + }; + processError(this); + return fieldErrors; + } + static 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 error = new ZodError(issues); + return error; + }; + errorMap = (issue, _ctx) => { + let message; + switch (issue.code) { + case ZodIssueCode.invalid_type: + if (issue.received === ZodParsedType.undefined) { + message = "Required"; + } else { + message = `Expected ${issue.expected}, received ${issue.received}`; + } + break; + case ZodIssueCode.invalid_literal: + message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`; + break; + case ZodIssueCode.unrecognized_keys: + message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`; + break; + case ZodIssueCode.invalid_union: + message = `Invalid input`; + break; + case ZodIssueCode.invalid_union_discriminator: + message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`; + break; + case ZodIssueCode.invalid_enum_value: + message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`; + break; + case ZodIssueCode.invalid_arguments: + message = `Invalid function arguments`; + break; + case ZodIssueCode.invalid_return_type: + message = `Invalid function return type`; + break; + case ZodIssueCode.invalid_date: + message = `Invalid date`; + break; + case ZodIssueCode.invalid_string: + if (typeof issue.validation === "object") { + if ("includes" in issue.validation) { + message = `Invalid input: must include "${issue.validation.includes}"`; + if (typeof issue.validation.position === "number") { + message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`; + } + } 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 }; + }; + overrideErrorMap = errorMap; + makeIssue = (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 + }; + }; + EMPTY_PATH = []; + ParseStatus = class _ParseStatus { + constructor() { + this.value = "valid"; + } + dirty() { + if (this.value === "valid") + this.value = "dirty"; + } + abort() { + if (this.value !== "aborted") + this.value = "aborted"; + } + static mergeArray(status, results) { + const arrayValue = []; + for (const s of results) { + if (s.status === "aborted") + return INVALID; + if (s.status === "dirty") + status.dirty(); + arrayValue.push(s.value); + } + return { status: status.value, value: arrayValue }; + } + static async mergeObjectAsync(status, pairs) { + const syncPairs = []; + for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; + syncPairs.push({ + key, + value + }); + } + return _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 = (value) => ({ status: "dirty", value }); + OK = (value) => ({ status: "valid", value }); + isAborted = (x) => x.status === "aborted"; + isDirty = (x) => x.status === "dirty"; + isValid = (x) => x.status === "valid"; + isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise; + (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 { + 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 = (ctx, result) => { + if (isValid(result)) { + return { success: true, data: result.value }; + } else { + if (!ctx.common.issues.length) { + throw new Error("Validation failed but no issues detected."); + } + return { + success: false, + get error() { + if (this._error) + return this._error; + const error = new ZodError(ctx.common.issues); + this._error = error; + return this._error; + } + }; + } + }; + ZodType = class { + 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 = (val) => { + if (typeof message === "string" || typeof message === "undefined") { + return { message }; + } else if (typeof message === "function") { + return message(val); + } else { + return message; + } + }; + return this._refinement((val, ctx) => { + const result = check(val); + const setError = () => ctx.addIssue({ + code: ZodIssueCode.custom, + ...getIssueProperties(val) + }); + if (typeof Promise !== "undefined" && result instanceof Promise) { + return result.then((data) => { + if (!data) { + setError(); + return false; + } else { + return true; + } + }); + } + if (!result) { + setError(); + return false; + } else { + return true; + } + }); + } + 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}$`); + ZodString = class _ZodString extends ZodType { + _parse(input) { + if (this._def.coerce) { + input.data = String(input.data); + } + const parsedType = this._getType(input); + if (parsedType !== ZodParsedType.string) { + const ctx2 = this._getOrReturnCtx(input); + addIssueToContext(ctx2, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.string, + received: ctx2.parsedType + }); + return INVALID; + } + const status = new ParseStatus(); + let ctx = void 0; + for (const check of this._def.checks) { + if (check.kind === "min") { + if (input.data.length < check.value) { + ctx = this._getOrReturnCtx(input, ctx); + addIssueToContext(ctx, { + code: ZodIssueCode.too_small, + minimum: check.value, + type: "string", + inclusive: true, + exact: false, + message: check.message + }); + status.dirty(); + } + } 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) + }); + }; + ZodNumber = class _ZodNumber extends ZodType { + 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 { + 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 { + _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 { + _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 { + _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 { + _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 { + _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 { + 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 { + 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 { + _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 { + _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 { + _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) + }); + }; + ZodObject = class _ZodObject extends ZodType { + constructor() { + super(...arguments); + this._cached = null; + this.nonstrict = this.passthrough; + this.augment = this.extend; + } + _getCached() { + if (this._cached !== null) + return this._cached; + const shape = this._def.shape(); + const keys = util.objectKeys(shape); + 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: (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 + }; + } + } : {} + }); + } + 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: () => ({ + ...this._def.shape(), + ...augmentation + }) + }); + } + /** + * Prior to zod@1.0.12 there was a bug in the + * inferred type of merged objects. Please + * upgrade if you are experiencing issues. + */ + merge(merging) { + const merged = new _ZodObject({ + unknownKeys: merging._def.unknownKeys, + catchall: merging._def.catchall, + shape: () => ({ + ...this._def.shape(), + ...merging._def.shape() + }), + typeName: ZodFirstPartyTypeKind.ZodObject + }); + return merged; + } + // 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: () => 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: () => 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: () => newShape + }); + } + 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: () => newShape + }); + } + keyof() { + return createZodEnum(util.objectKeys(this.shape)); + } + }; + ZodObject.create = (shape, params) => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + ZodObject.strictCreate = (shape, params) => { + return new ZodObject({ + shape: () => shape, + unknownKeys: "strict", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + ZodObject.lazycreate = (shape, params) => { + return new ZodObject({ + shape, + unknownKeys: "strip", + catchall: ZodNever.create(), + typeName: ZodFirstPartyTypeKind.ZodObject, + ...processCreateParams(params) + }); + }; + ZodUnion = class extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + const options = this._def.options; + function handleResults(results) { + for (const result of results) { + if (result.result.status === "valid") { + return result.result; + } + } + for (const result of results) { + if (result.result.status === "dirty") { + ctx.common.issues.push(...result.ctx.common.issues); + return result.result; + } + } + const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues)); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union, + unionErrors + }); + return INVALID; + } + 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 = (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 []; + } + }; + ZodDiscriminatedUnion = class _ZodDiscriminatedUnion extends ZodType { + _parse(input) { + const { ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.object) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.object, + received: ctx.parsedType + }); + return INVALID; + } + const 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) + }); + } + }; + ZodIntersection = class extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const handleParsed = (parsedLeft, parsedRight) => { + if (isAborted(parsedLeft) || isAborted(parsedRight)) { + return INVALID; + } + const merged = mergeValues(parsedLeft.value, parsedRight.value); + if (!merged.valid) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_intersection_types + }); + return INVALID; + } + if (isDirty(parsedLeft) || isDirty(parsedRight)) { + status.dirty(); + } + return { status: status.value, value: merged.data }; + }; + if (ctx.common.async) { + return Promise.all([ + this._def.left._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), + this._def.right._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }) + ]).then(([left, right]) => handleParsed(left, right)); + } else { + return handleParsed(this._def.left._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }), this._def.right._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + })); + } + } + }; + ZodIntersection.create = (left, right, params) => { + return new ZodIntersection({ + left, + right, + typeName: ZodFirstPartyTypeKind.ZodIntersection, + ...processCreateParams(params) + }); + }; + ZodTuple = class _ZodTuple extends ZodType { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.parsedType !== ZodParsedType.array) { + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_type, + expected: ZodParsedType.array, + received: ctx.parsedType + }); + return INVALID; + } + 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 { + 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 { + 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 { + _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 }; + } + 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 { + 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, error) { + return makeIssue({ + data: args, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + ctx.schemaErrorMap, + getErrorMap(), + errorMap + ].filter((x) => !!x), + issueData: { + code: ZodIssueCode.invalid_arguments, + argumentsError: error + } + }); + } + function makeReturnsIssue(returns, error) { + return makeIssue({ + data: returns, + path: ctx.path, + errorMaps: [ + ctx.common.contextualErrorMap, + ctx.schemaErrorMap, + getErrorMap(), + errorMap + ].filter((x) => !!x), + issueData: { + code: ZodIssueCode.invalid_return_type, + returnTypeError: error + } + }); + } + const params = { errorMap: ctx.common.contextualErrorMap }; + const fn = ctx.data; + if (this._def.returns instanceof ZodPromise) { + const me = this; + return OK(async function(...args) { + const error = new ZodError([]); + const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => { + error.addIssue(makeArgsIssue(args, e)); + throw error; + }); + const result = await Reflect.apply(fn, this, parsedArgs); + const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => { + error.addIssue(makeReturnsIssue(result, e)); + throw error; + }); + return parsedReturns; + }); + } else { + const me = this; + return OK(function(...args) { + const parsedArgs = me._def.args.safeParse(args, params); + if (!parsedArgs.success) { + throw new ZodError([makeArgsIssue(args, parsedArgs.error)]); + } + const result = Reflect.apply(fn, this, parsedArgs.data); + const parsedReturns = me._def.returns.safeParse(result, params); + if (!parsedReturns.success) { + throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]); + } + return parsedReturns.data; + }); + } + } + 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 { + 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 { + _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) + }); + }; + ZodEnum = class _ZodEnum extends ZodType { + 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 { + 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 { + 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 { + innerType() { + return this._def.schema; + } + sourceType() { + return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema; + } + _parse(input) { + const { status, ctx } = this._processInputParams(input); + const effect = this._def.effect || null; + const checkCtx = { + addIssue: (arg) => { + addIssueToContext(ctx, arg); + if (arg.fatal) { + status.abort(); + } else { + status.dirty(); + } + }, + get path() { + return ctx.path; + } + }; + checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); + if (effect.type === "preprocess") { + const processed = effect.transform(ctx.data, checkCtx); + if (ctx.common.async) { + return Promise.resolve(processed).then(async (processed2) => { + if (status.value === "aborted") + return INVALID; + const result = await this._def.schema._parseAsync({ + data: processed2, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") + return INVALID; + if (result.status === "dirty") + return DIRTY(result.value); + if (status.value === "dirty") + return DIRTY(result.value); + return result; + }); + } else { + if (status.value === "aborted") + return INVALID; + const result = this._def.schema._parseSync({ + data: processed, + path: ctx.path, + parent: ctx + }); + if (result.status === "aborted") + return INVALID; + if (result.status === "dirty") + return DIRTY(result.value); + if (status.value === "dirty") + return DIRTY(result.value); + return result; + } + } + if (effect.type === "refinement") { + const executeRefinement = (acc) => { + const result = effect.refinement(acc, checkCtx); + if (ctx.common.async) { + return Promise.resolve(result); + } + if (result instanceof Promise) { + throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead."); + } + return acc; + }; + if (ctx.common.async === false) { + const inner = this._def.schema._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inner.status === "aborted") + return INVALID; + if (inner.status === "dirty") + status.dirty(); + executeRefinement(inner.value); + return { status: status.value, value: inner.value }; + } else { + return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => { + if (inner.status === "aborted") + return INVALID; + if (inner.status === "dirty") + status.dirty(); + return executeRefinement(inner.value).then(() => { + return { status: status.value, value: inner.value }; + }); + }); + } + } + 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 { + _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 { + _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 { + _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 { + _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 { + _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 { + _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 { + _parse(input) { + const { status, ctx } = this._processInputParams(input); + if (ctx.common.async) { + const handleAsync = async () => { + const inResult = await this._def.in._parseAsync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") + return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return DIRTY(inResult.value); + } else { + return this._def.out._parseAsync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + }; + return handleAsync(); + } else { + const inResult = this._def.in._parseSync({ + data: ctx.data, + path: ctx.path, + parent: ctx + }); + if (inResult.status === "aborted") + return INVALID; + if (inResult.status === "dirty") { + status.dirty(); + return { + status: "dirty", + value: inResult.value + }; + } else { + return this._def.out._parseSync({ + data: inResult.value, + path: ctx.path, + parent: ctx + }); + } + } + } + static create(a, b) { + return new _ZodPipeline({ + in: a, + out: b, + typeName: ZodFirstPartyTypeKind.ZodPipeline + }); + } + }; + ZodReadonly = class extends ZodType { + _parse(input) { + const result = this._def.innerType._parse(input); + const freeze = (data) => { + if (isValid(data)) { + data.value = Object.freeze(data.value); + } + return data; + }; + return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result); + } + unwrap() { + return this._def.innerType; + } + }; + ZodReadonly.create = (type, params) => { + return new ZodReadonly({ + innerType: type, + typeName: ZodFirstPartyTypeKind.ZodReadonly, + ...processCreateParams(params) + }); + }; + 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 = (cls, params = { + message: `Input not instance of ${cls.name}` + }) => custom((data) => data instanceof cls, params); + 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 = () => stringType().optional(); + onumber = () => numberType().optional(); + oboolean = () => booleanType().optional(); + coerce = { + string: (arg) => ZodString.create({ ...arg, coerce: true }), + number: (arg) => ZodNumber.create({ ...arg, coerce: true }), + boolean: (arg) => ZodBoolean.create({ + ...arg, + coerce: true + }), + bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }), + date: (arg) => ZodDate.create({ ...arg, coerce: true }) + }; + 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 + }); + } +}); + +// cypher-executor/src/lib/prompt-recipe-schema.ts +var TransformSchema, KBDBBlockFragmentSchema, KVFragmentSchema, FragmentSchema, InputSchema, PromptAssemblySchema, OutputSpecSchema, PromptRecipeSchema; +var init_prompt_recipe_schema = __esm({ + "cypher-executor/src/lib/prompt-recipe-schema.ts"() { + "use strict"; + 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" }) + }); + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/recipe-loader.ts"() { + "use strict"; + init_prompt_recipe_schema(); + RecipeLoadError = class extends Error { + constructor(message, recipe) { + super(message); + this.recipe = recipe; + } + }; + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/recipe-transforms.ts"() { + "use strict"; + transforms = { + json_array: (v) => JSON.stringify(v ?? []), + to_string: (v) => { + if (v === null || v === void 0) return ""; + if (typeof v === "object") return JSON.stringify(v); + return String(v); + }, + join: (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"); + }, + markdown_list: (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"); + }, + extract_field: (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); + }, + first: (v) => { + if (!Array.isArray(v)) return v; + return v[0]; + }, + pluck_content: (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"); + } + }; + } +}); + +// cypher-executor/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(env, apiKey, fragment) { + const base = (env.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(env, apiKey, frag) { + if (frag.source === "kv") { + const val = await env.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(env, 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, env, apiKey) { + const recipe = await loadPromptRecipe(recipeRef, env.RECIPES); + const vars = {}; + for (const frag of recipe.fragments) { + const { var: name, value } = await resolveFragment(env, 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({ + "cypher-executor/src/lib/recipe-expander.ts"() { + "use strict"; + init_recipe_loader(); + init_recipe_transforms(); + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/paused-runs.ts"() { + "use strict"; + KEY_PREFIX = "paused_run:"; + IDX_PREFIX = "paused_idx:"; + TTL_SECONDS = 24 * 60 * 60; + } +}); + +// cypher-executor/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({ + "cypher-executor/src/lib/magic-vars.ts"() { + "use strict"; + } +}); + +// cypher-executor/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(env) { + const subdomain = env.WORKER_SUBDOMAIN || "uncle6-me"; + return `https://arcrun-kbdb-create-block.${subdomain}.workers.dev`; +} +function recordTelemetry(env, apiKey, record, ctx) { + const promise = (async () => { + try { + const api_key_hash = await hashApiKey(apiKey ?? ""); + const platformKey = env.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(env), { + 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({ + "cypher-executor/src/lib/telemetry.ts"() { + "use strict"; + } +}); + +// cypher-executor/src/graph-executor.ts +function propagateCtx(context, upstreamResult, upstreamNodeId) { + const baseCtx = typeof context === "object" && context !== null ? context : {}; + 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, context) { + if (!context || typeof context !== "object") return false; + const ctx = context; + 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(context, key) { + if (!context || typeof context !== "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 = context; + 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({ + "cypher-executor/src/graph-executor.ts"() { + "use strict"; + init_types(); + init_auth_dispatcher(); + init_recipe_expander(); + init_recipes(); + init_paused_runs(); + init_magic_vars(); + init_telemetry(); + GraphExecutor = class _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, env, apiKey) { + this.loader = loader; + this.workflowLoader = workflowLoader; + this.env = env; + this.apiKey = apiKey; + } + async execute(graph, initialContext, kvNamespace) { + const trace = []; + 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 }; + } + 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(), trace, 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 }; + } + /** + * 從 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 trace = [...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 }; + } + 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, trace, 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 }; + } + async executeNode(node, graph, context, visited, trace, fanIn, kvStore) { + const nodeKey = `${node.id}:${JSON.stringify(context).slice(0, 50)}`; + if (visited.has(nodeKey)) return context; + visited.add(nodeKey); + const start = Date.now(); + let result = context; + let nodeInput = context; + try { + switch (node.type) { + case "Input": + result = node.data ?? context; + 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 = context; + 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) { + trace.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: context, + paused_pending_result: result, + trace_so_far: trace, + 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, trace); + } + result = parseRecipeOutput( + result, + mergedContext._recipe_output_format, + mergedContext._recipe_output_required_fields + ); + if (kvStore && result !== null && result !== void 0 && graph.edges.some((e) => e.from === node.id && e.type === "PIPE")) { + await kvSetNodeOutput(kvStore, node.id, result); + } + void this.recordComponentReference?.(node.componentId, graph.id).catch(() => { + }); + break; + } + case "Output": + result = context; + break; + } + } catch (e) { + if (e instanceof WorkflowPaused) throw e; + const errMsg = e.message || String(e); + const duration_ms2 = Date.now() - start; + trace.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, + trace + ); + } + const duration_ms = Date.now() - start; + trace.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(context, 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, trace, fanIn, kvStore); + } + } else { + result = await this.executeNode(nextNode, graph, pipeContext, visited, trace, fanIn, kvStore); + } + break; + } + case "ON_SUCCESS": { + if (!isFailure(result)) { + const mergedCtx = propagateCtx(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + } + break; + } + case "ON_FAIL": { + if (isFailure(result)) { + const mergedCtx = propagateCtx(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + } + break; + } + case "IF": { + const passes = evaluateCondition(edge.condition ?? "true", result); + if (passes) { + const mergedCtx = propagateCtx(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, 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(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + } + break; + } + case "ON_FALSE": { + if (readBranch(result) === "false") { + const mergedCtx = propagateCtx(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + } + break; + } + case "ON_BRANCH": { + const actual = readBranch(result); + if (edge.branch !== void 0 && actual !== void 0 && actual === edge.branch) { + const mergedCtx = propagateCtx(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + } + break; + } + case "FOREACH": { + const iteratorKey = edge.iterator ?? "item"; + let items = getIterableFromContext(result, iteratorKey); + if (items.length === 0) { + items = getIterableFromContext(context, iteratorKey); + } + const iterResults = []; + const baseForeachCtx = propagateCtx(context, result, node.id); + for (const item of items) { + const itemContext = { + ...baseForeachCtx, + [iteratorKey]: item + }; + const itemResult = await this.executeNode(nextNode, graph, itemContext, /* @__PURE__ */ new Set(), trace, fanIn, kvStore); + iterResults.push(itemResult); + } + if (iterResults.length > 0) { + const failures = iterResults.filter( + (r) => r !== null && typeof r === "object" && r.success === false + ); + if (failures.length === iterResults.length) { + const first = failures[0]; + const errParts = []; + if (first.error) errParts.push(String(first.error)); + if (typeof first.status === "number") errParts.push(`HTTP ${first.status}`); + const bodyData = first.data; + if (bodyData && typeof bodyData.body === "string" && bodyData.body) { + errParts.push(bodyData.body.slice(0, 200)); + } + throw new Error( + `FOREACH \u6240\u6709 ${iterResults.length} \u9805\u76EE\u5747\u5931\u6557\uFF08\u9996\u9805\uFF1A${errParts.join("\uFF1B") || "\u672A\u77E5\u932F\u8AA4"}\uFF09` + ); + } + } + 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(context, result, node.id); + result = await this.executeNode(nextNode, graph, mergedCtx, visited, trace, fanIn, kvStore); + break; + } + case "IS_A": { + break; + } + case "CONTAINS": + case "HAS_STYLE": + case "HAS_BEHAVIOR": { + break; + } + case "CONTINUE": + break; + } + } + return result; + } + }; + } +}); + +// cypher-executor/src/lib/schemas.ts +var graphSchema, executeSchema; +var init_schemas = __esm({ + "cypher-executor/src/lib/schemas.ts"() { + "use strict"; + 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({}) + }); + } +}); + +// cypher-executor/src/actions/execution-evaluator.ts +function componentVerdictsFromTrace(nodes, trace) { + 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 trace) { + 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(env, nodes, trace) { + try { + const base = (env.REGISTRY_BASE_URL ?? (env.WORKER_SUBDOMAIN ? wasmWorkerUrl("registry", env.WORKER_SUBDOMAIN) : void 0))?.replace(/\/$/, ""); + if (!base) return; + const verdicts = componentVerdictsFromTrace(nodes, trace); + 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({ + "cypher-executor/src/actions/execution-evaluator.ts"() { + "use strict"; + init_component_loader(); + } +}); + +// cypher-executor/src/actions/webhook-handlers.ts +var webhook_handlers_exports = {}; +__export(webhook_handlers_exports, { + executeWebhookGraph: () => executeWebhookGraph, + generateToken: () => generateToken, + validateAndParseWebhook: () => validateAndParseWebhook +}); +function recordRecipeStats(env, recipeKeys, ok, at, ctx) { + if (recipeKeys.size === 0) return; + const base = (env.KBDB_BASE_URL ?? "https://kbdb.finally.click").replace(/\/$/, ""); + const headers = { "Content-Type": "application/json" }; + if (env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env.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 ; +} +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(env, 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(env); + const executor = new GraphExecutor(loader, void 0, env, apiKey); + const start = Date.now(); + try { + const result = await executor.execute( + parsed.data, + { ...triggerContext, _webhook_token: token }, + env.EXEC_CONTEXT + ); + const duration_ms = Date.now() - start; + recordTelemetry(env, apiKey, { + event_type: "run_success", + workflow_name: token, + duration_ms, + agent_user_agent: userAgent + }, ctx); + recordRecipeStats(env, executor.usedRecipeKeys, true, Date.now(), ctx); + { + const statsPromise = recordComponentStats( + env, + parsed.data.nodes, + result.trace + ); + if (ctx?.waitUntil) ctx.waitUntil(statsPromise); + else ; + } + 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(env, 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(env, executor.usedRecipeKeys, false, Date.now(), ctx); + } + if (!isPaused && err instanceof ExecutionError) { + const statsPromise = recordComponentStats( + env, + parsed.data.nodes, + err.trace + ); + if (ctx?.waitUntil) ctx.waitUntil(statsPromise); + else ; + } + 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({ + "cypher-executor/src/actions/webhook-handlers.ts"() { + "use strict"; + init_types(); + init_graph_executor(); + init_schemas(); + init_component_loader(); + init_telemetry(); + init_execution_evaluator(); + } +}); + +// cypher-executor/src/index.ts +init_dist(); + +// cypher-executor/node_modules/.pnpm/hono@4.12.10/node_modules/hono/dist/middleware/cors/index.js +var cors = (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 async function cors2(c, next) { + function set(key, value) { + c.res.headers.set(key, value); + } + 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 }); + } + }; +}; + +// cypher-executor/src/lib/cron-match.ts +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; +} +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; +} +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); +} +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; +} + +// cypher-executor/src/lib/cron-index.ts +var CRON_INDEX_KEY = "cron-idx:_all"; +function cronEntryKey(apiKey, name) { + return `${apiKey}:${name}`; +} +function parseCronEntryKey(entryKey) { + const idx = entryKey.indexOf(":"); + if (idx <= 0) return null; + return { apiKey: entryKey.slice(0, idx), name: entryKey.slice(idx + 1) }; +} +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 {}; + } +} +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)); +} + +// cypher-executor/src/scheduled.ts +init_webhook_handlers(); +init_kbdb_proxy(); +async function handleScheduled(controller, env, ctx) { + const now2 = new Date(controller.scheduledTime); + console.log("[scheduled] tick", now2.toISOString(), "controller.cron=", controller.cron); + const index = await readCronIndex(env.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 env.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(env, 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`); + if (now2.getUTCHours() === 2 && now2.getUTCMinutes() === 30) { + const { base, headers } = kbdbBase(env); + ctx.waitUntil( + fetch(`${base}/execution-log/cleanup`, { method: "POST", headers }).then(async (r) => { + const body = await r.json().catch(() => null); + console.log("[scheduled] execution-log cleanup", r.status, JSON.stringify(body)); + }).catch((e) => console.error("[scheduled] execution-log cleanup failed", e)) + ); + } +} + +// cypher-executor/src/routes/health.ts +init_dist(); + +// cypher-executor/src/lib/portal-auth-store.ts +init_credentials(); +var AUTH_STORE_PREFIX = "ARCRUN_AUTH_STORE"; +var SHARD_MAX_BYTES = 4600; +var AUTH_OVERLAY_TTL_MS = 18e4; +var ACCEL_KEY = "auth_store_recent"; +var ACCEL_TTL_SECONDS = 600; +var AUTH_ID_PREFIX = "auth:"; +var AuthStoreWriteError = class extends Error { +}; +var overlay = null; +var overlayAt = 0; +function emptyStore() { + return { version: 1, console: null, users: [] }; +} +function shardNames(env) { + const bag = env; + return Object.keys(bag).filter((k) => k === AUTH_STORE_PREFIX || /^ARCRUN_AUTH_STORE_\d+$/.test(k)).filter((k) => typeof bag[k] === "string" && bag[k].length > 0).sort((a, b) => shardIndex(a) - shardIndex(b)); +} +function shardIndex(name) { + if (name === AUTH_STORE_PREFIX) return 0; + return Number.parseInt(name.slice(AUTH_STORE_PREFIX.length + 1), 10) || 0; +} +function shardNameOf(index) { + return index === 0 ? AUTH_STORE_PREFIX : `${AUTH_STORE_PREFIX}_${index}`; +} +function authStorePresent(env) { + return shardNames(env).length > 0 || overlay !== null && Date.now() - overlayAt < AUTH_OVERLAY_TTL_MS; +} +function authStoreWritable(env) { + return Boolean(env.CF_SECRETS_API_TOKEN && env.CF_ACCOUNT_ID); +} +function readAuthStore(env) { + if (overlay && Date.now() - overlayAt < AUTH_OVERLAY_TTL_MS) return overlay; + return readAuthStoreFromEnv(env); +} +function readAuthStoreFromEnv(env) { + const bag = env; + const out = emptyStore(); + for (const name of shardNames(env)) { + let parsed = null; + try { + parsed = JSON.parse(bag[name]); + } catch { + continue; + } + if (!parsed || typeof parsed !== "object") continue; + if (parsed.console && !out.console) out.console = parsed.console; + if (Array.isArray(parsed.users)) { + for (const u of parsed.users) { + if (u && typeof u.email === "string" && typeof u.id === "string") out.users.push(u); + } + } + } + return out; +} +function findAuthUserByEmail(env, email) { + const needle = email.trim().toLowerCase(); + return readAuthStore(env).users.find((u) => u.email.toLowerCase() === needle) ?? null; +} +function findAuthUserById(env, id) { + return readAuthStore(env).users.find((u) => u.id === id) ?? null; +} +function isAuthStoreId(recordId) { + return recordId.startsWith(AUTH_ID_PREFIX); +} +function newAuthUserId() { + const arr = new Uint8Array(12); + crypto.getRandomValues(arr); + return AUTH_ID_PREFIX + Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join(""); +} +async function writeAuthStore(env, data) { + if (!authStoreWritable(env)) { + throw new AuthStoreWriteError( + "\u9019\u53F0\u5BE6\u4F8B\u9084\u4E0D\u80FD\u5BEB\u5165\u8A8D\u8B49\u5132\u5B58\uFF08\u7F3A CF_SECRETS_API_TOKEN / CF_ACCOUNT_ID\uFF09\u3002\u8A8D\u8B49\u5206\u96E2\u9700\u8981\u9019\u5169\u9805\u624D\u5BEB\u5F97\u9032 Workers Secrets\u2014\u2014\u8ACB\u91CD\u65B0\u57F7\u884C\u5B89\u88DD\uFF0F\u66F4\u65B0\u8B93\u5B83\u5C31\u7DD2\u3002" + ); + } + const shards = []; + let current = { v: 1, console: data.console ?? null, users: [] }; + for (const u of data.users) { + const trial = { ...current, users: [...current.users ?? [], u] }; + const size = new TextEncoder().encode(JSON.stringify(trial)).length; + if (size > SHARD_MAX_BYTES && (current.users ?? []).length > 0) { + shards.push(JSON.stringify(current)); + current = { v: 1, users: [u] }; + } else { + current = trial; + } + } + shards.push(JSON.stringify(current)); + for (const s of shards) { + if (new TextEncoder().encode(s).length > 5e3) { + throw new AuthStoreWriteError("\u55AE\u7B46\u8A8D\u8B49\u8CC7\u6599\u8D85\u904E Cloudflare \u8B8A\u6578 5 KB \u4E0A\u9650\uFF0C\u7121\u6CD5\u5BEB\u5165\u3002"); + } + } + const existing = shardNames(env); + for (let i = 0; i < shards.length; i++) { + await putWorkerSecret(env, shardNameOf(i), shards[i]); + } + for (const name of existing) { + if (shardIndex(name) >= shards.length) await deleteWorkerSecret(env, name); + } + overlay = { version: 1, console: data.console ?? null, users: [...data.users] }; + overlayAt = Date.now(); + try { + await env.SESSIONS_KV.put( + ACCEL_KEY, + JSON.stringify({ written_at: Date.now(), data: overlay }), + { expirationTtl: ACCEL_TTL_SECONDS } + ); + } catch { + } +} +async function hydrateFromAccelerator(env) { + let raw2 = null; + try { + raw2 = await env.SESSIONS_KV.get(ACCEL_KEY); + } catch { + return false; + } + if (!raw2) return false; + try { + const parsed = JSON.parse(raw2); + if (!parsed?.data || !Array.isArray(parsed.data.users)) return false; + if (overlay && overlayAt >= (parsed.written_at ?? 0)) return false; + overlay = { version: 1, console: parsed.data.console ?? null, users: parsed.data.users }; + overlayAt = parsed.written_at ?? Date.now(); + return true; + } catch { + return false; + } +} +async function authStoreRecentlyWritten(env) { + try { + return Boolean(await env.SESSIONS_KV.get(ACCEL_KEY)); + } catch { + return false; + } +} +function unionStores(a, b) { + const byId = /* @__PURE__ */ new Map(); + for (const u of [...a.users, ...b.users]) { + const prev = byId.get(u.id); + if (!prev || (u.updated_at ?? "") >= (prev.updated_at ?? "")) byId.set(u.id, u); + } + return { version: 1, console: a.console ?? b.console ?? null, users: [...byId.values()] }; +} +async function mutateAuthStore(env, fn) { + await hydrateFromAccelerator(env); + const next = unionStores(readAuthStore(env), readAuthStoreFromEnv(env)); + await fn(next); + await writeAuthStore(env, next); + return next; +} +function authStoreStatus(env) { + const data = readAuthStore(env); + return { + present: authStorePresent(env), + writable: authStoreWritable(env), + users: data.users.length, + console_configured: Boolean(data.console), + shards: shardNames(env).length + }; +} + +// cypher-executor/src/routes/health.ts +var healthRouter = new Hono2(); +healthRouter.get("/health", (c) => { + const bundleVersion = c.env.ARCRUN_BUNDLE_VERSION; + return c.json({ + ok: true, + ...bundleVersion ? { bundle_version: bundleVersion } : {}, + auth_store: authStoreStatus(c.env), + // arcrun-rag#38/#69/#25(2026-08-11):安裝器判斷「要不要重推」只比 bundle_version—— + // 但這次要修的洞是「installer 從沒注入過 PORTAL_MAIL_RELAY_BASE」,跟 bundle 內容 + // 版本無關(同一個 cypher 版本,有的實例有這個 var、有的沒有)。純比版本號的話, + // 已經在最新版的實例(如 leo 自己那台)永遠不會因為「按更新」而重推,這個 var + // 就永遠補不進去。只回布林(有沒有設,不回值本身)——不洩漏郵差網址。 + mail_relay_configured: Boolean(String(c.env.PORTAL_MAIL_RELAY_BASE ?? "").trim()) + }); +}); +healthRouter.get( + "/", + (c) => c.json({ + service: "arcrun-cypher-executor", + version: "1.0.0", + status: "ok" + }) +); + +// cypher-executor/src/routes/execute.ts +init_dist(); +init_types(); +init_graph_executor(); +init_schemas(); +init_component_loader(); + +// cypher-executor/src/actions/execution-logger.ts +init_kbdb_proxy(); +function extractTarget(input) { + if (!input) return void 0; + const raw2 = input.page_name ?? input.path; + if (raw2 === void 0 || raw2 === null) return void 0; + return typeof raw2 === "string" ? raw2 : JSON.stringify(raw2); +} +async function writeExecutionVerdict(env, workflowId, nodes, verdict, durationMs, message, input, apiKey) { + try { + const { base, headers } = kbdbBase(env); + await fetch(`${base}/execution-log/record`, { + method: "POST", + headers, + body: JSON.stringify({ + workflow_id: workflowId, + owner_id: apiKey ?? null, + verdict, + duration_ms: Math.max(0, Math.round(durationMs)), + message: message ?? "", + target: extractTarget(input) ?? null + }) + }); + } catch { + } +} + +// cypher-executor/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 } = 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, context, 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", context, apiKey) + ); + 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), context, apiKey) + ); + 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); + } +}); + +// cypher-executor/src/routes/cypher.ts +init_dist(); + +// cypher-executor/src/actions/cypher-handlers.ts +init_types(); +init_graph_executor(); +init_schemas(); +init_component_loader(); +init_execution_evaluator(); + +// cypher-executor/src/actions/triplet-parser.ts +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 }; +} +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); +} +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"; +} +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"; +} + +// cypher-executor/src/actions/search-nodes.ts +init_component_loader(); +init_recipes(); + +// cypher-executor/src/lib/branch-hints.ts +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()]; +} + +// cypher-executor/src/actions/search-nodes.ts +async function searchNodes(parsed, config, env, 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 = config?.[nodeName]?.component; + nodeResults[nodeName] = { + status: configComponent ? "found" : "unchecked", + componentId: configComponent ?? nodeName, + type: role + }; + } + return { nodeResults, missingNodes }; + } + const sub = env?.WORKER_SUBDOMAIN; + const registryBase = env?.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 && env?.RECIPES ? await listAllRecipes2(env.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 = config?.[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, env, 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 }; +} +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: [] }; + } +} +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 []; + } +} +function similarFromCatalog(entries, nodeName) { + const searchableOf = (e) => [e.canonical_id, e.display_name ?? "", e.description ?? "", ...e.aliases ?? [], ...e.tags ?? []].join(" ").toLowerCase(); + 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 count = /* @__PURE__ */ new Map(); + for (const e of entries) { + const hay = searchableOf(e); + const hits = tokens.filter((t) => hay.includes(t)).length; + if (hits > 0) count.set(e.canonical_id, Math.max(count.get(e.canonical_id) ?? 0, hits)); + } + return [...count.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([id]) => id); +} +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); +} +async function legacyPerNodeLookup(registryBase, componentId, nodeName, role, env, 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) ?? (env?.RECIPES ? await resolveRecipe(componentId, env.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 + }; +} +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` + } + }; +} +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`; +} +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" + }; +} +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 }; + } +} +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); +} +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 []; + } +} +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 count = /* @__PURE__ */ new Map(); + for (const ids of hits) { + for (const id of ids) count.set(id, (count.get(id) ?? 0) + 1); + } + return [...count.entries()].sort((a, b) => b[1] - a[1]).slice(0, 3).map(([id]) => id); +} + +// cypher-executor/src/actions/graph-builder.ts +function buildExecutionGraph(parsed, nodeResults, graphId, graphName, config) { + const nodes = [...parsed.nodeNames].map((name) => { + const nr = nodeResults[name]; + const id = name.toLowerCase().replace(/\s+/g, "-"); + const nodeConfig = config?.[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 }; +} + +// cypher-executor/src/actions/cypher-handlers.ts +async function handleCypherSearch(triplets, env, 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, env, 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 }; +} +async function handleCypherExecute(triplets, context, graphId, graphName, config, env, waitUntil, apiKey) { + const parsed = parseTriplets(triplets); + if (!parsed) { + throw new Error("\u7121\u6CD5\u89E3\u6790\u4EFB\u4F55\u7BC0\u9EDE"); + } + const { nodeResults } = await searchNodes(parsed, config, env, "compile"); + const graph = buildExecutionGraph(parsed, nodeResults, graphId, graphName, config); + const parseResult = graphSchema.safeParse(graph); + if (!parseResult.success) { + throw new Error("\u5716\u5B9A\u7FA9\u7522\u751F\u5931\u6557"); + } + const loader = createComponentLoader(env); + const executor = new GraphExecutor(loader, void 0, env, apiKey); + const start = Date.now(); + try { + const result = await executor.execute(parseResult.data, context ?? {}, env.EXEC_CONTEXT); + const duration_ms = Date.now() - start; + waitUntil(recordComponentStats(env, 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(env, 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; + } +} + +// cypher-executor/src/actions/target-search.ts +init_component_loader(); + +// cypher-executor/src/lib/workflow-search.ts +async function fetchTenantWorkflowSearch(env, apiKey, q, mode = "semantic") { + const base = (env.KBDB_BASE_URL ?? "https://arcrun-kbdb.uncle6-me.workers.dev").replace(/\/$/, ""); + const headers = { "Content-Type": "application/json" }; + if (env.KBDB_INTERNAL_TOKEN) headers["Authorization"] = `Bearer ${env.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 }); +} + +// cypher-executor/src/actions/target-search.ts +async function searchByTarget(target, query, env, apiKey) { + if (target === "component") { + const sub = env.WORKER_SUBDOMAIN; + const registryBase = env.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 (!env.RECIPES) return { ok: false, status: 502, error: "RECIPES KV \u672A\u7D81\u5B9A" }; + const all = await listAllRecipes2(env.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(env, 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 } }; +} + +// cypher-executor/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); + } + } +}); + +// cypher-executor/src/routes/validate.ts +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 }); +}); + +// cypher-executor/src/routes/docs.ts +init_dist(); + +// cypher-executor/src/lib/openapi.ts +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" + } + } + } +}; + +// cypher-executor/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 + + + + + + +
+