diff --git a/.worker-builds/arcrun-array-ops/component.wasm b/.worker-builds/arcrun-array-ops/component.wasm new file mode 100644 index 0000000..c0720f5 Binary files /dev/null and b/.worker-builds/arcrun-array-ops/component.wasm differ diff --git a/.worker-builds/arcrun-array-ops/worker.mjs b/.worker-builds/arcrun-array-ops/worker.mjs new file mode 100644 index 0000000..34fb36e --- /dev/null +++ b/.worker-builds/arcrun-array-ops/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/array_ops/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/array_ops/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/array_ops/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/array_ops/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]; + } + }); +}; + +// .component-builds/array_ops/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; + +// .component-builds/array_ops/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"); + } + /** + * 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; + } +}; + +// .component-builds/array_ops/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; + } +}; + +// .component-builds/array_ops/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); + }; +}; + +// .component-builds/array_ops/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 { +}; + +// .component-builds/array_ops/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/array_ops/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/array_ops/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); +} + +// .component-builds/array_ops/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("|") + ")"; + } +}; + +// .component-builds/array_ops/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]; + } +}; + +// .component-builds/array_ops/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); + } + } +}; + +// .component-builds/array_ops/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]; + } +}; + +// .component-builds/array_ops/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])]; + } +}; + +// .component-builds/array_ops/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); + } +}; + +// .component-builds/array_ops/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()] + }); + } +}; + +// .component-builds/array_ops/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 }); + } + }; +}; + +// .component-builds/array_ops/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-auth-oauth2/component.wasm b/.worker-builds/arcrun-auth-oauth2/component.wasm new file mode 100644 index 0000000..1b2d74e Binary files /dev/null and b/.worker-builds/arcrun-auth-oauth2/component.wasm differ diff --git a/.worker-builds/arcrun-auth-oauth2/worker.mjs b/.worker-builds/arcrun-auth-oauth2/worker.mjs new file mode 100644 index 0000000..730c5b8 --- /dev/null +++ b/.worker-builds/arcrun-auth-oauth2/worker.mjs @@ -0,0 +1,2601 @@ +// .component-builds/auth_oauth2/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/auth_oauth2/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/auth_oauth2/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/auth_oauth2/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]; + } + }); +}; + +// .component-builds/auth_oauth2/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; + +// .component-builds/auth_oauth2/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"); + } + /** + * 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; + } +}; + +// .component-builds/auth_oauth2/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; + } +}; + +// .component-builds/auth_oauth2/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); + }; +}; + +// .component-builds/auth_oauth2/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 { +}; + +// .component-builds/auth_oauth2/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/auth_oauth2/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/auth_oauth2/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); +} + +// .component-builds/auth_oauth2/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("|") + ")"; + } +}; + +// .component-builds/auth_oauth2/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]; + } +}; + +// .component-builds/auth_oauth2/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); + } + } +}; + +// .component-builds/auth_oauth2/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]; + } +}; + +// .component-builds/auth_oauth2/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])]; + } +}; + +// .component-builds/auth_oauth2/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); + } +}; + +// .component-builds/auth_oauth2/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()] + }); + } +}; + +// .component-builds/auth_oauth2/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 === "*") { + 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/wasi-shim.ts +var WASI_ESUCCESS = 0; +var WASI_ENOSYS = 76; +var FD_STDIN = 0; +var FD_STDOUT = 1; +var FD_STDERR = 2; +function createWasiShim(stdinData, hostFunctions) { + const stdinBytes = new TextEncoder().encode(stdinData); + let stdinOffset = 0; + const stdoutChunks = []; + const stderrChunks = []; + let memory = null; + function getMemoryView() { + if (!memory) throw new Error("WASI memory not set \u2014 call setMemory() after instantiate"); + return new DataView(memory.buffer); + } + function writeOut(buf, outPtr, outLenPtr, data) { + try { + new Uint8Array(buf, outPtr, data.length).set(data); + new DataView(buf).setUint32(outLenPtr, data.length, true); + return 0; + } catch { + return 1; + } + } + function fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== FD_STDOUT && fd !== FD_STDERR) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalWritten = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const chunk = new Uint8Array(buf, iov_base, iov_len); + const copy = new Uint8Array(iov_len); + copy.set(chunk); + if (fd === FD_STDOUT) stdoutChunks.push(copy); + else stderrChunks.push(copy); + totalWritten += iov_len; + } + view.setUint32(nwritten_ptr, totalWritten, true); + return WASI_ESUCCESS; + } + function fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== FD_STDIN) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalRead = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(iov_len, remaining); + const dest = new Uint8Array(buf, iov_base, toCopy); + dest.set(stdinBytes.subarray(stdinOffset, stdinOffset + toCopy)); + stdinOffset += toCopy; + totalRead += toCopy; + } + view.setUint32(nread_ptr, totalRead, true); + return WASI_ESUCCESS; + } + function proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + } + function random_get(buf_ptr, buf_len) { + const view = new Uint8Array(memory.buffer, buf_ptr, buf_len); + crypto.getRandomValues(view); + return WASI_ESUCCESS; + } + let asyncifyDataPtr = 0; + const ASYNCIFY_BUF_SIZE = 1024 * 1024; + let asyncifyPendingPromise = null; + let asyncifyResult = 0; + let asyncifyExports = null; + function jspiSuspending(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + return SuspendingCtor ? new SuspendingCtor(fn) : fn; + } + function asyncifyWrap(fn) { + return (...args) => { + if (!memory) return 1; + const ax = asyncifyExports; + if (!ax) return 0; + const state = ax.get_state(); + if (state === 2) { + return asyncifyResult; + } + if (state === 1) { + return 0; + } + asyncifyPendingPromise = fn(...args); + ax.start_unwind(asyncifyDataPtr); + return 0; + }; + } + function hostWrap(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + if (SuspendingCtor) { + return new SuspendingCtor(fn); + } + return asyncifyWrap(fn); + } + const shim = { + imports: { + wasi_snapshot_preview1: { + fd_write, + fd_read, + proc_exit, + random_get, + // 其餘 syscall 回傳 ENOSYS(不允許網路/檔案系統操作) + fd_seek: () => WASI_ENOSYS, + fd_close: () => WASI_ESUCCESS, + fd_fdstat_get: () => WASI_ENOSYS, + fd_prestat_get: () => WASI_ENOSYS, + fd_prestat_dir_name: () => WASI_ENOSYS, + environ_get: () => WASI_ESUCCESS, + environ_sizes_get: (count_ptr, size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(count_ptr, 0, true); + view.setUint32(size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + args_get: () => WASI_ESUCCESS, + args_sizes_get: (argc_ptr, argv_buf_size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(argc_ptr, 0, true); + view.setUint32(argv_buf_size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + clock_time_get: (id, precision, time_ptr) => { + if (memory) { + const view = getMemoryView(); + const now = BigInt(Date.now()) * 1000000n; + view.setBigUint64(time_ptr, now, true); + } + return WASI_ESUCCESS; + }, + clock_res_get: () => WASI_ENOSYS, + poll_oneoff: () => WASI_ENOSYS, + sched_yield: () => WASI_ESUCCESS, + proc_raise: () => WASI_ENOSYS, + sock_accept: () => WASI_ENOSYS, + sock_recv: () => WASI_ENOSYS, + sock_send: () => WASI_ENOSYS, + sock_shutdown: () => WASI_ENOSYS, + path_open: () => WASI_ENOSYS, + path_create_directory: () => WASI_ENOSYS, + path_remove_directory: () => WASI_ENOSYS, + path_rename: () => WASI_ENOSYS, + path_unlink_file: () => WASI_ENOSYS, + path_filestat_get: () => WASI_ENOSYS, + path_readlink: () => WASI_ENOSYS, + path_symlink: () => WASI_ENOSYS, + path_link: () => WASI_ENOSYS + }, + // u6u host functions:讓 .wasm 零件透過 host function 呼叫外部服務 + // .wasm 零件用 //go:wasmimport u6u 宣告 + // 所有 async host function 透過 asyncifyWrap 包裝,實作 asyncify 協議 + u6u: { + http_request: hostFunctions?.http_request ? hostWrap(async (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const snapBuf = memory.buffer; + const dec = new TextDecoder(); + const url = dec.decode(new Uint8Array(snapBuf, urlPtr, urlLen)); + const method = dec.decode(new Uint8Array(snapBuf, methodPtr, methodLen)); + const headers = dec.decode(new Uint8Array(snapBuf, headersPtr, headersLen)); + const body = dec.decode(new Uint8Array(snapBuf, bodyPtr, bodyLen)); + try { + const result = await hostFunctions.http_request(url, method, headers, body); + return writeOut(memory.buffer, outPtr, outLenPtr, new TextEncoder().encode(result)); + } catch (e) { + const errDetail = e instanceof Error ? e.message : String(e); + const errEnv = new TextEncoder().encode( + JSON.stringify({ error: `fetch failed: ${errDetail}`, status: 0, body: "" }) + ); + return writeOut(memory.buffer, outPtr, outLenPtr, errEnv); + } + }) : () => 1, + // kv_get(keyPtr, keyLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 key + kv_get: hostFunctions?.kv_get ? hostWrap(async (keyPtr, keyLen, outPtr, outLenPtr) => { + if (!memory) { + console.error("[kv_get] memory null"); + return 1; + } + const key = new TextDecoder().decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + console.error(`[kv_get] key="${key}" keyPtr=${keyPtr} keyLen=${keyLen} outPtr=${outPtr} outLenPtr=${outLenPtr}`); + try { + const result = await hostFunctions.kv_get(key); + console.error(`[kv_get] result=${result === null ? "null" : result.slice(0, 80)}`); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + const status = writeOut(memory.buffer, outPtr, outLenPtr, encoded); + console.error(`[kv_get] writeOut status=${status} encodedLen=${encoded.length} memBufLen=${memory.buffer.byteLength}`); + return status; + } catch (e) { + console.error(`[kv_get] error: ${e}`); + return 1; + } + }) : () => 1, + // secret_get(refPtr, refLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 ref + // 與 kv_get 同款 pointer/memory-write 機制;差別只在 host 端實作來源(env[ref] 而非 KV.get)。 + secret_get: hostFunctions?.secret_get ? hostWrap(async (refPtr, refLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const ref = new TextDecoder().decode(new Uint8Array(memory.buffer, refPtr, refLen)); + try { + const result = await hostFunctions.secret_get(ref); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + return writeOut(memory.buffer, outPtr, outLenPtr, encoded); + } catch { + return 1; + } + }) : () => 1, + // kv_put(keyPtr, keyLen, valPtr, valLen, ttlSeconds) → 0 成功;1 錯誤 + kv_put: hostFunctions?.kv_put ? hostWrap(async (keyPtr, keyLen, valPtr, valLen, ttlSeconds) => { + if (!memory) return 1; + const dec = new TextDecoder(); + const key = dec.decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + const value = dec.decode(new Uint8Array(memory.buffer, valPtr, valLen)); + try { + await hostFunctions.kv_put(key, value, ttlSeconds); + return 0; + } catch { + return 1; + } + }) : () => 1, + // crypto_decrypt — 已停用,永遠回 1(失敗)。 + // + // ⚠️ 不能整條移除:現役 auth_static_key / auth_service_account / auth_oauth2 的 + // .wasm 仍宣告 `//go:wasmimport u6u crypto_decrypt`,import 缺項會讓 WASM + // **instantiate 直接失敗**(不是呼叫才失敗)→ 所有認證零件全掛。故保留成 stub, + // 讓連結成立。待三個零件的 Go 原始碼移除該 wasmimport 並重編 wasm 後,才可刪掉這條。 + crypto_decrypt: () => 1, + // crypto_sign_rs256(dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) → 0 成功 + crypto_sign_rs256: hostFunctions?.crypto_sign_rs256 ? hostWrap(async (dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) => { + if (!memory) return 1; + const data = new Uint8Array(new Uint8Array(memory.buffer, dataPtr, dataLen)); + const pkcs8 = new Uint8Array(new Uint8Array(memory.buffer, pkcs8Ptr, pkcs8Len)); + try { + const sig = await hostFunctions.crypto_sign_rs256(data, pkcs8); + return writeOut(memory.buffer, outPtr, outLenPtr, sig); + } catch { + return 1; + } + }) : () => 1 + } + }, + setMemory(mem) { + memory = mem; + }, + async run(instance) { + const exp = instance.exports; + const startFn = exp._start ?? exp.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + const promisingFn = WebAssembly["promising"]; + if (promisingFn) { + try { + await promisingFn(startFn)(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + const asyncifyGetState = exp.asyncify_get_state; + const asyncifyStartUnwind = exp.asyncify_start_unwind; + const asyncifyStopUnwind = exp.asyncify_stop_unwind; + const asyncifyStartRewind = exp.asyncify_start_rewind; + const asyncifyStopRewind = exp.asyncify_stop_rewind; + if (asyncifyGetState && asyncifyStartUnwind && asyncifyStopUnwind && asyncifyStartRewind && asyncifyStopRewind) { + asyncifyExports = { + get_state: asyncifyGetState, + start_unwind: asyncifyStartUnwind, + stop_unwind: asyncifyStopUnwind, + start_rewind: asyncifyStartRewind, + stop_rewind: asyncifyStopRewind + }; + const mallocFn = exp.malloc; + if (mallocFn && memory) { + const totalSize = ASYNCIFY_BUF_SIZE; + asyncifyDataPtr = mallocFn(totalSize); + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + totalSize, true); + } else if (memory) { + const memBytes = memory.buffer.byteLength; + asyncifyDataPtr = memBytes - ASYNCIFY_BUF_SIZE; + if (asyncifyDataPtr > 8) { + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + ASYNCIFY_BUF_SIZE, true); + } + } + } + if (!asyncifyExports) { + try { + startFn(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + let rewinding = false; + while (true) { + asyncifyPendingPromise = null; + try { + if (rewinding) { + asyncifyExports.start_rewind(asyncifyDataPtr); + startFn(); + asyncifyExports.stop_rewind(); + } else { + startFn(); + } + } catch (e) { + if (e instanceof Error && e.message === "wasm exit: 0") break; + throw e; + } + if (asyncifyPendingPromise !== null) { + asyncifyExports.stop_unwind(); + asyncifyResult = await asyncifyPendingPromise; + asyncifyPendingPromise = null; + rewinding = true; + continue; + } + break; + } + }, + getStdout() { + if (stdoutChunks.length === 0) return ""; + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + }, + getStderr() { + if (stderrChunks.length === 0) return ""; + const total = stderrChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stderrChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + } + }; + return shim; +} +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) + }; +} + +// .component-builds/auth_oauth2/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: "auth_oauth2" })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + const apiKey = typeof input.api_key === "string" ? input.api_key : ""; + if (!apiKey) { + return c.json({ success: false, error: "api_key \u5FC5\u586B" }, 400); + } + try { + const result = await runWasm(c.env, apiKey, input); + return c.json(result); + } catch (e) { + return c.json( + { success: false, error: e instanceof Error ? e.message : String(e) }, + 500 + ); + } +}); +var index_default = app; +async function runWasm(env, apiKey, input) { + const stdinData = JSON.stringify(input); + const hostFunctions = createArcrunHostFunctions(env, apiKey); + hostFunctions.http_request = async (url, method, headersJSON, body) => { + const headers = {}; + try { + Object.assign(headers, JSON.parse(headersJSON || "{}")); + } catch { + } + const res = await fetch(url, { + method, + headers, + body: body || void 0 + }); + return res.text(); + }; + const shim = createWasiShim(stdinData, hostFunctions); + const instance = await WebAssembly.instantiate( + componentWasm, + shim.imports + ); + shim.setMemory(instance.exports.memory); + await shim.run(instance); + const stdout = shim.getStdout().trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-auth-service-account/component.wasm b/.worker-builds/arcrun-auth-service-account/component.wasm new file mode 100644 index 0000000..1598e66 Binary files /dev/null and b/.worker-builds/arcrun-auth-service-account/component.wasm differ diff --git a/.worker-builds/arcrun-auth-service-account/worker.mjs b/.worker-builds/arcrun-auth-service-account/worker.mjs new file mode 100644 index 0000000..5e8b48e --- /dev/null +++ b/.worker-builds/arcrun-auth-service-account/worker.mjs @@ -0,0 +1,2614 @@ +// .component-builds/auth_service_account/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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]; + } + }); +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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"); + } + /** + * 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; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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); + }; +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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 { +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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); +} + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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("|") + ")"; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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]; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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); + } + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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]; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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])]; + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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); + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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()] + }); + } +}; + +// .component-builds/auth_service_account/node_modules/.pnpm/hono@4.12.14/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/wasi-shim.ts +var WASI_ESUCCESS = 0; +var WASI_ENOSYS = 76; +var FD_STDIN = 0; +var FD_STDOUT = 1; +var FD_STDERR = 2; +function createWasiShim(stdinData, hostFunctions) { + const stdinBytes = new TextEncoder().encode(stdinData); + let stdinOffset = 0; + const stdoutChunks = []; + const stderrChunks = []; + let memory = null; + function getMemoryView() { + if (!memory) throw new Error("WASI memory not set \u2014 call setMemory() after instantiate"); + return new DataView(memory.buffer); + } + function writeOut(buf, outPtr, outLenPtr, data) { + try { + new Uint8Array(buf, outPtr, data.length).set(data); + new DataView(buf).setUint32(outLenPtr, data.length, true); + return 0; + } catch { + return 1; + } + } + function fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== FD_STDOUT && fd !== FD_STDERR) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalWritten = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const chunk = new Uint8Array(buf, iov_base, iov_len); + const copy = new Uint8Array(iov_len); + copy.set(chunk); + if (fd === FD_STDOUT) stdoutChunks.push(copy); + else stderrChunks.push(copy); + totalWritten += iov_len; + } + view.setUint32(nwritten_ptr, totalWritten, true); + return WASI_ESUCCESS; + } + function fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== FD_STDIN) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalRead = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(iov_len, remaining); + const dest = new Uint8Array(buf, iov_base, toCopy); + dest.set(stdinBytes.subarray(stdinOffset, stdinOffset + toCopy)); + stdinOffset += toCopy; + totalRead += toCopy; + } + view.setUint32(nread_ptr, totalRead, true); + return WASI_ESUCCESS; + } + function proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + } + function random_get(buf_ptr, buf_len) { + const view = new Uint8Array(memory.buffer, buf_ptr, buf_len); + crypto.getRandomValues(view); + return WASI_ESUCCESS; + } + let asyncifyDataPtr = 0; + const ASYNCIFY_BUF_SIZE = 1024 * 1024; + let asyncifyPendingPromise = null; + let asyncifyResult = 0; + let asyncifyExports = null; + function jspiSuspending(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + return SuspendingCtor ? new SuspendingCtor(fn) : fn; + } + function asyncifyWrap(fn) { + return (...args) => { + if (!memory) return 1; + const ax = asyncifyExports; + if (!ax) return 0; + const state = ax.get_state(); + if (state === 2) { + return asyncifyResult; + } + if (state === 1) { + return 0; + } + asyncifyPendingPromise = fn(...args); + ax.start_unwind(asyncifyDataPtr); + return 0; + }; + } + function hostWrap(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + if (SuspendingCtor) { + return new SuspendingCtor(fn); + } + return asyncifyWrap(fn); + } + const shim = { + imports: { + wasi_snapshot_preview1: { + fd_write, + fd_read, + proc_exit, + random_get, + // 其餘 syscall 回傳 ENOSYS(不允許網路/檔案系統操作) + fd_seek: () => WASI_ENOSYS, + fd_close: () => WASI_ESUCCESS, + fd_fdstat_get: () => WASI_ENOSYS, + fd_prestat_get: () => WASI_ENOSYS, + fd_prestat_dir_name: () => WASI_ENOSYS, + environ_get: () => WASI_ESUCCESS, + environ_sizes_get: (count_ptr, size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(count_ptr, 0, true); + view.setUint32(size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + args_get: () => WASI_ESUCCESS, + args_sizes_get: (argc_ptr, argv_buf_size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(argc_ptr, 0, true); + view.setUint32(argv_buf_size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + clock_time_get: (id, precision, time_ptr) => { + if (memory) { + const view = getMemoryView(); + const now = BigInt(Date.now()) * 1000000n; + view.setBigUint64(time_ptr, now, true); + } + return WASI_ESUCCESS; + }, + clock_res_get: () => WASI_ENOSYS, + poll_oneoff: () => WASI_ENOSYS, + sched_yield: () => WASI_ESUCCESS, + proc_raise: () => WASI_ENOSYS, + sock_accept: () => WASI_ENOSYS, + sock_recv: () => WASI_ENOSYS, + sock_send: () => WASI_ENOSYS, + sock_shutdown: () => WASI_ENOSYS, + path_open: () => WASI_ENOSYS, + path_create_directory: () => WASI_ENOSYS, + path_remove_directory: () => WASI_ENOSYS, + path_rename: () => WASI_ENOSYS, + path_unlink_file: () => WASI_ENOSYS, + path_filestat_get: () => WASI_ENOSYS, + path_readlink: () => WASI_ENOSYS, + path_symlink: () => WASI_ENOSYS, + path_link: () => WASI_ENOSYS + }, + // u6u host functions:讓 .wasm 零件透過 host function 呼叫外部服務 + // .wasm 零件用 //go:wasmimport u6u 宣告 + // 所有 async host function 透過 asyncifyWrap 包裝,實作 asyncify 協議 + u6u: { + http_request: hostFunctions?.http_request ? hostWrap(async (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const snapBuf = memory.buffer; + const dec = new TextDecoder(); + const url = dec.decode(new Uint8Array(snapBuf, urlPtr, urlLen)); + const method = dec.decode(new Uint8Array(snapBuf, methodPtr, methodLen)); + const headers = dec.decode(new Uint8Array(snapBuf, headersPtr, headersLen)); + const body = dec.decode(new Uint8Array(snapBuf, bodyPtr, bodyLen)); + try { + const result = await hostFunctions.http_request(url, method, headers, body); + return writeOut(memory.buffer, outPtr, outLenPtr, new TextEncoder().encode(result)); + } catch (e) { + const errDetail = e instanceof Error ? e.message : String(e); + const errEnv = new TextEncoder().encode( + JSON.stringify({ error: `fetch failed: ${errDetail}`, status: 0, body: "" }) + ); + return writeOut(memory.buffer, outPtr, outLenPtr, errEnv); + } + }) : () => 1, + // kv_get(keyPtr, keyLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 key + kv_get: hostFunctions?.kv_get ? hostWrap(async (keyPtr, keyLen, outPtr, outLenPtr) => { + if (!memory) { + console.error("[kv_get] memory null"); + return 1; + } + const key = new TextDecoder().decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + console.error(`[kv_get] key="${key}" keyPtr=${keyPtr} keyLen=${keyLen} outPtr=${outPtr} outLenPtr=${outLenPtr}`); + try { + const result = await hostFunctions.kv_get(key); + console.error(`[kv_get] result=${result === null ? "null" : result.slice(0, 80)}`); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + const status = writeOut(memory.buffer, outPtr, outLenPtr, encoded); + console.error(`[kv_get] writeOut status=${status} encodedLen=${encoded.length} memBufLen=${memory.buffer.byteLength}`); + return status; + } catch (e) { + console.error(`[kv_get] error: ${e}`); + return 1; + } + }) : () => 1, + // secret_get(refPtr, refLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 ref + // 與 kv_get 同款 pointer/memory-write 機制;差別只在 host 端實作來源(env[ref] 而非 KV.get)。 + secret_get: hostFunctions?.secret_get ? hostWrap(async (refPtr, refLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const ref = new TextDecoder().decode(new Uint8Array(memory.buffer, refPtr, refLen)); + try { + const result = await hostFunctions.secret_get(ref); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + return writeOut(memory.buffer, outPtr, outLenPtr, encoded); + } catch { + return 1; + } + }) : () => 1, + // kv_put(keyPtr, keyLen, valPtr, valLen, ttlSeconds) → 0 成功;1 錯誤 + kv_put: hostFunctions?.kv_put ? hostWrap(async (keyPtr, keyLen, valPtr, valLen, ttlSeconds) => { + if (!memory) return 1; + const dec = new TextDecoder(); + const key = dec.decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + const value = dec.decode(new Uint8Array(memory.buffer, valPtr, valLen)); + try { + await hostFunctions.kv_put(key, value, ttlSeconds); + return 0; + } catch { + return 1; + } + }) : () => 1, + // crypto_decrypt — 已停用,永遠回 1(失敗)。 + // + // ⚠️ 不能整條移除:現役 auth_static_key / auth_service_account / auth_oauth2 的 + // .wasm 仍宣告 `//go:wasmimport u6u crypto_decrypt`,import 缺項會讓 WASM + // **instantiate 直接失敗**(不是呼叫才失敗)→ 所有認證零件全掛。故保留成 stub, + // 讓連結成立。待三個零件的 Go 原始碼移除該 wasmimport 並重編 wasm 後,才可刪掉這條。 + crypto_decrypt: () => 1, + // crypto_sign_rs256(dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) → 0 成功 + crypto_sign_rs256: hostFunctions?.crypto_sign_rs256 ? hostWrap(async (dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) => { + if (!memory) return 1; + const data = new Uint8Array(new Uint8Array(memory.buffer, dataPtr, dataLen)); + const pkcs8 = new Uint8Array(new Uint8Array(memory.buffer, pkcs8Ptr, pkcs8Len)); + try { + const sig = await hostFunctions.crypto_sign_rs256(data, pkcs8); + return writeOut(memory.buffer, outPtr, outLenPtr, sig); + } catch { + return 1; + } + }) : () => 1 + } + }, + setMemory(mem) { + memory = mem; + }, + async run(instance) { + const exp = instance.exports; + const startFn = exp._start ?? exp.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + const promisingFn = WebAssembly["promising"]; + if (promisingFn) { + try { + await promisingFn(startFn)(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + const asyncifyGetState = exp.asyncify_get_state; + const asyncifyStartUnwind = exp.asyncify_start_unwind; + const asyncifyStopUnwind = exp.asyncify_stop_unwind; + const asyncifyStartRewind = exp.asyncify_start_rewind; + const asyncifyStopRewind = exp.asyncify_stop_rewind; + if (asyncifyGetState && asyncifyStartUnwind && asyncifyStopUnwind && asyncifyStartRewind && asyncifyStopRewind) { + asyncifyExports = { + get_state: asyncifyGetState, + start_unwind: asyncifyStartUnwind, + stop_unwind: asyncifyStopUnwind, + start_rewind: asyncifyStartRewind, + stop_rewind: asyncifyStopRewind + }; + const mallocFn = exp.malloc; + if (mallocFn && memory) { + const totalSize = ASYNCIFY_BUF_SIZE; + asyncifyDataPtr = mallocFn(totalSize); + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + totalSize, true); + } else if (memory) { + const memBytes = memory.buffer.byteLength; + asyncifyDataPtr = memBytes - ASYNCIFY_BUF_SIZE; + if (asyncifyDataPtr > 8) { + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + ASYNCIFY_BUF_SIZE, true); + } + } + } + if (!asyncifyExports) { + try { + startFn(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + let rewinding = false; + while (true) { + asyncifyPendingPromise = null; + try { + if (rewinding) { + asyncifyExports.start_rewind(asyncifyDataPtr); + startFn(); + asyncifyExports.stop_rewind(); + } else { + startFn(); + } + } catch (e) { + if (e instanceof Error && e.message === "wasm exit: 0") break; + throw e; + } + if (asyncifyPendingPromise !== null) { + asyncifyExports.stop_unwind(); + asyncifyResult = await asyncifyPendingPromise; + asyncifyPendingPromise = null; + rewinding = true; + continue; + } + break; + } + }, + getStdout() { + if (stdoutChunks.length === 0) return ""; + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + }, + getStderr() { + if (stderrChunks.length === 0) return ""; + const total = stderrChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stderrChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + } + }; + return shim; +} +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) + }; +} + +// .component-builds/auth_service_account/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: "auth_service_account" })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + const apiKey = typeof input.api_key === "string" ? input.api_key : ""; + if (!apiKey) { + return c.json({ success: false, error: "api_key \u5FC5\u586B" }, 400); + } + try { + const result = await runWasm(c.env, apiKey, input); + return c.json(result); + } catch (e) { + return c.json( + { success: false, error: e instanceof Error ? e.message : String(e) }, + 500 + ); + } +}); +var index_default = app; +async function runWasm(env, apiKey, input) { + const stdinData = JSON.stringify(input); + const baseHost = createArcrunHostFunctions(env, apiKey); + const hostFunctions = { + ...baseHost, + http_request: async (url, method, headersJson, body) => { + const headers = {}; + if (headersJson) { + try { + const parsed = JSON.parse(headersJson); + if (parsed && typeof parsed === "object") { + for (const [k, v] of Object.entries(parsed)) { + if (typeof v === "string") headers[k] = v; + } + } + } catch { + } + } + const init = { method, headers }; + if (body && method.toUpperCase() !== "GET" && method.toUpperCase() !== "HEAD") { + init.body = body; + } + const res = await fetch(url, init); + return await res.text(); + } + }; + const shim = createWasiShim(stdinData, hostFunctions); + const instance = await WebAssembly.instantiate( + componentWasm, + shim.imports + ); + shim.setMemory(instance.exports.memory); + await shim.run(instance); + const stdout = shim.getStdout().trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-auth-static-key/component.wasm b/.worker-builds/arcrun-auth-static-key/component.wasm new file mode 100644 index 0000000..afb0a1c Binary files /dev/null and b/.worker-builds/arcrun-auth-static-key/component.wasm differ diff --git a/.worker-builds/arcrun-auth-static-key/worker.mjs b/.worker-builds/arcrun-auth-static-key/worker.mjs new file mode 100644 index 0000000..9713710 --- /dev/null +++ b/.worker-builds/arcrun-auth-static-key/worker.mjs @@ -0,0 +1,2605 @@ +// .component-builds/auth_static_key/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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]; + } + }); +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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); + }; +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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 { +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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(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)); + }); + }; +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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); +} + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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("|") + ")"; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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]; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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); + } + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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]; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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])]; + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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); + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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()] + }); + } +}; + +// .component-builds/auth_static_key/node_modules/.pnpm/hono@4.12.25/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 }); + } + }; +}; + +// cypher-executor/src/lib/wasi-shim.ts +var WASI_ESUCCESS = 0; +var WASI_ENOSYS = 76; +var FD_STDIN = 0; +var FD_STDOUT = 1; +var FD_STDERR = 2; +function createWasiShim(stdinData, hostFunctions) { + const stdinBytes = new TextEncoder().encode(stdinData); + let stdinOffset = 0; + const stdoutChunks = []; + const stderrChunks = []; + let memory = null; + function getMemoryView() { + if (!memory) throw new Error("WASI memory not set \u2014 call setMemory() after instantiate"); + return new DataView(memory.buffer); + } + function writeOut(buf, outPtr, outLenPtr, data) { + try { + new Uint8Array(buf, outPtr, data.length).set(data); + new DataView(buf).setUint32(outLenPtr, data.length, true); + return 0; + } catch { + return 1; + } + } + function fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== FD_STDOUT && fd !== FD_STDERR) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalWritten = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const chunk = new Uint8Array(buf, iov_base, iov_len); + const copy = new Uint8Array(iov_len); + copy.set(chunk); + if (fd === FD_STDOUT) stdoutChunks.push(copy); + else stderrChunks.push(copy); + totalWritten += iov_len; + } + view.setUint32(nwritten_ptr, totalWritten, true); + return WASI_ESUCCESS; + } + function fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== FD_STDIN) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalRead = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(iov_len, remaining); + const dest = new Uint8Array(buf, iov_base, toCopy); + dest.set(stdinBytes.subarray(stdinOffset, stdinOffset + toCopy)); + stdinOffset += toCopy; + totalRead += toCopy; + } + view.setUint32(nread_ptr, totalRead, true); + return WASI_ESUCCESS; + } + function proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + } + function random_get(buf_ptr, buf_len) { + const view = new Uint8Array(memory.buffer, buf_ptr, buf_len); + crypto.getRandomValues(view); + return WASI_ESUCCESS; + } + let asyncifyDataPtr = 0; + const ASYNCIFY_BUF_SIZE = 1024 * 1024; + let asyncifyPendingPromise = null; + let asyncifyResult = 0; + let asyncifyExports = null; + function jspiSuspending(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + return SuspendingCtor ? new SuspendingCtor(fn) : fn; + } + function asyncifyWrap(fn) { + return (...args) => { + if (!memory) return 1; + const ax = asyncifyExports; + if (!ax) return 0; + const state = ax.get_state(); + if (state === 2) { + return asyncifyResult; + } + if (state === 1) { + return 0; + } + asyncifyPendingPromise = fn(...args); + ax.start_unwind(asyncifyDataPtr); + return 0; + }; + } + function hostWrap(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + if (SuspendingCtor) { + return new SuspendingCtor(fn); + } + return asyncifyWrap(fn); + } + const shim = { + imports: { + wasi_snapshot_preview1: { + fd_write, + fd_read, + proc_exit, + random_get, + // 其餘 syscall 回傳 ENOSYS(不允許網路/檔案系統操作) + fd_seek: () => WASI_ENOSYS, + fd_close: () => WASI_ESUCCESS, + fd_fdstat_get: () => WASI_ENOSYS, + fd_prestat_get: () => WASI_ENOSYS, + fd_prestat_dir_name: () => WASI_ENOSYS, + environ_get: () => WASI_ESUCCESS, + environ_sizes_get: (count_ptr, size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(count_ptr, 0, true); + view.setUint32(size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + args_get: () => WASI_ESUCCESS, + args_sizes_get: (argc_ptr, argv_buf_size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(argc_ptr, 0, true); + view.setUint32(argv_buf_size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + clock_time_get: (id, precision, time_ptr) => { + if (memory) { + const view = getMemoryView(); + const now = BigInt(Date.now()) * 1000000n; + view.setBigUint64(time_ptr, now, true); + } + return WASI_ESUCCESS; + }, + clock_res_get: () => WASI_ENOSYS, + poll_oneoff: () => WASI_ENOSYS, + sched_yield: () => WASI_ESUCCESS, + proc_raise: () => WASI_ENOSYS, + sock_accept: () => WASI_ENOSYS, + sock_recv: () => WASI_ENOSYS, + sock_send: () => WASI_ENOSYS, + sock_shutdown: () => WASI_ENOSYS, + path_open: () => WASI_ENOSYS, + path_create_directory: () => WASI_ENOSYS, + path_remove_directory: () => WASI_ENOSYS, + path_rename: () => WASI_ENOSYS, + path_unlink_file: () => WASI_ENOSYS, + path_filestat_get: () => WASI_ENOSYS, + path_readlink: () => WASI_ENOSYS, + path_symlink: () => WASI_ENOSYS, + path_link: () => WASI_ENOSYS + }, + // u6u host functions:讓 .wasm 零件透過 host function 呼叫外部服務 + // .wasm 零件用 //go:wasmimport u6u 宣告 + // 所有 async host function 透過 asyncifyWrap 包裝,實作 asyncify 協議 + u6u: { + http_request: hostFunctions?.http_request ? hostWrap(async (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const snapBuf = memory.buffer; + const dec = new TextDecoder(); + const url = dec.decode(new Uint8Array(snapBuf, urlPtr, urlLen)); + const method = dec.decode(new Uint8Array(snapBuf, methodPtr, methodLen)); + const headers = dec.decode(new Uint8Array(snapBuf, headersPtr, headersLen)); + const body = dec.decode(new Uint8Array(snapBuf, bodyPtr, bodyLen)); + try { + const result = await hostFunctions.http_request(url, method, headers, body); + return writeOut(memory.buffer, outPtr, outLenPtr, new TextEncoder().encode(result)); + } catch (e) { + const errDetail = e instanceof Error ? e.message : String(e); + const errEnv = new TextEncoder().encode( + JSON.stringify({ error: `fetch failed: ${errDetail}`, status: 0, body: "" }) + ); + return writeOut(memory.buffer, outPtr, outLenPtr, errEnv); + } + }) : () => 1, + // kv_get(keyPtr, keyLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 key + kv_get: hostFunctions?.kv_get ? hostWrap(async (keyPtr, keyLen, outPtr, outLenPtr) => { + if (!memory) { + console.error("[kv_get] memory null"); + return 1; + } + const key = new TextDecoder().decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + console.error(`[kv_get] key="${key}" keyPtr=${keyPtr} keyLen=${keyLen} outPtr=${outPtr} outLenPtr=${outLenPtr}`); + try { + const result = await hostFunctions.kv_get(key); + console.error(`[kv_get] result=${result === null ? "null" : result.slice(0, 80)}`); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + const status = writeOut(memory.buffer, outPtr, outLenPtr, encoded); + console.error(`[kv_get] writeOut status=${status} encodedLen=${encoded.length} memBufLen=${memory.buffer.byteLength}`); + return status; + } catch (e) { + console.error(`[kv_get] error: ${e}`); + return 1; + } + }) : () => 1, + // secret_get(refPtr, refLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 ref + // 與 kv_get 同款 pointer/memory-write 機制;差別只在 host 端實作來源(env[ref] 而非 KV.get)。 + secret_get: hostFunctions?.secret_get ? hostWrap(async (refPtr, refLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const ref = new TextDecoder().decode(new Uint8Array(memory.buffer, refPtr, refLen)); + try { + const result = await hostFunctions.secret_get(ref); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + return writeOut(memory.buffer, outPtr, outLenPtr, encoded); + } catch { + return 1; + } + }) : () => 1, + // kv_put(keyPtr, keyLen, valPtr, valLen, ttlSeconds) → 0 成功;1 錯誤 + kv_put: hostFunctions?.kv_put ? hostWrap(async (keyPtr, keyLen, valPtr, valLen, ttlSeconds) => { + if (!memory) return 1; + const dec = new TextDecoder(); + const key = dec.decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + const value = dec.decode(new Uint8Array(memory.buffer, valPtr, valLen)); + try { + await hostFunctions.kv_put(key, value, ttlSeconds); + return 0; + } catch { + return 1; + } + }) : () => 1, + // crypto_decrypt — 已停用,永遠回 1(失敗)。 + // + // ⚠️ 不能整條移除:現役 auth_static_key / auth_service_account / auth_oauth2 的 + // .wasm 仍宣告 `//go:wasmimport u6u crypto_decrypt`,import 缺項會讓 WASM + // **instantiate 直接失敗**(不是呼叫才失敗)→ 所有認證零件全掛。故保留成 stub, + // 讓連結成立。待三個零件的 Go 原始碼移除該 wasmimport 並重編 wasm 後,才可刪掉這條。 + crypto_decrypt: () => 1, + // crypto_sign_rs256(dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) → 0 成功 + crypto_sign_rs256: hostFunctions?.crypto_sign_rs256 ? hostWrap(async (dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) => { + if (!memory) return 1; + const data = new Uint8Array(new Uint8Array(memory.buffer, dataPtr, dataLen)); + const pkcs8 = new Uint8Array(new Uint8Array(memory.buffer, pkcs8Ptr, pkcs8Len)); + try { + const sig = await hostFunctions.crypto_sign_rs256(data, pkcs8); + return writeOut(memory.buffer, outPtr, outLenPtr, sig); + } catch { + return 1; + } + }) : () => 1 + } + }, + setMemory(mem) { + memory = mem; + }, + async run(instance) { + const exp = instance.exports; + const startFn = exp._start ?? exp.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + const promisingFn = WebAssembly["promising"]; + if (promisingFn) { + try { + await promisingFn(startFn)(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + const asyncifyGetState = exp.asyncify_get_state; + const asyncifyStartUnwind = exp.asyncify_start_unwind; + const asyncifyStopUnwind = exp.asyncify_stop_unwind; + const asyncifyStartRewind = exp.asyncify_start_rewind; + const asyncifyStopRewind = exp.asyncify_stop_rewind; + if (asyncifyGetState && asyncifyStartUnwind && asyncifyStopUnwind && asyncifyStartRewind && asyncifyStopRewind) { + asyncifyExports = { + get_state: asyncifyGetState, + start_unwind: asyncifyStartUnwind, + stop_unwind: asyncifyStopUnwind, + start_rewind: asyncifyStartRewind, + stop_rewind: asyncifyStopRewind + }; + const mallocFn = exp.malloc; + if (mallocFn && memory) { + const totalSize = ASYNCIFY_BUF_SIZE; + asyncifyDataPtr = mallocFn(totalSize); + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + totalSize, true); + } else if (memory) { + const memBytes = memory.buffer.byteLength; + asyncifyDataPtr = memBytes - ASYNCIFY_BUF_SIZE; + if (asyncifyDataPtr > 8) { + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + ASYNCIFY_BUF_SIZE, true); + } + } + } + if (!asyncifyExports) { + try { + startFn(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + let rewinding = false; + while (true) { + asyncifyPendingPromise = null; + try { + if (rewinding) { + asyncifyExports.start_rewind(asyncifyDataPtr); + startFn(); + asyncifyExports.stop_rewind(); + } else { + startFn(); + } + } catch (e) { + if (e instanceof Error && e.message === "wasm exit: 0") break; + throw e; + } + if (asyncifyPendingPromise !== null) { + asyncifyExports.stop_unwind(); + asyncifyResult = await asyncifyPendingPromise; + asyncifyPendingPromise = null; + rewinding = true; + continue; + } + break; + } + }, + getStdout() { + if (stdoutChunks.length === 0) return ""; + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + }, + getStderr() { + if (stderrChunks.length === 0) return ""; + const total = stderrChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stderrChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + } + }; + return shim; +} +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) + }; +} + +// .component-builds/auth_static_key/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: "auth_static_key" })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + const apiKey = typeof input.api_key === "string" ? input.api_key : ""; + if (!apiKey) { + return c.json({ success: false, error: "api_key \u5FC5\u586B" }, 400); + } + try { + const result = await runWasm(c.env, apiKey, input); + return c.json(result); + } catch (e) { + return c.json( + { success: false, error: e instanceof Error ? e.message : String(e) }, + 500 + ); + } +}); +var index_default = app; +async function runWasm(env, apiKey, input) { + const stdinData = JSON.stringify(input); + const hostFunctions = createArcrunHostFunctions(env, apiKey); + const shim = createWasiShim(stdinData, hostFunctions); + const instance = await WebAssembly.instantiate( + componentWasm, + shim.imports + ); + shim.setMemory(instance.exports.memory); + await shim.run(instance); + const stdout = shim.getStdout().trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-cron/component.wasm b/.worker-builds/arcrun-cron/component.wasm new file mode 100644 index 0000000..ea658f8 Binary files /dev/null and b/.worker-builds/arcrun-cron/component.wasm differ diff --git a/.worker-builds/arcrun-cron/worker.mjs b/.worker-builds/arcrun-cron/worker.mjs new file mode 100644 index 0000000..54a8057 --- /dev/null +++ b/.worker-builds/arcrun-cron/worker.mjs @@ -0,0 +1,2540 @@ +// .component-builds/cron/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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]; + } + }); +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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"); + } + /** + * 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; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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); + }; +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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 { +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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); +} + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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("|") + ")"; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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]; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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); + } + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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]; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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])]; + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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); + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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()] + }); + } +}; + +// .component-builds/cron/node_modules/.pnpm/hono@4.12.14/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/wasi-shim.ts +var WASI_ESUCCESS = 0; +var WASI_ENOSYS = 76; +var FD_STDIN = 0; +var FD_STDOUT = 1; +var FD_STDERR = 2; +function createWasiShim(stdinData, hostFunctions) { + const stdinBytes = new TextEncoder().encode(stdinData); + let stdinOffset = 0; + const stdoutChunks = []; + const stderrChunks = []; + let memory = null; + function getMemoryView() { + if (!memory) throw new Error("WASI memory not set \u2014 call setMemory() after instantiate"); + return new DataView(memory.buffer); + } + function writeOut(buf, outPtr, outLenPtr, data) { + try { + new Uint8Array(buf, outPtr, data.length).set(data); + new DataView(buf).setUint32(outLenPtr, data.length, true); + return 0; + } catch { + return 1; + } + } + function fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== FD_STDOUT && fd !== FD_STDERR) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalWritten = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const chunk = new Uint8Array(buf, iov_base, iov_len); + const copy = new Uint8Array(iov_len); + copy.set(chunk); + if (fd === FD_STDOUT) stdoutChunks.push(copy); + else stderrChunks.push(copy); + totalWritten += iov_len; + } + view.setUint32(nwritten_ptr, totalWritten, true); + return WASI_ESUCCESS; + } + function fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== FD_STDIN) return WASI_ENOSYS; + const view = getMemoryView(); + const buf = memory.buffer; + let totalRead = 0; + for (let i = 0; i < iovs_len; i++) { + const iov_base = view.getUint32(iovs + i * 8, true); + const iov_len = view.getUint32(iovs + i * 8 + 4, true); + if (iov_len === 0) continue; + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(iov_len, remaining); + const dest = new Uint8Array(buf, iov_base, toCopy); + dest.set(stdinBytes.subarray(stdinOffset, stdinOffset + toCopy)); + stdinOffset += toCopy; + totalRead += toCopy; + } + view.setUint32(nread_ptr, totalRead, true); + return WASI_ESUCCESS; + } + function proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + } + function random_get(buf_ptr, buf_len) { + const view = new Uint8Array(memory.buffer, buf_ptr, buf_len); + crypto.getRandomValues(view); + return WASI_ESUCCESS; + } + let asyncifyDataPtr = 0; + const ASYNCIFY_BUF_SIZE = 1024 * 1024; + let asyncifyPendingPromise = null; + let asyncifyResult = 0; + let asyncifyExports = null; + function jspiSuspending(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + return SuspendingCtor ? new SuspendingCtor(fn) : fn; + } + function asyncifyWrap(fn) { + return (...args) => { + if (!memory) return 1; + const ax = asyncifyExports; + if (!ax) return 0; + const state = ax.get_state(); + if (state === 2) { + return asyncifyResult; + } + if (state === 1) { + return 0; + } + asyncifyPendingPromise = fn(...args); + ax.start_unwind(asyncifyDataPtr); + return 0; + }; + } + function hostWrap(fn) { + const SuspendingCtor = WebAssembly["Suspending"]; + if (SuspendingCtor) { + return new SuspendingCtor(fn); + } + return asyncifyWrap(fn); + } + const shim = { + imports: { + wasi_snapshot_preview1: { + fd_write, + fd_read, + proc_exit, + random_get, + // 其餘 syscall 回傳 ENOSYS(不允許網路/檔案系統操作) + fd_seek: () => WASI_ENOSYS, + fd_close: () => WASI_ESUCCESS, + fd_fdstat_get: () => WASI_ENOSYS, + fd_prestat_get: () => WASI_ENOSYS, + fd_prestat_dir_name: () => WASI_ENOSYS, + environ_get: () => WASI_ESUCCESS, + environ_sizes_get: (count_ptr, size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(count_ptr, 0, true); + view.setUint32(size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + args_get: () => WASI_ESUCCESS, + args_sizes_get: (argc_ptr, argv_buf_size_ptr) => { + if (memory) { + const view = getMemoryView(); + view.setUint32(argc_ptr, 0, true); + view.setUint32(argv_buf_size_ptr, 0, true); + } + return WASI_ESUCCESS; + }, + clock_time_get: (id, precision, time_ptr) => { + if (memory) { + const view = getMemoryView(); + const now = BigInt(Date.now()) * 1000000n; + view.setBigUint64(time_ptr, now, true); + } + return WASI_ESUCCESS; + }, + clock_res_get: () => WASI_ENOSYS, + poll_oneoff: () => WASI_ENOSYS, + sched_yield: () => WASI_ESUCCESS, + proc_raise: () => WASI_ENOSYS, + sock_accept: () => WASI_ENOSYS, + sock_recv: () => WASI_ENOSYS, + sock_send: () => WASI_ENOSYS, + sock_shutdown: () => WASI_ENOSYS, + path_open: () => WASI_ENOSYS, + path_create_directory: () => WASI_ENOSYS, + path_remove_directory: () => WASI_ENOSYS, + path_rename: () => WASI_ENOSYS, + path_unlink_file: () => WASI_ENOSYS, + path_filestat_get: () => WASI_ENOSYS, + path_readlink: () => WASI_ENOSYS, + path_symlink: () => WASI_ENOSYS, + path_link: () => WASI_ENOSYS + }, + // u6u host functions:讓 .wasm 零件透過 host function 呼叫外部服務 + // .wasm 零件用 //go:wasmimport u6u 宣告 + // 所有 async host function 透過 asyncifyWrap 包裝,實作 asyncify 協議 + u6u: { + http_request: hostFunctions?.http_request ? hostWrap(async (urlPtr, urlLen, methodPtr, methodLen, headersPtr, headersLen, bodyPtr, bodyLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const snapBuf = memory.buffer; + const dec = new TextDecoder(); + const url = dec.decode(new Uint8Array(snapBuf, urlPtr, urlLen)); + const method = dec.decode(new Uint8Array(snapBuf, methodPtr, methodLen)); + const headers = dec.decode(new Uint8Array(snapBuf, headersPtr, headersLen)); + const body = dec.decode(new Uint8Array(snapBuf, bodyPtr, bodyLen)); + try { + const result = await hostFunctions.http_request(url, method, headers, body); + return writeOut(memory.buffer, outPtr, outLenPtr, new TextEncoder().encode(result)); + } catch (e) { + const errDetail = e instanceof Error ? e.message : String(e); + const errEnv = new TextEncoder().encode( + JSON.stringify({ error: `fetch failed: ${errDetail}`, status: 0, body: "" }) + ); + return writeOut(memory.buffer, outPtr, outLenPtr, errEnv); + } + }) : () => 1, + // kv_get(keyPtr, keyLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 key + kv_get: hostFunctions?.kv_get ? hostWrap(async (keyPtr, keyLen, outPtr, outLenPtr) => { + if (!memory) { + console.error("[kv_get] memory null"); + return 1; + } + const key = new TextDecoder().decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + console.error(`[kv_get] key="${key}" keyPtr=${keyPtr} keyLen=${keyLen} outPtr=${outPtr} outLenPtr=${outLenPtr}`); + try { + const result = await hostFunctions.kv_get(key); + console.error(`[kv_get] result=${result === null ? "null" : result.slice(0, 80)}`); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + const status = writeOut(memory.buffer, outPtr, outLenPtr, encoded); + console.error(`[kv_get] writeOut status=${status} encodedLen=${encoded.length} memBufLen=${memory.buffer.byteLength}`); + return status; + } catch (e) { + console.error(`[kv_get] error: ${e}`); + return 1; + } + }) : () => 1, + // secret_get(refPtr, refLen, outPtr, outLenPtr) → 0 成功;1 錯誤;2 找不到 ref + // 與 kv_get 同款 pointer/memory-write 機制;差別只在 host 端實作來源(env[ref] 而非 KV.get)。 + secret_get: hostFunctions?.secret_get ? hostWrap(async (refPtr, refLen, outPtr, outLenPtr) => { + if (!memory) return 1; + const ref = new TextDecoder().decode(new Uint8Array(memory.buffer, refPtr, refLen)); + try { + const result = await hostFunctions.secret_get(ref); + if (result === null) return 2; + const encoded = new TextEncoder().encode(result); + return writeOut(memory.buffer, outPtr, outLenPtr, encoded); + } catch { + return 1; + } + }) : () => 1, + // kv_put(keyPtr, keyLen, valPtr, valLen, ttlSeconds) → 0 成功;1 錯誤 + kv_put: hostFunctions?.kv_put ? hostWrap(async (keyPtr, keyLen, valPtr, valLen, ttlSeconds) => { + if (!memory) return 1; + const dec = new TextDecoder(); + const key = dec.decode(new Uint8Array(memory.buffer, keyPtr, keyLen)); + const value = dec.decode(new Uint8Array(memory.buffer, valPtr, valLen)); + try { + await hostFunctions.kv_put(key, value, ttlSeconds); + return 0; + } catch { + return 1; + } + }) : () => 1, + // crypto_decrypt — 已停用,永遠回 1(失敗)。 + // + // ⚠️ 不能整條移除:現役 auth_static_key / auth_service_account / auth_oauth2 的 + // .wasm 仍宣告 `//go:wasmimport u6u crypto_decrypt`,import 缺項會讓 WASM + // **instantiate 直接失敗**(不是呼叫才失敗)→ 所有認證零件全掛。故保留成 stub, + // 讓連結成立。待三個零件的 Go 原始碼移除該 wasmimport 並重編 wasm 後,才可刪掉這條。 + crypto_decrypt: () => 1, + // crypto_sign_rs256(dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) → 0 成功 + crypto_sign_rs256: hostFunctions?.crypto_sign_rs256 ? hostWrap(async (dataPtr, dataLen, pkcs8Ptr, pkcs8Len, outPtr, outLenPtr) => { + if (!memory) return 1; + const data = new Uint8Array(new Uint8Array(memory.buffer, dataPtr, dataLen)); + const pkcs8 = new Uint8Array(new Uint8Array(memory.buffer, pkcs8Ptr, pkcs8Len)); + try { + const sig = await hostFunctions.crypto_sign_rs256(data, pkcs8); + return writeOut(memory.buffer, outPtr, outLenPtr, sig); + } catch { + return 1; + } + }) : () => 1 + } + }, + setMemory(mem) { + memory = mem; + }, + async run(instance) { + const exp = instance.exports; + const startFn = exp._start ?? exp.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + const promisingFn = WebAssembly["promising"]; + if (promisingFn) { + try { + await promisingFn(startFn)(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + const asyncifyGetState = exp.asyncify_get_state; + const asyncifyStartUnwind = exp.asyncify_start_unwind; + const asyncifyStopUnwind = exp.asyncify_stop_unwind; + const asyncifyStartRewind = exp.asyncify_start_rewind; + const asyncifyStopRewind = exp.asyncify_stop_rewind; + if (asyncifyGetState && asyncifyStartUnwind && asyncifyStopUnwind && asyncifyStartRewind && asyncifyStopRewind) { + asyncifyExports = { + get_state: asyncifyGetState, + start_unwind: asyncifyStartUnwind, + stop_unwind: asyncifyStopUnwind, + start_rewind: asyncifyStartRewind, + stop_rewind: asyncifyStopRewind + }; + const mallocFn = exp.malloc; + if (mallocFn && memory) { + const totalSize = ASYNCIFY_BUF_SIZE; + asyncifyDataPtr = mallocFn(totalSize); + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + totalSize, true); + } else if (memory) { + const memBytes = memory.buffer.byteLength; + asyncifyDataPtr = memBytes - ASYNCIFY_BUF_SIZE; + if (asyncifyDataPtr > 8) { + const view = new DataView(memory.buffer); + view.setInt32(asyncifyDataPtr, asyncifyDataPtr + 8, true); + view.setInt32(asyncifyDataPtr + 4, asyncifyDataPtr + ASYNCIFY_BUF_SIZE, true); + } + } + } + if (!asyncifyExports) { + try { + startFn(); + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + return; + } + let rewinding = false; + while (true) { + asyncifyPendingPromise = null; + try { + if (rewinding) { + asyncifyExports.start_rewind(asyncifyDataPtr); + startFn(); + asyncifyExports.stop_rewind(); + } else { + startFn(); + } + } catch (e) { + if (e instanceof Error && e.message === "wasm exit: 0") break; + throw e; + } + if (asyncifyPendingPromise !== null) { + asyncifyExports.stop_unwind(); + asyncifyResult = await asyncifyPendingPromise; + asyncifyPendingPromise = null; + rewinding = true; + continue; + } + break; + } + }, + getStdout() { + if (stdoutChunks.length === 0) return ""; + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + }, + getStderr() { + if (stderrChunks.length === 0) return ""; + const total = stderrChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let offset = 0; + for (const chunk of stderrChunks) { + merged.set(chunk, offset); + offset += chunk.length; + } + return new TextDecoder().decode(merged); + } + }; + return shim; +} + +// .component-builds/cron/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: "cron" })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(input); + return c.json(result); + } catch (e) { + return c.json( + { success: false, error: e instanceof Error ? e.message : String(e) }, + 500 + ); + } +}); +var index_default = app; +async function runWasm(input) { + const shim = createWasiShim(JSON.stringify(input)); + const instance = await WebAssembly.instantiate( + componentWasm, + shim.imports + ); + shim.setMemory(instance.exports.memory); + await shim.run(instance); + const stdout = shim.getStdout().trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-date-ops/component.wasm b/.worker-builds/arcrun-date-ops/component.wasm new file mode 100644 index 0000000..19e08bb Binary files /dev/null and b/.worker-builds/arcrun-date-ops/component.wasm differ diff --git a/.worker-builds/arcrun-date-ops/worker.mjs b/.worker-builds/arcrun-date-ops/worker.mjs new file mode 100644 index 0000000..6d34a39 --- /dev/null +++ b/.worker-builds/arcrun-date-ops/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/date_ops/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/date_ops/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/date_ops/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/date_ops/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]; + } + }); +}; + +// .component-builds/date_ops/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; + +// .component-builds/date_ops/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"); + } + /** + * 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; + } +}; + +// .component-builds/date_ops/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; + } +}; + +// .component-builds/date_ops/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); + }; +}; + +// .component-builds/date_ops/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 { +}; + +// .component-builds/date_ops/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/date_ops/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/date_ops/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); +} + +// .component-builds/date_ops/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("|") + ")"; + } +}; + +// .component-builds/date_ops/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]; + } +}; + +// .component-builds/date_ops/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); + } + } +}; + +// .component-builds/date_ops/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]; + } +}; + +// .component-builds/date_ops/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])]; + } +}; + +// .component-builds/date_ops/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); + } +}; + +// .component-builds/date_ops/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()] + }); + } +}; + +// .component-builds/date_ops/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 }); + } + }; +}; + +// .component-builds/date_ops/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-filter/component.wasm b/.worker-builds/arcrun-filter/component.wasm new file mode 100644 index 0000000..debfee9 Binary files /dev/null and b/.worker-builds/arcrun-filter/component.wasm differ diff --git a/.worker-builds/arcrun-filter/worker.mjs b/.worker-builds/arcrun-filter/worker.mjs new file mode 100644 index 0000000..e916861 --- /dev/null +++ b/.worker-builds/arcrun-filter/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/filter/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/filter/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/filter/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/filter/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]; + } + }); +}; + +// .component-builds/filter/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; + +// .component-builds/filter/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"); + } + /** + * 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; + } +}; + +// .component-builds/filter/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; + } +}; + +// .component-builds/filter/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); + }; +}; + +// .component-builds/filter/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 { +}; + +// .component-builds/filter/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/filter/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/filter/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); +} + +// .component-builds/filter/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("|") + ")"; + } +}; + +// .component-builds/filter/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]; + } +}; + +// .component-builds/filter/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); + } + } +}; + +// .component-builds/filter/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]; + } +}; + +// .component-builds/filter/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])]; + } +}; + +// .component-builds/filter/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); + } +}; + +// .component-builds/filter/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()] + }); + } +}; + +// .component-builds/filter/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 }); + } + }; +}; + +// .component-builds/filter/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-foreach-control/component.wasm b/.worker-builds/arcrun-foreach-control/component.wasm new file mode 100644 index 0000000..eca5999 Binary files /dev/null and b/.worker-builds/arcrun-foreach-control/component.wasm differ diff --git a/.worker-builds/arcrun-foreach-control/worker.mjs b/.worker-builds/arcrun-foreach-control/worker.mjs new file mode 100644 index 0000000..e33dee8 --- /dev/null +++ b/.worker-builds/arcrun-foreach-control/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/foreach_control/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/foreach_control/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/foreach_control/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/foreach_control/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]; + } + }); +}; + +// .component-builds/foreach_control/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; + +// .component-builds/foreach_control/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"); + } + /** + * 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; + } +}; + +// .component-builds/foreach_control/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; + } +}; + +// .component-builds/foreach_control/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); + }; +}; + +// .component-builds/foreach_control/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 { +}; + +// .component-builds/foreach_control/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/foreach_control/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/foreach_control/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); +} + +// .component-builds/foreach_control/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("|") + ")"; + } +}; + +// .component-builds/foreach_control/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]; + } +}; + +// .component-builds/foreach_control/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); + } + } +}; + +// .component-builds/foreach_control/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]; + } +}; + +// .component-builds/foreach_control/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])]; + } +}; + +// .component-builds/foreach_control/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); + } +}; + +// .component-builds/foreach_control/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()] + }); + } +}; + +// .component-builds/foreach_control/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 }); + } + }; +}; + +// .component-builds/foreach_control/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-if-control/component.wasm b/.worker-builds/arcrun-if-control/component.wasm new file mode 100644 index 0000000..af45ec1 Binary files /dev/null and b/.worker-builds/arcrun-if-control/component.wasm differ diff --git a/.worker-builds/arcrun-if-control/worker.mjs b/.worker-builds/arcrun-if-control/worker.mjs new file mode 100644 index 0000000..de5de22 --- /dev/null +++ b/.worker-builds/arcrun-if-control/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/if_control/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/if_control/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/if_control/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/if_control/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]; + } + }); +}; + +// .component-builds/if_control/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; + +// .component-builds/if_control/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"); + } + /** + * 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; + } +}; + +// .component-builds/if_control/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; + } +}; + +// .component-builds/if_control/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); + }; +}; + +// .component-builds/if_control/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 { +}; + +// .component-builds/if_control/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/if_control/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/if_control/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); +} + +// .component-builds/if_control/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("|") + ")"; + } +}; + +// .component-builds/if_control/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]; + } +}; + +// .component-builds/if_control/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); + } + } +}; + +// .component-builds/if_control/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]; + } +}; + +// .component-builds/if_control/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])]; + } +}; + +// .component-builds/if_control/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); + } +}; + +// .component-builds/if_control/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()] + }); + } +}; + +// .component-builds/if_control/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 }); + } + }; +}; + +// .component-builds/if_control/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-merge/component.wasm b/.worker-builds/arcrun-merge/component.wasm new file mode 100644 index 0000000..a9a0763 Binary files /dev/null and b/.worker-builds/arcrun-merge/component.wasm differ diff --git a/.worker-builds/arcrun-merge/worker.mjs b/.worker-builds/arcrun-merge/worker.mjs new file mode 100644 index 0000000..de7ccae --- /dev/null +++ b/.worker-builds/arcrun-merge/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/merge/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/merge/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/merge/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/merge/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]; + } + }); +}; + +// .component-builds/merge/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; + +// .component-builds/merge/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"); + } + /** + * 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; + } +}; + +// .component-builds/merge/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; + } +}; + +// .component-builds/merge/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); + }; +}; + +// .component-builds/merge/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 { +}; + +// .component-builds/merge/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/merge/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/merge/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); +} + +// .component-builds/merge/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("|") + ")"; + } +}; + +// .component-builds/merge/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]; + } +}; + +// .component-builds/merge/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); + } + } +}; + +// .component-builds/merge/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]; + } +}; + +// .component-builds/merge/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])]; + } +}; + +// .component-builds/merge/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); + } +}; + +// .component-builds/merge/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()] + }); + } +}; + +// .component-builds/merge/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 }); + } + }; +}; + +// .component-builds/merge/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-number-ops/component.wasm b/.worker-builds/arcrun-number-ops/component.wasm new file mode 100644 index 0000000..e0f2952 Binary files /dev/null and b/.worker-builds/arcrun-number-ops/component.wasm differ diff --git a/.worker-builds/arcrun-number-ops/worker.mjs b/.worker-builds/arcrun-number-ops/worker.mjs new file mode 100644 index 0000000..f84ab7f --- /dev/null +++ b/.worker-builds/arcrun-number-ops/worker.mjs @@ -0,0 +1,2291 @@ +// .component-builds/number_ops/src/index.ts +import componentWasm from "./component.wasm"; + +// .component-builds/number_ops/node_modules/hono/dist/compose.js +var compose = (middleware, onError, onNotFound) => { + return (context, next) => { + let index = -1; + return dispatch(0); + async function dispatch(i) { + if (i <= index) { + throw new Error("next() called multiple times"); + } + index = i; + let res; + let isError = false; + let handler; + if (middleware[i]) { + handler = middleware[i][0][0]; + context.req.routeIndex = i; + } else { + handler = i === middleware.length && next || void 0; + } + if (handler) { + try { + res = await handler(context, () => dispatch(i + 1)); + } catch (err) { + if (err instanceof Error && onError) { + context.error = err; + res = await onError(err, context); + isError = true; + } else { + throw err; + } + } + } else { + if (context.finalized === false && onNotFound) { + res = await onNotFound(context); + } + } + if (res && (context.finalized === false || isError)) { + context.res = res; + } + return context; + } + }; +}; + +// .component-builds/number_ops/node_modules/hono/dist/request/constants.js +var GET_MATCH_RESULT = /* @__PURE__ */ Symbol(); + +// .component-builds/number_ops/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]; + } + }); +}; + +// .component-builds/number_ops/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; + +// .component-builds/number_ops/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"); + } + /** + * 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; + } +}; + +// .component-builds/number_ops/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; + } +}; + +// .component-builds/number_ops/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); + }; +}; + +// .component-builds/number_ops/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 { +}; + +// .component-builds/number_ops/node_modules/hono/dist/utils/constants.js +var COMPOSED_HANDLER = "__COMPOSED_HANDLER"; + +// .component-builds/number_ops/node_modules/hono/dist/hono-base.js +var notFoundHandler = (c) => { + return c.text("404 Not Found", 404); +}; +var errorHandler = (err, c) => { + if ("getResponse" in err) { + const res = err.getResponse(); + return c.newResponse(res.body, res); + } + console.error(err); + return c.text("Internal Server Error", 500); +}; +var Hono = class _Hono { + get; + post; + put; + delete; + options; + patch; + all; + on; + use; + /* + This class is like an abstract class and does not have a router. + To use it, inherit the class and implement router in the constructor. + */ + router; + getPath; + // Cannot use `#` because it requires visibility at JavaScript runtime. + _basePath = "/"; + #path = "/"; + routes = []; + constructor(options = {}) { + const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; + allMethods.forEach((method) => { + this[method] = (args1, ...args) => { + if (typeof args1 === "string") { + this.#path = args1; + } else { + this.#addRoute(method, this.#path, args1); + } + 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)); + }); + }; +}; + +// .component-builds/number_ops/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); +} + +// .component-builds/number_ops/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("|") + ")"; + } +}; + +// .component-builds/number_ops/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]; + } +}; + +// .component-builds/number_ops/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); + } + } +}; + +// .component-builds/number_ops/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]; + } +}; + +// .component-builds/number_ops/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])]; + } +}; + +// .component-builds/number_ops/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); + } +}; + +// .component-builds/number_ops/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()] + }); + } +}; + +// .component-builds/number_ops/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 }); + } + }; +}; + +// .component-builds/number_ops/src/index.ts +var app = new Hono2(); +app.use("*", cors()); +app.get("/", (c) => c.json({ ok: true, component: COMPONENT_ID })); +app.post("/", async (c) => { + let input; + try { + input = await c.req.json(); + } catch { + return c.json({ success: false, error: "request body must be JSON" }, 400); + } + try { + const result = await runWasm(componentWasm, input); + return c.json(result); + } catch (e) { + return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 500); + } +}); +var index_default = app; +async function runWasm(wasmModule, input) { + const stdinBytes = new TextEncoder().encode(JSON.stringify(input)); + let stdinOffset = 0; + const stdoutChunks = []; + let memory = null; + const getView = () => new DataView(memory.buffer); + const wasi = { + wasi_snapshot_preview1: { + fd_write(fd, iovs, iovs_len, nwritten_ptr) { + if (fd !== 1 && fd !== 2) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + if (len === 0) continue; + const chunk = new Uint8Array(memory.buffer, base, len); + const copy = new Uint8Array(len); + copy.set(chunk); + if (fd === 1) stdoutChunks.push(copy); + total2 += len; + } + view.setUint32(nwritten_ptr, total2, true); + return 0; + }, + fd_read(fd, iovs, iovs_len, nread_ptr) { + if (fd !== 0) return 76; + const view = getView(); + let total2 = 0; + for (let i = 0; i < iovs_len; i++) { + const base = view.getUint32(iovs + i * 8, true); + const len = view.getUint32(iovs + i * 8 + 4, true); + const remaining = stdinBytes.length - stdinOffset; + if (remaining <= 0) break; + const toCopy = Math.min(len, remaining); + new Uint8Array(memory.buffer, base, toCopy).set( + stdinBytes.subarray(stdinOffset, stdinOffset + toCopy) + ); + stdinOffset += toCopy; + total2 += toCopy; + } + view.setUint32(nread_ptr, total2, true); + return 0; + }, + proc_exit(code) { + throw new Error(`wasm exit: ${code}`); + }, + random_get(ptr, len) { + crypto.getRandomValues(new Uint8Array(memory.buffer, ptr, len)); + return 0; + }, + fd_seek: () => 76, + fd_close: () => 0, + fd_fdstat_get: () => 76, + fd_prestat_get: () => 76, + fd_prestat_dir_name: () => 76, + environ_get: () => 0, + environ_sizes_get: (cp, sp) => { + if (memory) { + const v = getView(); + v.setUint32(cp, 0, true); + v.setUint32(sp, 0, true); + } + return 0; + }, + args_get: () => 0, + args_sizes_get: (ap, bp) => { + if (memory) { + const v = getView(); + v.setUint32(ap, 0, true); + v.setUint32(bp, 0, true); + } + return 0; + }, + clock_time_get: (_id, _prec, tp) => { + if (memory) getView().setBigUint64(tp, BigInt(Date.now()) * 1000000n, true); + return 0; + }, + clock_res_get: () => 76, + poll_oneoff: () => 76, + sched_yield: () => 0, + proc_raise: () => 76, + sock_accept: () => 76, + sock_recv: () => 76, + sock_send: () => 76, + sock_shutdown: () => 76, + path_open: () => 76, + path_create_directory: () => 76, + path_remove_directory: () => 76, + path_rename: () => 76, + path_unlink_file: () => 76, + path_filestat_get: () => 76, + path_readlink: () => 76, + path_symlink: () => 76, + path_link: () => 76 + }, + // u6u host functions (no-op for pure logic components) + u6u: { http_request: () => 1 } + }; + const instance = await WebAssembly.instantiate(wasmModule, wasi); + memory = instance.exports.memory; + const promising = WebAssembly["promising"]; + const startFn = instance.exports._start ?? instance.exports.main; + if (typeof startFn !== "function") throw new Error("WASM missing _start or main export"); + try { + if (promising) { + await promising(startFn)(); + } else { + startFn(); + } + } catch (e) { + if (!(e instanceof Error && e.message === "wasm exit: 0")) throw e; + } + const decoder = new TextDecoder(); + const total = stdoutChunks.reduce((n, c) => n + c.length, 0); + const merged = new Uint8Array(total); + let off = 0; + for (const chunk of stdoutChunks) { + merged.set(chunk, off); + off += chunk.length; + } + const stdout = decoder.decode(merged).trim(); + if (!stdout) throw new Error("WASM component produced no output"); + return JSON.parse(stdout); +} +export { + index_default as default +}; diff --git a/.worker-builds/arcrun-rag-ui/worker.mjs b/.worker-builds/arcrun-rag-ui/worker.mjs new file mode 100644 index 0000000..0b6daaf --- /dev/null +++ b/.worker-builds/arcrun-rag-ui/worker.mjs @@ -0,0 +1,80 @@ +// arcrun-rag-ui — 用戶實例的 GUI(console-ui/public 內嵌;由 Arcrun scripts/build-ui-worker.mjs 產生,勿手改) +const FILES = {"/apple-touch-icon.png":{"type":"image/png","b64":true,"data":"iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAIAAACyr5FlAAAABmJLR0QA/wD/AP+gvaeTAAATEklEQVR4nO3dd1xTV/8H8JOEERGMILKs4kDA+jjroyxBNipFwFV9LHsoD+JAcLXV2mr9dWhdVauCqAy1sgQnyKiKiKgMkSlLTVCCbDUB8vsjz8tS5ISMk4S+Xt/3X0DOPd8LfJKce++5JxRtHT0EQH+o8t4BMHhBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEQxA3N9ct4WEUCkWqVb7d+Y2To6NUS4iHpqqqJu99GKSmT5t26sRxCwtzY2PDtLRbXV1d0qgSGOC3ccN6FxdnCoWSk3NPGiXEBuHo3+jRn1w8H8tgMBBChhMn2trZpKXdam9vJ1vF2tp6/76fqVQqhUIxMzUZpTfqVkZmT08P2Spio2jr6Ml7HwYdVVXVpMT4ScZGvX/IZLG8vHyLiotJVTEyNExOildT+9uT8/6DB76+AWw2m1QVScCYoy8ajfbb4YN9koEQ0tXRib90wcHBnkgVbW2t6HNRfZKBEJo9a1ZyYoKBwQQiVSQEbyt97f5ul7u7W78PKSkpfe68kMPl5OU9kKQEnU6PPnfG0HBiv4+qqw93c1306HFBff1zSapIDsLxN76+3hs3rBPQgEqlWs610NHRycwUc3BAoVAOHdhvPc9KQBs6ne7u5spmswsKi8QoQcogHXMoKioaGxqOmzBeV0dbc4QmYziD/3Mej9fa0spuYjNZDc+qnpVXVLx//55UURsb66jIUzQaTZjGWdnZgauDWlvbRK2ybcvm4OAgIRsfPvzb3h9/ktcQdXCFQ09Pz9XVxdbG+rOZM5WUlAZsz+V2FRUXZ2Vlp6amljwtlaT0JGOjpMR4VVVV4TcpL6/w8PKuq6sXfpNly5b8uu8XkXYs9cqVkHUb3759K9JWRAyWcEwyNgoN3eDo4CDkE/djjx4X/PbbsStXr/J4PFG31dLSSklO+OSTT0TdkM1m+/j65z3IF6axqYlJXOw5RUVFUasUFBZ6+/ixWA2ibigh+YdjyJAhWzeHe3t7ih2L3vIe5IeFby4vrxB+Ezqd/sfF8zNnTBevIofD2RgaHp+QILjZ+PFjLyclqquri1eFyWR6evoUl5SIt7l45DwgNTI0vHA+1s7Olkolc1A9Sk/vi+XL6uqfl5YK9S5DoVCOHDowz8pS7Io0Gm3+fEcqlZpzD3t+k8FgXDwfp6cn/vNQTU3N3d2trLy8quqZ2J2ISp7hmDvXIi72nI6ODtluFRQUFsx3YjexCwoKB2wcHrbJ0+NLCStSKBRTUxODCePT0m91d3f3eVRRUeHM6chp06ZKWIV/IN3Z2ZGf/1DCroQkt3DMs7I6czpiyJAh0uicQqHYWM8rKSmtrKoS0GzJ4sU7d3xN6rqasbHR3LkWaWnpnZ2dvX/+0//tXbDAiUgJKpU6z8pKW1s7MytLBocw8hlzTJk8OT7+4tChQ6VapaW11drGDjeOGzt2TOatdGGOiURSX1/v6eVbWlbG/3axu/uhg/vJlkAI/fnn7YDANS2trcR77k0OrxzDhqldvBA3cqSmtAvRlZVHjtS8cvVav482N7e0tLbOs7IkNdzhYzAY7u6uT56U1NTUIISqqqpGjRo1+dNPCZZACOnrj3FydMzIzGhubiHbc29yCIe7u9uypUuEbMxkMp+UlBQWFZWVlbNYDVxuF4PBEP7faWRklJSU/OZNc7+PPn5c8PhxgYO9nbKyspAdCkNZWdl1kUtzS/PjxwXd3d3Xrl3v6uoyNzMjOy9EQ0PDzdU1/8HDFy9fEuy2N/m8raxftzZsU6iAP1Z1de2pyIirV68zmcw+D6mqqtrZ2a4O9J86ZYowtY4dP7Hru+8FNDA2Moo6fWr06NHC9CaSyMiob3Z+yx+iOjsvPPjrPjqdTrYEh8PZFLblj0uXyHbLJ58B6b3c+y+ZL21tbD5+Dejq6vpl3/6g4OD8/If9zp/gcDilpWUxsXEIUUxNTQaspa2tdfJUhIAGjWx2UvLl2bP/raerK9JvMaAZM6bPmD71Zlo6h8MpL6/Izv7T3s6W7EiLRqM5OTkoKirevZtDsNv/dS6vo5Xi4ieFRcVOjg69zxi2trZ5+fidv3BxwKE4j8e7m5MzQmPE9OnTBLdkMBiX4uMFvzd3dnbGxyeMG6tv/NGVegmNGzfO3t72VkZGa2sri9VwOeWKhYU52fEWhUIxmTPbyHDizbR0stPV5Hmeo7q6+vbtO46ODioqKgihltbW5ctXinQ1/F7u/ZUrlvM3F+B+Xn55ebngNt3d3VeuXqNQKCYmc8gODjQ1NV0XueTl5TGZrLa2tviExE8nTRo/fhzBEgghQ0NDS0vLtLT0jo4OUn3K+Qwpk8W6ceOGna2tisrQLz288h+KdnqHy+Vqao7896zPBDcrKSnJzb0vTId3c3Jqamrt7GyInMv/YOjQoYvd3Wpqa8vKyjgcTvLllGFqajNnziBYAiGkq6PzufPCO3fuvG5sJNKh/OdzvHnTnHw5pai4OD39lhib83i8pUsWC25TUV55KyNDyA6flpbevZNjb2834AuSSBQUFBYumI8Q717u/Z6enozMrMbGxnlWVmQPpIcNG+bu7lbytLS6ulry3uQfDoRQR0dHWdkAL/s4HM77wAB/wW0qq6quXbsufJ8vXr68cvWq5dy5I0aMEG+v+kWhUMzMTMeN0+efZS8oKHz48LGDvT3ZA2klJaVFLp+3tbc9fPhIwq7+8XNIm5reDNhGUUFB1G5ra+tcXN2ysrPF2ilB3N3cLlyI5ccuKzvbxdVNpBkhwqDRaLt27vhhz24F0X/x3v7x4fj4Qhcpra1tX3p4nzkbTbzn2bNmpSQn8ueQlpdXOLu4CjkjRCSeHqvOnokcNkz8d4Z/fDikqqura8vWbeGbtxK/o0lff0xKcqKtrQ1CqLGxcemyL6RxIsvK0vJKSsr48WPF2xzCMbBz0TEenj5tbSJPFxVMVVX1dMRJb29PhBCHw1m3PnT3D3uJX2vlTzIymTNHjG0lek+SHmVlZX39Mbo6upqamqqqKqof3d/xAdnRPk5mVpab+5Ko0xGjRo0i2C2NRtv93a6x+vq7vtvd3d195MjRFy9e7v/lJ7JDVHV19diYsxs3hSckJIq0ofynCX6gra1lbT3PzNRkxvQZY8fqEzzTkJiYFBQcInk/2tpaEadOzhjonKwY0tLSg4JD+JcLZn02M+LUCU1NwleteTzevv0H9u3/Vfg5tvIPB41Gmz/fyfPLVaamJlJ6GSAVDoQQnU4/dGD/woULiPTWW8nTUk8vnxcvXiCERo/+5ExUpJGhIfEqiYlJG0LDhLyfQ85jDltbm4z0m78f+83c3Ew2bxASevfuXcDqoIMHDxPv+dNJxqmXE/kvS/X1z10WuWdkZhKv4uq66OKFOCFfluT2/6DT6Qf2/3I2KnKQ3BcqPB6PdzY65uO5BJLT0tLy8vLkf93W1nb895PSOFCfOWO6vb2tMC3lEw41NbXzcTFLhZ7yM6jMmD4t9XKiLunr+wihgwcPr98Qyv96xYrlZ6NOk73EgxDq7Oz0D1gTG3temMZyOFqh0Wgnjh8d8GrZ4CS9OTth4Vsu/nEJIUSlUrdt2RwUtJpsCYQQi9Xg5e1bWCTs/bdyCEdAgJ+l5VzZ15VcSEjw5rBNxFeBampq8vULzL1/HyGkoqJy6OD++U5kZqv3VvTkiZenD5PFEn4TWYdDQ0NjwzoyBw6ypKSk9NOPewe8/CuGysoqT2/v6upahJCOjvbpyFNCTn8UyfXrN/67dl2feyYGJOsxx8qVX4h0s/JgoK6uHhcXLY1k3L595/NFbvxkTJk8OTUlWRrJOHrsd1//QFGTgWT/yuHi8rmMK0rIwGBCVGTkuHH6xHuOjondtv0rLrcLIeTo6HDk0AGyM0gQQlxu19bt22Ni4sTbXKbhGD58+ORJk2RZUUIWFuYnjh/lLxtHUE9Pz/e79xw7foL/7ZrVAdu3bSV+mqelpcUvYPWdO3fF7kGm4ZhkbCztNT0J+s/KFXt2f6+oSPhP1NHRERyy/vr1GwghRUWFPbu//8/KFWRLIISqq2s9vLwkvOtapuEge9VKeqhU6vZtW9esDiDeM5PJ9PLyLXryBCHEYDBOHD9qYWFOvMq93Fxfv8A3bwaeBiWYTMOhNuwfMBRVUVE5fOhXaSwp/KTkqaeXz8uXLxFC+vpjzpyOnDjRgHiVpKTk9Rs3EVkNS6bhGPzvKbo6OqejIqZMnky856vXrq0N2cA/ZJgze3bEqd/FXsgFh8fj7f3xp0OHjpDqUKaHsgRvqZCGqVOmpKYkSyMZR44c9Q9Yw0/G0iWLz8dFE0/G27dvA1YHEUwGkvErRwPrlSzLiWS+k9Ohg/ulcDDJ3bx1W1zcBYQQhULZHLYpJCSYbAmEUEPDK28fv8cFBWS7lWk4yitEWKqLIC0trblzLT58W1FR0WfRjqCg1du2bCZ+MNnc3OzrH8hf7p5Opx/8dZ+z80KyJdDfhzJkyXqyT17uXeLHLA0NrzQ0NIQ/5gwNC/9wWVJRUWHvnj0rViwnu0sIoWfPajy9vKqeVSOEtLS0IiOkNYVszX/XSun9Wtanz69fv0m8zx3f7npa+lSMDYcPHx4bfU4aybibc8/ZZRE/Gb1n8ZB14uQpb19/6Y3kZB2O6JgYMdYJFaC9vT09/ZaQt8L2pqurezk50czMlODO8J0/f3HFylXNzc0IIXNzs8SES8RfLPn3TOzYuUt6t+0g2YfjaWlZSkoqwQ7PRcd2dHRcSb0q6oZsNvt142uCe4IQ6unp2f3D3g2hm7hcLv8ndXV17969I1ulpbV1lYeXNO626kMOM8F2fvsd/1klOTabfejwEYRQbl7eo8eijdU5HI6fX2BNTR2RPUH8g8nAoCNHjvb+YX39cx9ff4ILtNfW1i1ydc/O/pNUhwLIIRxMFmtN0Fr+1UhJdHd3h6zb+OEk8ddffyPqfWlNTU0eXl5E1uRjsRrc3JdeudrPC9iD/IcbQsOIvJnef/DA2cVVpPWZJSGfu+xra2vLysqdHB3EvtO3q6srdFN46pW//hlMFqupqcnWxmbA87A3bt4sLn7C/7qp6U1hYZHrokU0mvjPk+KSkqXLVlTh1zwtLS2jUJCZqUTjm/iEBD//1cQ/SkwAuS3BUFlZmZmZZTJnjoaGhqjbPn/+3Nc/8PqNvgc+BQWF1TU1FhbmdIF3jPUOB0Korq6usbHR3t5O1N34X283bnp4+jQ1NQludu9e7vhxYydNMhajBI/H+/mXfdIefn5MnutzNDQ0nIuOYTexJxoYCDln4vXr1wcPHwlZt6G6uqbfBqWlpTExcc0tzfQh9GFqav3eV9gnHAihwqIiVVW1WZ/NFPVXOHb8RGhYOIfDEaZx+q0Mc3OzUSKugP7+/fvgkPVRUWdF3TfJyf+ON4QQlUqdM3u29TyrmZ/NNJxo0OeWm/b29orKqkcPH6VnZN6+/afkgxXcPkSc/F34j3Djcru2bf8qOiZWpCqampopyYljxgi7rOXr1699fP3zJV6GRTyDIhx9KCsrMxiMIUPoXG5XS0uLzC7XDR06NCHhj38JsdpwS0uLf+Ca27fviFHFyNAwKTFemGUzSsvKPDx9nj+X2ye9DcZwyJGOjnbq5STBNyzV1tZ5eHlXVFSKXcXK0vLsmUjBg3GxPyaMoEGxJtjg0d7ekZNzb7G7G+7zlPIe5H+xcpWEz+ba2tqGV68c7LFvYeeiY4LXrnv7lvDZM1FBOPp69epVZeUzZ+cFHx8SJydf9vULILKKS1FR8XDG8I9Xm+zu7t7x7a4ff/x5MHwuNYSjHxWVlRwud67FX1f5+YtbfPX1DoLrP2VlZ/9r8uQJE/66j7yjo8M/cM2lS/GkSkgIwtG/+/fztLW1p06dgvhrMm0IjYg8TbYEj8dLS79lY2OjNXIkQojJZK5Ysepebi7ZKpKAASmWoqJCzLmzEycaePv4iXrhRni6OjopKUlMJsvbx+/1a8IXAiUE4RBEXV1dRUWFv9qO9BgYTKivf07w4hwpEA6A9Q9YaQnIC4QDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOAAWhANgQTgAFoQDYEE4ABaEA2BBOADW/wPYvdSqRewFmQAAAABJRU5ErkJggg=="},"/console/dashboard/index.html":{"type":"text/html; charset=utf-8","b64":false,"data":"\n\n\n\n\nArcrun 駕駛艙\n\n\n\n\n\n\n
\n
\n
Arcrun 駕駛艙
\n
\n
\n \n
\n
\n
\n
\n
\n
載入中
\n
\n
\n
\n
\n
\n
今日完成
\n
/
\n
\n
\n
\n
收件匣未處理
\n
\n
來自 Telegram
\n
\n
\n
\n
等你的事
\n
載入中…
\n
\n
\n
今日路線
\n
  • 載入中…
\n
本週
\n
    \n
    系統狀況live 健康信號
    \n
    載入中…
    \n
    每 60 秒自動刷新
    \n 進入完整控制台 ›\n
    \n\n\n\n"},"/console/index.html":{"type":"text/html; charset=utf-8","b64":false,"data":"\n\n\n\n\nArcrun Console\n\n\n\n\n\n\n\n\n
    \n
    \n
    \n
    Arcrun
    \n
    私人系統・僅供擁有者進入
    \n
    \n
    \n \n \n \n
    \n
    \n
    這是一個人的智慧總部。
    若你不是擁有者,這裡沒有你要找的東西。
    \n \n \n
    \n
    \n\n\n
    \n
    \n
    \n
    Arcrun
    \n
    首次設定
    \n
    系統偵測到尚未設定擁有者帳號。
    設定一組 Email 與密碼,之後只有你能進入。
    \n
    \n
    \n \n \n \n \n
    \n
    \n \n
    \n
    \n\n\n
    \n
    \n
    Arcrun
    \n \n
    總庫搜尋
    \n
    工作流
    \n \n
    設定
    \n
    ☾ 切深色
    \n
    \n
    \n
    \n\n \n
    \n
    Arcrun 控制台
    \n
    \n
    \n
    \n
    \n
    \n
    載入中
    \n
    \n
    \n
    \n
    \n
    \n
    今日完成
    \n
    /
    \n
    \n
    \n
    \n
    收件匣未處理
    \n
    \n
    來自 Telegram
    \n
    \n
    \n
    \n
    等你的事
    \n
    載入中…
    \n
    \n
    \n
    \n
    \n
    \n 今日路線狀態即時同步\n
    \n
    • 載入中…
    \n
    本週
    \n
      \n
      每 60 秒自動刷新
      \n
      \n
      \n
      \n\n \n
      \n
      總庫搜尋
      \n
      \n
      \n
      \n 藏書地圖\n
      \n
      地圖載入中…
      \n
      \n
      \n
      \n \n \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n\n \n
      \n
      \n \n 知識卡片\n
      \n
      \n
      載入中…
      \n
      \n
      關聯視圖
      \n
      \n
      \n
      \n
      \n
      \n\n \n
      \n
      工作流
      \n \n
      載入中…
      \n
      \n
      零件與 Recipes(框架資源)
      \n
      \n \n \n
      \n
      \n
      \n
      \n\n \n
      \n
      憑證管理
      \n
      \n 🛡 保險箱原則:系統只保存目錄與加密後的值,任何頁面都看不到密文內容。只能整筆替換或刪除。\n
      \n
      \n
      新增憑證
      \n
      \n \n \n \n \n
      \n
      \n
      \n
      載入中…
      \n
      \n\n \n
      \n
      分流台全部待辦・80/15/5
      \n
      \n
      載入中…
      \n
      \n\n \n
      \n
      設定
      \n
      \n
      \n
      \n
      \n
      深色模式
      \n
      預設淺色(紙感)。切換立即生效,選擇記在這台裝置(localStorage)。
      \n
      \n
      \n
      \n
      \n
      \n \n
      語意搜尋
      \n
      狀態偵測中…
      \n
      \n
      \n
      \n
      MCP token 有效期(TTL)
      \n
      讀取中…
      \n
      \n 誠實佔位:此頁還不能改這個值——可調功能=Arcrun#19(設定頁改→存 KBDB→發 token 時讀)。實作前要調整請在部署端 env MCP_TOKEN_TTL(mcp worker)設定。\n
      \n
      \n
      \n
      更換帳號密碼
      \n
      需輸入舊密碼驗證身分
      \n
      \n \n \n \n \n
      \n
      \n
      \n \n
      \n
      Portal 帳號密碼救援
      \n
      忘記某個 Portal(RAG 搜尋頁)帳號的密碼,包含你自己那組管理員帳號——不需要先登進 Portal。輸入該帳號的 Email,會產生一組新密碼,只顯示這一次,請立刻抄下並拿去 Portal 登入頁使用。
      \n
      \n \n \n
      \n
      \n
      \n
      \n
      系統資訊
      \n
      載入中…
      \n
      \n \n
      \n
      \n\n
      \n
      \n\n\n
      \n \n
      搜尋
      \n
      工作流
      \n \n
      設定
      \n
      \n\n
      \n\n\n\n\n"},"/favicon.ico":{"type":"image/x-icon","b64":true,"data":"AAABAAMAEBAAAAAAIAAZAgAANgAAACAgAAAAACAAcAQAAE8CAAAwMAAAAAAgAPQDAAC/BgAAiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB4ElEQVR4nLWTz24SURTGzx3+hUGgA43AVKPEN9AYdacmdWMXoEbd1prUF6CNu6q4dsFGI6+gJCxY1roAqV2SqCun1Y3gRuxMCCkznzkHx0xsjSaNX3Iz351zzy93zjmjcnkTdAhph0n+PwCllCxfoVDo1z7oDwRomkae55HruuJZw+FQ3vE+6PcBlFLkOA5FIhGKx+Nk2zYBoHK5RLFYjGzHoRvXr4kfjUZyG1Eub6JgHkMyNYObt26j3W5ja+stFhfvoFQqg9VsNrG0dFf8q/V1FIunkDiSkjxiQL4wByMzi3PnL2B+/grW1h7gw/t3OHGyiHq9LomfP+3gTacDwEOv18PFS5eRnT06BTAplTZQqazA+mjBtm1sbnZ5PnD6zFkMBn3A89BoNLBtWQKs1WpIJNNTgDl3HHoiidcbGxKc7O1hZ9vC8vI9DL8N4boTtFotfB0MJF6tPkZ6JoN8wUSY68CV5eJUVu/TwsJV6na7ZBgGaUqjfv8Lraw+oXanQ42XL+jhoyo9ffacstnMtPi5n6PMXRiPx1LhaDQqrWQxiDvCrUvoOn3f3SVd16VDvFTwX2AIH5SAUvKcTCYUDofFM5Q939iXfIIv/1BQ3G8/Iej/OMq/i6EH+X8G/E0/AKIBFUjISo/5AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEN0lEQVR4nO1WXUwcVRT+ZvZvll26doEuhVJflFgfpDWQBkOV+ER/XkpjrRoppUQTpeKTae2PYgkt/pREgaKxtcWEygOpPFgaU0l9qGkrTVmXkLIlUiJKbEgK7i4zs7O7x9yzDiHbRaxpwgsnObl3vnvnnDPfOefekXy5eYQlFHkpnS8HsMzAMgMPhQFJklj/K/5Q21CSJCQSCdb5zhbCHzgAWZbZABGxmpjpJB6Pw2q1suq6DovFsiD+wAHIkgRVVVmFU4tFRiwWQyQSmfuqcCSC+rfqcK7ra+T6fAiHw+wsFQ+Fknha8eXmUarmrs6nld5s2vB0MbW3n6TBmzfpF7+fenp6aHvlDsrKXkXerBx6s24fGVGdhAQCQ1Re/jzZ7ArV179NhhFlfCgwRM8+V04u9wrKyy+4zxfSOc/O8VFh4RM0PDzMRkZvB2ls7Feea6pKFZs38x6/f5CxcOgvHu/e/ZN2766mHy9f5udIODyHv7TrZXJmZLJ9oaY/OZURkWtB173paXzT3Y39Bw6gZOMzWL+hGF1dXXAoCrZt3ca5ra19HdevX4PLnYmYEUVOzip0dLTD7w+gv78fGS4XYrEkfvbsV9hX9wbC4QhisTjM2pTTpcUsvKamZpw6dRpr1xbA5/NhcnKS8cxMN+x2O26PjuLFXa+gt7cXBAlRXWO89rW9CAaD6OvrA5EEI6rDYrWgufk4jja8B6dTgahprqV0KeAxN4+OHD5C4+PjpM5GWDV1lint7OzkGlhT8CiPnpVZ9NOVK7ymayrFYwbPDx46TJcu/cDzqKaSrms8b2xspBUeL63OW0PWdK03MzODHZXb0fBBQzItCUGZBMMw5tIknjVN43QdOvguitYXIR4zuPVkixXfnj+PwscfQ0lJMeOSLMNmszNbXee64XDY2Y41XQ0I40+uW4d4PIGoNgubPbnZHC1ysiW9Xi8+/qgZlZWViBsGJEnmw+fMmdNwZ7pRVVWVdC5JsFhtaG1txfsNR3mPw+FIH4D0T/5vBUe4950u99yaf3AQRUVP4YWdO3FrJIjS0o3YsmUrdE2FQ3FC1zU0NR1DaWkpKioqOPc2u4MLdP+Bd/D5F19CURSuExFE2iIUCy6XCxcvfo8TJ1owMjKCO3fGcOG7C6iuqcUnLS0IBAKYnr6Hq1evCcq4M6amprBnTy2OHf8QgcAQ2xKMCfzVqmq0tXewXZFi0zl/8EI/pYIFcQrm5+fDoTgw8dsEH7HxRAIZiqhiwqyq4mTbZygrK0N1zV4MDNyAx+NBKBRCW+un2FS2CdU1Nfh54AYe8Xj4/fsY9/3LX7GINhqNsjNBm3kEm5eMqAO32w2nomDi9z+4PcVaOjyd80UDMGsi9UIyn+ffejabbY7ahfB0YsUiMt/xfMwcBUupeV0I/18BLCapwS2Gp4qMJRZ5OQAspwBLK38DPGKRRP2boyYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAMAAAADAIBgAAAFcC+YcAAAO7SURBVHic1ZdZTFNBFIb/TkuAJkjCLkhJShUkhbi+i3EpGhfUBxOjUKhYKcZE466h4vZoZBGjFOoKFNAiEq3iAoIUFBMViWLQqHF5gYSCJMiiuWOsqVwupUXJfMlNZub8mXvOnTNn5oqCQ0J/gGEIGIeAcQgYh4BxCBiHgHEIGIeAcQgYh4BxCBiHgHEIGIeAcQgYh/yPl6SmqhEQEOC2ZlICSElJxpHDety4bkbUjBkua0ZDNN4/svgFC6BSLUGETAaRSARbjw0tLU9RVn4VnZ2djtr4eFwwGiAWi2nfZuuBdqsOD2prx6WZkAC8vLyQl3sKCSoVr727uxvqlM2wNjXRfnRUFCrNFfDx8XHQDQ4O4lCmHufPX3RKM2EptGvnDrvzfX19aLRaYW1uRn9/Px3z9fXFmfxcGiiHXC6Hp6fniHkkEglOHDtKU0YxXTGm5vfKuL0CnINGo4G2NZot9nSJjJTDcrMaUqmU9pPUqbhzp4a258+bi0LDOfj7+/POee/efRQYipCTfVJQo03PQG9vr3srwKXI+vUbkJSkdsj1jo63sFp/pQ1HePg0e/vxkxYsX7EK7e1veOdcuDAeBw/uR5o2XVBjvlaBsLAw9wLg4NKF22QeHh4IDQ1FRISMPiLRH43kryX/8OEjVq5ORG1dHe+cMTOjkZ+Xg0x9lqCmusqMObNnuRfA2jVrUHXdjI43r/CkuRGNDQ/pw1USIbigN25So7i4lNceFBSEosJzuHS5WFBTXlYK1dKlDuMSZ53fv3cPMjLS4SqBgYFQxilHtX/69BldXV1jal63vxp/AH5+ftBq0+AqcbGxMBYZEBISzGtvaHiE7Nw85OVkC2o0aVq6F8cdgEIup6XNFZYlJNAq4+3tzWu/cqUEdfX1MBYWCGr2HTiAgYHBETanvPrW981ph+XySChjYtDa1gadbiv27dkNQkZuteHhYRw7fgJELMbp3GxBTf6Zs+6dA9xh0vCwFjJZOK+9oKAQGk2KvV9Tc5d+1Sx9Jq+eOwh127bTkjuWxmK5LeibU1VoaGgIuoxtdJP9TUmJCfqsI7hlsTiMm0xlvLX9y9evSExcRx0zOaGZ0MvclCk+WLxoMUKmBmPg+3c0NT3Gs+fP7XaFIhJSbyl6em149+49XbHqqkr7KfuitRXJyanUwd/InNBMWACuwF0nTKXFtIqMdiWY74Rm0gLgiFUq8bKtjW5KdzSTFsC/hIBxCBiHgHEIGIeAcQgYh4BxCBiHgHEIGIeAcQgYh0y2A+7yE3xdjklMPM/hAAAAAElFTkSuQmCC"},"/favicon.svg":{"type":"image/svg+xml","b64":false,"data":"arcrun icon"},"/index.html":{"type":"text/html; charset=utf-8","b64":false,"data":"\n\n\n\nArcrun RAG\n\n\n\n\n\n\n\n

      正在前往搜尋頁… 沒有自動跳轉請點這裡

      \n\n\n"},"/portal/index.html":{"type":"text/html; charset=utf-8","b64":false,"data":"\n\n\n\n\nArcrun Portal\n\n\n\n\n\n\n\n\n\n\n\n
      \n
      \n
      \n
      \"arc>run\" width=\"986\" height=\"176\">\"arc>run\" width=\"986\" height=\"176\">
      \n
      知識入口・Portal
      \n
      \n
      \n \n \n \n
      \n
      \n \n \n
      \n \n \n
      \n
      \n \n
      \n
      \n\n\n
      \n
      \n
      \n
      設定新密碼
      \n
      \n
      \n
      \n \n
      \n
      \n
      \n\n\n
      \n
      \n
      \n
      \"arc>run\" width=\"986\" height=\"176\">\"arc>run\" width=\"986\" height=\"176\">
      \n
      歡迎!先建立你的帳號
      \n
      \n
      \n \n \n \n \n
      \n \n \n
      \n
      這組帳密就是之後登入知識庫用的,只需要設定這一次。
      \n
      \n
      \n\n\n
      \n
      \n
      \"arcrun\"\"arcrun\"
      \n
      搜尋
      \n
      總圖
      \n
      上傳
      \n
      工作流
      \n
      管理
      \n
      設定
      \n
      ☾ 切深色
      \n
      \n
      \n
      \n\n \n
      \n
      搜尋
      \n
      \n
      \n \n \n
      \n
      \n \n \n \n
      \n \n
      \n
      AI 問答・答案附出處,可回搜尋驗證
      \n
      \n \n \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n
      \n\n \n
      \n
      總圖
      \n
      \n
      \n
      \n 點節點可跳到該實體的圖譜搜尋。這張圖由知識庫的三元組即時算出——同一份地圖的文字版\n (給 AI 注入用的總庫目錄)。\n
      \n
      \n
      \n\n \n
      \n
      \n \n 知識卡片\n
      \n
      載入中…
      \n
      \n\n \n
      \n
      上傳Markdown / 純文字
      \n
      \n 上傳的文件會進入知識庫收件管線:約 1 分鐘後可在搜尋頁找到;AI 整理後會以 wiki 卡形式出現。支援 .md / .txt(一律以 .md 收件)。\n
      \n
      \n
      把 .md / .txt 檔案拖放到這裡
      \n
      \n \n \n
      \n
      \n
      \n\n \n
      \n
      工作流唯讀・系統狀態
      \n
      \n 此頁只顯示系統裡的工作流與最近執行狀態,不能觸發執行(觸發屬系統擁有者權限)。\n
      \n
      載入中…
      \n
      \n\n \n
      \n
      設定
      \n
      \n \n
      \n
      \n
      \n
      \n 版本\n \n
      \n
      查詢中…
      \n
      \n \n
      \n
      \n
      \n
      我的帳號
      \n
      載入中…
      \n
      \n
      \n
      \n
      \n
      深色模式
      \n
      預設淺色(紙感)。切換立即生效,選擇記在這台裝置。
      \n
      \n
      \n
      \n
      \n \n
      \n
      更改密碼
      \n
      需輸入舊密碼驗證身分;新密碼至少 8 碼
      \n
      \n \n \n \n \n
      \n
      \n
      \n \n
      \n \n
      \n 你的知識庫網址(小幫手連線用)\n \n \n
      \n
      同步小幫手
      \n
      把你電腦上的資料夾變成知識庫。換電腦或重裝時可以再下載一次。
      \n
      \n 下載 Mac 版\n
      封測版未簽章,第一次請右鍵→打開。裝好第一次開啟時,貼上這個網址+你的帳號密碼就連上了。
      \n
      \n
      \n \n
      \n
      \n 你的 MCP 網址(給你的 AI 連線用)\n \n \n
      \n
      接上你的 AI(MCP)
      \n
      把上面這串網址貼到 Claude、ChatGPT 等 AI 的「新增自訂連接器」欄位,就能讓你的 AI 直接查這個知識庫。
      \n
      \n \n
      \n
      AI 設定
      \n
      \n 這裡不需要任何設定。聊天問答用的是你自己 Cloudflare 帳號內建的 AI,裝好就能直接問。
      \n 文件整理成知識卡的部分,請在同步小幫手(電腦上的托盤圖示)的「AI 設定…」填一把 Gemini API Key。\n
      \n
      \n \n
      \n
      疑難排解
      \n
      要回報問題,請到你電腦上的 Arcrun(同步小幫手)「版本與更新」頁——那裡的「疑難排解」按一下就能匯出完整診斷檔給我們(只有統計數字,不含你的任何文件內容)。
      \n
      \n \n
      \n
      \n\n \n
      \n
      管理帳號與知識庫授權
      \n\n
      執行紀錄保留期
      \n
      \n
      保留天數
      \n
      執行紀錄是稽核資料,超過保留天數會被每日自動清除;預設 90 天(3 個月),也可設為「不刪除」(企業稽核用途)。
      \n
      \n \n \n \n
      \n
      \n
      \n
      \n\n
      帳號管理
      \n
      \n
      新增同仁帳號
      \n
      建立後會產生一組一次性密碼——只顯示這一次,請當場轉交同仁(同仁可在「設定」自行改密)。
      \n
      \n \n \n \n \n
      \n
      \n
      \n
      \n
      載入中…
      \n\n
      庫目錄管理
      \n
      \n 你的知識庫網址(小幫手連線用)\n \n \n
      \n
      \n \n 裝好同步小幫手並選好要看守的資料夾之後,每個資料夾會自動成為一個「庫」出現在下面——不需要人工新增。下面還是空的,代表小幫手還沒裝好或還沒選資料夾。\n
      \n
      載入中…
      \n
      \n\n
      \n
      \n\n\n
      \n
      搜尋
      \n
      總圖
      \n
      上傳
      \n
      工作流
      \n
      管理
      \n
      設定
      \n
      \n\n
      \n\n\n\n"},"/portal/os-split.test.mjs":{"type":"application/javascript; charset=utf-8","b64":false,"data":"import fs from 'node:fs';\nconst html = fs.readFileSync(new URL('./index.html', import.meta.url).pathname,'utf8');\n// 抽出 daemonPick 相關函式(從 DAEMON_BASE_DEFAULT 到 daemonHint 結尾)\n//\n// 🔴 2026-08-05:結尾標記本來寫死 daemonHint 的**整句文案**,於是同日改 Mac 提示語\n// (zip→DMG 的步驟不同)就讓這支自測直接炸「抽不到函式區塊」,而且沒人發現。\n// ⇒ 改成錨定「函式結束」這個結構,不再綁文案——文案本來就會改,測試不該為此壞掉。\nconst start = html.indexOf('var DAEMON_BASE_DEFAULT');\nconst hintAt = html.indexOf('function daemonHint', start);\nconst endMark = '\\n }';\nconst end = hintAt < 0 ? -1 : html.indexOf(endMark, hintAt) + endMark.length;\nif (start < 0 || hintAt < 0 || end < start) throw new Error('抽不到函式區塊');\nconst src = html.slice(start, end);\n\nconst cases = [\n ['Windows', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120 Safari/537.36'],\n ['Mac', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Safari/605.1.15'],\n ['iPhone', 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 Safari/604.1'],\n ['Linux', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120 Safari/537.36'],\n];\nlet pass=0, fail=0;\nconst chk=(l,c,extra='')=>{ if(c){console.log('PASS:',l);pass++;} else {console.log('FAIL:',l,extra);fail++;} };\n\nfor (const [name, ua] of cases) {\n const fn = new Function('navigator','window', src + '; return {daemonPick:daemonPick, daemonHint:daemonHint, daemonBase:daemonBase};');\n const api = fn({userAgent: ua}, {});\n const d = api.daemonPick();\n const label = d.sure ? d.pick.label : '(兩個都給)';\n const url = d.sure ? d.pick.url : d.mac.url + ' + ' + d.win.url;\n console.log(`\\n[${name}] sure=${d.sure} → ${label}`);\n console.log(` url: ${url}`);\n if (name==='Windows') {\n chk('Windows 給 win zip', d.sure && d.pick.url.endsWith('ArcrunRAG-win-unsigned.zip'), d.pick&&d.pick.url);\n chk('Windows 另一版是 Mac', d.other && d.other.url.endsWith('ArcrunRAG-mac.dmg'));\n chk('Windows 話術提 藍色視窗', api.daemonHint('win').includes('仍要執行'));\n }\n if (name==='Mac') {\n // 2026-08-05:Mac 一律給 DMG(拖進 Applications 的標準安裝畫面),不再給 zip\n // ——zip 解開就是一個裸 .app,使用者會直接在「下載」資料夾雙擊執行,自更新會蓋錯位置。\n chk('Mac 給 dmg(不是 zip)', d.sure && d.pick.url.endsWith('ArcrunRAG-mac.dmg'));\n chk('Mac 另一版是 Windows', d.other && d.other.url.endsWith('win-unsigned.zip'));\n chk('Mac 話術提 右鍵打開', api.daemonHint('mac').includes('右鍵'));\n }\n if (name==='iPhone' || name==='Linux') {\n // iPhone 含 \"Mac OS X\" 但不是桌機 Mac;Linux 兩者皆非 → 都該落在「不確定=兩個都給」\n if (name==='Linux') chk('Linux 判不出來→兩個都給', d.sure===false);\n if (name==='iPhone') chk('iPhone 不該被判成 Mac(手機→兩個都給)', d.sure===false, 'sure='+d.sure);\n }\n}\n// 舊 key 相容\nconst fn2 = new Function('navigator','window', src + '; return daemonBase();');\nconsole.log('\\n[相容] daemonDownload 舊 key →', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonDownload:'https://x.dev/d/ArcrunRAG-mac-unsigned.zip'}}));\nchk('舊 key 推得出目錄', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonDownload:'https://x.dev/d/ArcrunRAG-mac-unsigned.zip'}})==='https://x.dev/d/');\nchk('daemonBase 新 key 優先', fn2({userAgent:''},{ARCRUN_CONFIG:{daemonBase:'https://y.dev/z'}})==='https://y.dev/z/');\nconsole.log(`\\n=== ${pass} passed, ${fail} failed ===`);\nprocess.exit(fail?1:0);\n"},"/portal/safejson.test.mjs":{"type":"application/javascript; charset=utf-8","b64":false,"data":"import fs from 'node:fs';\nconst html = fs.readFileSync(new URL('./index.html', import.meta.url).pathname,'utf8');\n\n// 抽出 safeJson 與 friendlyErr 求值\nconst grab = (name) => {\n const i = html.indexOf(`function ${name}(`);\n if (i < 0) throw new Error(`找不到 ${name}`);\n let d=0, j=html.indexOf('{', i);\n for (let k=j;k{c?(console.log('PASS:',l),pass++):(console.log('FAIL:',l,e),fail++)};\n\n// ① safeJson:非 JSON 不可拋例外(同事撞到的 404 HTML 頁)\nconst html404 = '404 Not Found';\nawait fn.safeJson({ text: () => Promise.resolve(html404) })\n .then(d => t('404 HTML → 回空物件不拋錯', typeof d === 'object' && d !== null))\n .catch(e => t('404 HTML → 不該拋錯', false, e.message));\n\nawait fn.safeJson({ text: () => Promise.resolve('') })\n .then(d => t('空回應 → 回空物件', JSON.stringify(d)==='{}'))\n .catch(() => t('空回應 → 不該拋錯', false));\n\nawait fn.safeJson({ text: () => Promise.resolve('{\"error\":\"帳號或密碼不對\"}') })\n .then(d => t('正常 JSON 仍要解析得出來', d.error === '帳號或密碼不對'), )\n .catch(() => t('正常 JSON 不該拋錯', false));\n\n// ② friendlyErr:不可把技術訊息噴給使用者\nconst leak = fn.friendlyErr(new Error('Unexpected non-whitespace character after JSON at position 4'));\nt('JSON 錯誤 → 不外洩原文', !/JSON|position/i.test(leak), `實得: ${leak}`);\nt('JSON 錯誤 → 說人話', /伺服器回應異常/.test(leak), `實得: ${leak}`);\n\nconst net = fn.friendlyErr(new Error('Failed to fetch'));\nt('網路錯誤 → 既有訊息保留', /連線中斷/.test(net), `實得: ${net}`);\n\nconst ours = fn.friendlyErr(new Error('帳號或密碼不對——用你在知識庫網站設定的那組'));\nt('我們自己的中文訊息 → 原樣顯示', /帳號或密碼不對/.test(ours), `實得: ${ours}`);\n\nconst stack = fn.friendlyErr(new Error('TypeError: Cannot read properties of undefined'));\nt('英文技術訊息 → 收斂不外洩', !/TypeError|undefined/.test(stack), `實得: ${stack}`);\n\nconsole.log(`\\n=== ${pass} passed, ${fail} failed ===`);\nprocess.exit(fail?1:0);\n"}}; +const UI_FINGERPRINT = "82bc636990e60172663f7ce90c75d8b434193b8532b21f1d4b57c5fb330cbe11"; +function b64ToBytes(b64) { const bin = atob(b64); const a = new Uint8Array(bin.length); for (let i = 0; i < bin.length; i++) a[i] = bin.charCodeAt(i); return a; } +export default { + async fetch(request, env) { + const url = new URL(request.url); + let p = url.pathname; + // 🔴 UI 自報版本(安裝器據此判斷要不要重推,取代「猜 favicon 特徵」)。 + // 比照 cypher 的 /health。舊世代的 UI 沒有這條路由 ⇒ SPA fallback 回 HTML + // ⇒ 安裝器解析 JSON 失敗=判定為舊版=重推。**天然向後相容,不需額外世代判斷。** + // bundle_version 由安裝器以 ARCRUN_BUNDLE_VERSION 注入(cypher /health 同一個值); + // 沒注入就回空字串,安裝器那端把空值一律當「舊的」處理。 + if (p === '/__version') { + // 🔴 2026-08-08:多報 worker_subdomain / config_ok 兩格。 + // 這條路由是**安裝器唯一會去問實例的地方**(probeInstanceStale), + // 以前它只報版本 ⇒「版本對、但 apiBase 空」的實例在安裝器眼中是「已是最新」 + // ⇒ 永遠不會被重推=壞掉的實例自己好不了。報了之後,安裝器把 + // config_ok:false 一律當成 stale ⇒ **下一次安裝/更新就自動治好它**。 + return new Response(JSON.stringify({ + ok: true, + ui_fingerprint: UI_FINGERPRINT, + bundle_version: env.ARCRUN_BUNDLE_VERSION || '', + worker_subdomain: env.WORKER_SUBDOMAIN || '', + config_ok: Boolean(env.WORKER_SUBDOMAIN), + }), { + headers: { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' }, + }); + } + // config.js 動態產生:apiBase 指向同帳號的 cypher(WORKER_SUBDOMAIN 由安裝器注入) + // + // 🔴 2026-08-08 事故(leo 的 youlin 實例整頁不能用,頂端紅字「設定檔沒載入」): + // 有人用 wrangler deploy 手動補這顆 worker ⇒ 繞過安裝器的變數注入 + // ⇒ WORKER_SUBDOMAIN 空 ⇒ 這裡**安靜地**退成 apiBase:""(而且回 HTTP 200!) + // ⇒ 前端連不到自己的後端,但**部署是「成功」的**:worker 活著、curl 200、 + // /__version 版本也對——只有真人打開瀏覽器才看得出壞了。 + // 正解不是「退一個合理的預設值」(沒有合理預設,猜錯更慘), + // 是**大聲失敗**:回 500+專用標頭,讓機器檢查一眼看穿。 + // 瀏覽器不執行非 2xx 的