diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d5659cd2..ab35af7e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,4 +71,4 @@ jobs: - name: Build wws on release mode run: cargo build --verbose --release - name: Test - run: cargo test --workspace --exclude wasm-workers-quick-js-engine -- --show-output + run: cargo test --workspace -- --show-output diff --git a/Cargo.lock b/Cargo.lock index d20b4f3d..9b3d6758 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,29 +397,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.60.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "clap 3.2.25", - "env_logger 0.9.3", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "which", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -596,47 +573,12 @@ dependencies = [ "libc", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clang-sys" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "strsim", - "termcolor", - "textwrap", -] - [[package]] name = "clap" version = "4.4.6" @@ -655,7 +597,7 @@ checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.1", + "clap_lex", "strsim", ] @@ -671,15 +613,6 @@ dependencies = [ "syn 2.0.37", ] -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clap_lex" version = "0.5.1" @@ -1074,19 +1007,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime 2.1.0", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.10.0" @@ -1334,12 +1254,6 @@ dependencies = [ "url", ] -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "h2" version = "0.3.21" @@ -1419,15 +1333,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys", -] - [[package]] name = "http" version = "0.2.9" @@ -1631,18 +1536,6 @@ dependencies = [ "cc", ] -[[package]] -name = "javy" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "407ec70e152460c246509dc086b97017ed52d453e49993059ce369ab609e34a4" -dependencies = [ - "anyhow", - "quickjs-wasm-rs", - "serde-transcode", - "serde_json", -] - [[package]] name = "jobserver" version = "0.1.26" @@ -1679,12 +1572,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128" version = "0.2.5" @@ -2024,12 +1911,6 @@ dependencies = [ "pretty_env_logger", ] -[[package]] -name = "os_str_bytes" -version = "6.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" - [[package]] name = "parking_lot" version = "0.12.1" @@ -2065,12 +1946,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.0" @@ -2204,29 +2079,6 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -[[package]] -name = "quickjs-wasm-rs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a318ed47e42082c11771620a1235231f34c10f775f4972dbc7753d4b07d8d568" -dependencies = [ - "anyhow", - "once_cell", - "quickjs-wasm-sys", - "serde", -] - -[[package]] -name = "quickjs-wasm-sys" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f72b064defce86eb257f5505ff22604f67d6b1036e995ac703cfdbe378e2df92" -dependencies = [ - "bindgen", - "cc", - "walkdir", -] - [[package]] name = "quote" version = "1.0.33" @@ -2538,15 +2390,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-transcode" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" version = "1.0.188" @@ -2634,12 +2477,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "shlex" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2785,12 +2622,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.49" @@ -3251,15 +3082,6 @@ dependencies = [ "leb128", ] -[[package]] -name = "wasm-workers-quick-js-engine" -version = "0.1.0" -dependencies = [ - "anyhow", - "javy", - "wit-bindgen-rust", -] - [[package]] name = "wasm-workers-rs" version = "1.6.1" @@ -3279,7 +3101,7 @@ version = "1.6.1" dependencies = [ "actix-web", "anyhow", - "clap 4.4.6", + "clap", "env_logger 0.10.0", "prettytable-rs", "reqwest", @@ -3730,18 +3552,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "wiggle" version = "13.0.0" diff --git a/Cargo.toml b/Cargo.toml index 432b6bbd..35e3f74c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,6 @@ members = [ "crates/worker", "kits/rust", "kits/rust/worker", - "kits/javascript", ] # Exclude examples exclude = [ @@ -71,6 +70,8 @@ exclude = [ "examples/rust-pdf-create", "examples/rust-wasi-nn", "examples/rust-wasi-nn-preload", + # It uses incompatible crate versions + "kits/javascript", ] [workspace.dependencies] diff --git a/examples/js-hono/dist/[...app].js b/examples/js-hono/dist/[...app].js index e13f03cc..5b1dd907 100644 --- a/examples/js-hono/dist/[...app].js +++ b/examples/js-hono/dist/[...app].js @@ -1,1609 +1,2 @@ -(() => { - // node_modules/hono/dist/types.js - var FetchEventLike = class { - }; - var FetchEvent = class extends FetchEventLike { - }; - - // node_modules/hono/dist/utils/url.js - var splitPath = (path) => { - const paths = path.split("/"); - if (paths[0] === "") { - paths.shift(); - } - return paths; - }; - var splitRoutingPath = (path) => { - 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 paths = path.split("/"); - if (paths[0] === "") { - paths.shift(); - } - 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].indexOf(mark) !== -1) { - paths[j] = paths[j].replace(mark, groups[i][1]); - break; - } - } - } - return paths; - }; - var patternCache = {}; - var getPattern = (label) => { - if (label === "*") { - return "*"; - } - const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/); - if (match) { - if (!patternCache[label]) { - if (match[2]) { - patternCache[label] = [label, match[1], new RegExp("^" + match[2] + "$")]; - } else { - patternCache[label] = [label, match[1], true]; - } - } - return patternCache[label]; - } - return null; - }; - var getPath = (request) => { - const match = request.url.match(/^https?:\/\/[^/]+(\/[^?]*)/); - return match ? match[1] : ""; - }; - var getQueryStrings = (url) => { - const queryIndex = url.indexOf("?", 8); - return queryIndex === -1 ? "" : "?" + url.slice(queryIndex + 1); - }; - var getPathNoStrict = (request) => { - const result = getPath(request); - return result.length > 1 && result[result.length - 1] === "/" ? result.slice(0, -1) : result; - }; - var mergePath = (...paths) => { - let p = ""; - let endsWithSlash = false; - for (let path of paths) { - if (p[p.length - 1] === "/") { - p = p.slice(0, -1); - endsWithSlash = true; - } - if (path[0] !== "/") { - path = `/${path}`; - } - if (path === "/" && endsWithSlash) { - p = `${p}/`; - } else if (path !== "/") { - p = `${p}${path}`; - } - if (path === "/" && p === "") { - p = "/"; - } - } - return p; - }; - var checkOptionalParameter = (path) => { - const match = path.match(/^(.+|)(\/\:[^\/]+)\?$/); - if (!match) - return null; - const base = match[1]; - const optional = base + match[2]; - return [base === "" ? "/" : base.replace(/\/$/, ""), optional]; - }; - var _decodeURI = (value) => { - if (!/[%+]/.test(value)) { - return value; - } - if (value.indexOf("+") !== -1) { - value = value.replace(/\+/g, " "); - } - return /%/.test(value) ? decodeURIComponent_(value) : value; - }; - var _getQueryParam = (url, key, multiple) => { - let encoded; - if (!multiple && key && !/[%+]/.test(key)) { - let keyIndex2 = url.indexOf(`?${key}`, 8); - if (keyIndex2 === -1) { - keyIndex2 = url.indexOf(`&${key}`, 8); - } - 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 ?? (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) { - ; - (results[name] ?? (results[name] = [])).push(value); - } else { - results[name] ?? (results[name] = value); - } - } - return key ? results[key] : results; - }; - var getQueryParam = _getQueryParam; - var getQueryParams = (url, key) => { - return _getQueryParam(url, key, true); - }; - var decodeURIComponent_ = decodeURIComponent; - - // node_modules/hono/dist/utils/cookie.js - var validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/; - var validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/; - var parse = (cookie, name) => { - const pairs = cookie.trim().split(";"); - return pairs.reduce((parsedCookie, pairStr) => { - pairStr = pairStr.trim(); - const valueStartPos = pairStr.indexOf("="); - if (valueStartPos === -1) - return parsedCookie; - const cookieName = pairStr.substring(0, valueStartPos).trim(); - if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName)) - return parsedCookie; - let cookieValue = pairStr.substring(valueStartPos + 1).trim(); - if (cookieValue.startsWith('"') && cookieValue.endsWith('"')) - cookieValue = cookieValue.slice(1, -1); - if (validCookieValueRegEx.test(cookieValue)) - parsedCookie[cookieName] = decodeURIComponent_(cookieValue); - return parsedCookie; - }, {}); - }; - var _serialize = (name, value, opt = {}) => { - let cookie = `${name}=${value}`; - if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) { - cookie += `; Max-Age=${Math.floor(opt.maxAge)}`; - } - if (opt.domain) { - cookie += `; Domain=${opt.domain}`; - } - if (opt.path) { - cookie += `; Path=${opt.path}`; - } - if (opt.expires) { - cookie += `; Expires=${opt.expires.toUTCString()}`; - } - if (opt.httpOnly) { - cookie += "; HttpOnly"; - } - if (opt.secure) { - cookie += "; Secure"; - } - if (opt.sameSite) { - cookie += `; SameSite=${opt.sameSite}`; - } - if (opt.partitioned) { - cookie += "; Partitioned"; - } - return cookie; - }; - var serialize = (name, value, opt = {}) => { - value = encodeURIComponent(value); - return _serialize(name, value, opt); - }; - - // node_modules/hono/dist/utils/stream.js - var StreamingApi = class { - constructor(writable) { - this.writable = writable; - this.writer = writable.getWriter(); - this.encoder = new TextEncoder(); - } - async write(input) { - try { - if (typeof input === "string") { - input = this.encoder.encode(input); - } - await this.writer.write(input); - } catch (e) { - } - return this; - } - async writeln(input) { - await this.write(input + "\n"); - return this; - } - sleep(ms) { - return new Promise((res) => setTimeout(res, ms)); - } - async close() { - try { - await this.writer.close(); - } catch (e) { - } - } - async pipe(body) { - this.writer.releaseLock(); - await body.pipeTo(this.writable, { preventClose: true }); - this.writer = this.writable.getWriter(); - } - }; - - // node_modules/hono/dist/context.js - var TEXT_PLAIN = "text/plain; charset=UTF-8"; - var Context = class { - constructor(req, options) { - this.env = {}; - this._var = {}; - this.finalized = false; - this.error = void 0; - this._status = 200; - this._h = void 0; - this._pH = void 0; - this._init = true; - this._renderer = (content) => this.html(content); - this.notFoundHandler = () => new Response(); - this.render = (...args) => this._renderer(...args); - this.setRenderer = (renderer) => { - this._renderer = renderer; - }; - this.header = (name, value, options2) => { - if (value === void 0) { - if (this._h) { - this._h.delete(name); - } else if (this._pH) { - delete this._pH[name.toLocaleLowerCase()]; - } - if (this.finalized) { - this.res.headers.delete(name); - } - return; - } - if (options2?.append) { - if (!this._h) { - this._init = false; - this._h = new Headers(this._pH); - this._pH = {}; - } - this._h.append(name, value); - } else { - if (this._h) { - this._h.set(name, value); - } else { - this._pH ?? (this._pH = {}); - this._pH[name.toLowerCase()] = value; - } - } - if (this.finalized) { - if (options2?.append) { - this.res.headers.append(name, value); - } else { - this.res.headers.set(name, value); - } - } - }; - this.status = (status) => { - this._status = status; - }; - this.set = (key, value) => { - this._var ?? (this._var = {}); - this._var[key] = value; - }; - this.get = (key) => { - return this._var ? this._var[key] : void 0; - }; - this.newResponse = (data, arg, headers) => { - if (this._init && !headers && !arg && this._status === 200) { - return new Response(data, { - headers: this._pH - }); - } - if (arg && typeof arg !== "number") { - const res = new Response(data, arg); - const contentType = this._pH?.["content-type"]; - if (contentType) { - res.headers.set("content-type", contentType); - } - return res; - } - const status = arg ?? this._status; - this._pH ?? (this._pH = {}); - this._h ?? (this._h = new Headers()); - for (const [k, v] of Object.entries(this._pH)) { - this._h.set(k, v); - } - if (this._res) { - this._res.headers.forEach((v, k) => { - this._h?.set(k, v); - }); - for (const [k, v] of Object.entries(this._pH)) { - this._h.set(k, v); - } - } - headers ?? (headers = {}); - for (const [k, v] of Object.entries(headers)) { - if (typeof v === "string") { - this._h.set(k, v); - } else { - this._h.delete(k); - for (const v2 of v) { - this._h.append(k, v2); - } - } - } - return new Response(data, { - status, - headers: this._h - }); - }; - this.body = (data, arg, headers) => { - return typeof arg === "number" ? this.newResponse(data, arg, headers) : this.newResponse(data, arg); - }; - this.text = (text, arg, headers) => { - if (!this._pH) { - if (this._init && !headers && !arg) { - return new Response(text); - } - this._pH = {}; - } - if (this._pH["content-type"]) { - this._pH["content-type"] = TEXT_PLAIN; - } - return typeof arg === "number" ? this.newResponse(text, arg, headers) : this.newResponse(text, arg); - }; - this.json = (object, arg, headers) => { - const body = JSON.stringify(object); - this._pH ?? (this._pH = {}); - this._pH["content-type"] = "application/json; charset=UTF-8"; - return typeof arg === "number" ? this.newResponse(body, arg, headers) : this.newResponse(body, arg); - }; - this.jsonT = (object, arg, headers) => { - const response = typeof arg === "number" ? this.json(object, arg, headers) : this.json(object, arg); - return { - response, - data: object, - format: "json", - status: response.status - }; - }; - this.html = (html, arg, headers) => { - this._pH ?? (this._pH = {}); - this._pH["content-type"] = "text/html; charset=UTF-8"; - return typeof arg === "number" ? this.newResponse(html, arg, headers) : this.newResponse(html, arg); - }; - this.redirect = (location, status = 302) => { - this._h ?? (this._h = new Headers()); - this._h.set("Location", location); - return this.newResponse(null, status); - }; - this.streamText = (cb, arg, headers) => { - headers ?? (headers = {}); - this.header("content-type", TEXT_PLAIN); - this.header("x-content-type-options", "nosniff"); - this.header("transfer-encoding", "chunked"); - return this.stream(cb, arg, headers); - }; - this.stream = (cb, arg, headers) => { - const { readable, writable } = new TransformStream(); - const stream = new StreamingApi(writable); - cb(stream).finally(() => stream.close()); - return typeof arg === "number" ? this.newResponse(readable, arg, headers) : this.newResponse(readable, arg); - }; - this.cookie = (name, value, opt) => { - const cookie = serialize(name, value, opt); - this.header("set-cookie", cookie, { append: true }); - }; - this.notFound = () => { - return this.notFoundHandler(this); - }; - this.req = req; - if (options) { - this._exCtx = options.executionCtx; - this.env = options.env; - if (options.notFoundHandler) { - this.notFoundHandler = options.notFoundHandler; - } - } - } - get event() { - if (this._exCtx instanceof FetchEvent) { - return this._exCtx; - } else { - throw Error("This context has no FetchEvent"); - } - } - get executionCtx() { - if (this._exCtx) { - return this._exCtx; - } else { - throw Error("This context has no ExecutionContext"); - } - } - get res() { - this._init = false; - return this._res || (this._res = new Response("404 Not Found", { status: 404 })); - } - set res(_res) { - this._init = false; - if (this._res && _res) { - this._res.headers.delete("content-type"); - this._res.headers.forEach((v, k) => { - _res.headers.set(k, v); - }); - } - this._res = _res; - this.finalized = true; - } - get var() { - return { ...this._var }; - } - get runtime() { - const global = globalThis; - if (global?.Deno !== void 0) { - return "deno"; - } - if (global?.Bun !== void 0) { - return "bun"; - } - if (typeof global?.WebSocketPair === "function") { - return "workerd"; - } - if (typeof global?.EdgeRuntime === "string") { - return "edge-light"; - } - if (global?.fastly !== void 0) { - return "fastly"; - } - if (global?.__lagon__ !== void 0) { - return "lagon"; - } - if (global?.process?.release?.name === "node") { - return "node"; - } - return "other"; - } - }; - - // node_modules/hono/dist/compose.js - var compose = (middleware, onError, onNotFound) => { - const middlewareLength = middleware.length; - return (context, next) => { - let index = -1; - return dispatch(0); - function dispatch(i) { - if (i <= index) { - throw new Error("next() called multiple times"); - } - let handler = middleware[i]; - index = i; - if (i === middlewareLength && next) - handler = next; - let res; - let isError = false; - if (!handler) { - if (context instanceof Context && context.finalized === false && onNotFound) { - res = onNotFound(context); - } - } else { - try { - res = handler(context, () => { - const dispatchRes = dispatch(i + 1); - return dispatchRes instanceof Promise ? dispatchRes : Promise.resolve(dispatchRes); - }); - } catch (err) { - if (err instanceof Error && context instanceof Context && onError) { - context.error = err; - res = onError(err, context); - isError = true; - } else { - throw err; - } - } - } - if (!(res instanceof Promise)) { - if (res !== void 0 && "response" in res) { - res = res["response"]; - } - if (res && (context.finalized === false || isError)) { - context.res = res; - } - return context; - } else { - return res.then((res2) => { - if (res2 !== void 0 && "response" in res2) { - res2 = res2["response"]; - } - if (res2 && context.finalized === false) { - context.res = res2; - } - return context; - }).catch(async (err) => { - if (err instanceof Error && context instanceof Context && onError) { - context.error = err; - context.res = await onError(err, context); - return context; - } - throw err; - }); - } - } - }; - }; - - // node_modules/hono/dist/http-exception.js - var HTTPException = class extends Error { - constructor(status = 500, options) { - super(options?.message); - this.res = options?.res; - this.status = status; - } - getResponse() { - if (this.res) { - return this.res; - } - return new Response(this.message, { - status: this.status - }); - } - }; - - // node_modules/hono/dist/utils/body.js - var parseBody = async (request) => { - let body = {}; - const contentType = request.headers.get("Content-Type"); - if (contentType && (contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded"))) { - const formData = await request.formData(); - if (formData) { - const form = {}; - formData.forEach((value, key) => { - if (key.slice(-2) === "[]") { - if (!form[key]) { - form[key] = [value.toString()]; - } else { - if (Array.isArray(form[key])) { - ; - form[key].push(value.toString()); - } - } - } else { - form[key] = value; - } - }); - body = form; - } - } - return body; - }; - - // node_modules/hono/dist/request.js - var HonoRequest = class { - constructor(request, path = "/", paramData) { - this.bodyCache = {}; - this.cachedBody = (key) => { - const { bodyCache, raw } = this; - const cachedBody = bodyCache[key]; - if (cachedBody) - return cachedBody; - if (bodyCache.arrayBuffer) { - return (async () => { - return await new Response(bodyCache.arrayBuffer)[key](); - })(); - } - return bodyCache[key] = raw[key](); - }; - this.raw = request; - this.path = path; - this.paramData = paramData; - this.vData = {}; - } - param(key) { - if (this.paramData) { - if (key) { - const param = this.paramData[key]; - return param ? /\%/.test(param) ? decodeURIComponent_(param) : param : void 0; - } else { - const decoded = {}; - for (const [key2, value] of Object.entries(this.paramData)) { - if (value && typeof value === "string") { - decoded[key2] = /\%/.test(value) ? decodeURIComponent_(value) : value; - } - } - return decoded; - } - } - return null; - } - query(key) { - return getQueryParam(this.url, key); - } - queries(key) { - return getQueryParams(this.url, key); - } - header(name) { - if (name) - return this.raw.headers.get(name.toLowerCase()) ?? void 0; - const headerData = {}; - this.raw.headers.forEach((value, key) => { - headerData[key] = value; - }); - return headerData; - } - cookie(key) { - const cookie = this.raw.headers.get("Cookie"); - if (!cookie) - return; - const obj = parse(cookie); - if (key) { - const value = obj[key]; - return value; - } else { - return obj; - } - } - async parseBody() { - if (this.bodyCache.parsedBody) - return this.bodyCache.parsedBody; - const parsedBody = await parseBody(this); - this.bodyCache.parsedBody = parsedBody; - return parsedBody; - } - json() { - return this.cachedBody("json"); - } - text() { - return this.cachedBody("text"); - } - arrayBuffer() { - return this.cachedBody("arrayBuffer"); - } - blob() { - return this.cachedBody("blob"); - } - formData() { - return this.cachedBody("formData"); - } - addValidatedData(target, data) { - this.vData[target] = data; - } - valid(target) { - return this.vData[target]; - } - get url() { - return this.raw.url; - } - get method() { - return this.raw.method; - } - get headers() { - return this.raw.headers; - } - get body() { - return this.raw.body; - } - get bodyUsed() { - return this.raw.bodyUsed; - } - get integrity() { - return this.raw.integrity; - } - get keepalive() { - return this.raw.keepalive; - } - get referrer() { - return this.raw.referrer; - } - get signal() { - return this.raw.signal; - } - }; - - // 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 UnsupportedPathError = class extends Error { - }; - - // node_modules/hono/dist/hono-base.js - function defineDynamicClass() { - return class { - }; - } - var notFoundHandler = (c) => { - return c.text("404 Not Found", 404); - }; - var errorHandler = (err, c) => { - if (err instanceof HTTPException) { - return err.getResponse(); - } - console.trace(err); - const message = "Internal Server Error"; - return c.text(message, 500); - }; - var Hono = class extends defineDynamicClass() { - constructor(init = {}) { - super(); - this._basePath = "/"; - this.path = "/"; - this.routes = []; - this.notFoundHandler = notFoundHandler; - this.errorHandler = errorHandler; - this.head = () => { - console.warn("`app.head()` is no longer used. `app.get()` implicitly handles the HEAD method."); - return this; - }; - this.handleEvent = (event) => { - return this.dispatch(event.request, event, void 0, event.request.method); - }; - this.fetch = (request, Env, executionCtx) => { - return this.dispatch(request, executionCtx, Env, request.method); - }; - this.request = (input, requestInit, Env, executionCtx) => { - if (input instanceof Request) { - if (requestInit !== void 0) { - input = new Request(input, requestInit); - } - return this.fetch(input, Env, executionCtx); - } - input = input.toString(); - const path = /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`; - const req = new Request(path, requestInit); - return this.fetch(req, Env, executionCtx); - }; - this.fire = () => { - addEventListener("fetch", (event) => { - event.respondWith(this.dispatch(event.request, event, void 0, event.request.method)); - }); - }; - const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE]; - allMethods.map((method) => { - this[method] = (args1, ...args) => { - if (typeof args1 === "string") { - this.path = args1; - } else { - this.addRoute(method, this.path, args1); - } - args.map((handler) => { - if (typeof handler !== "string") { - this.addRoute(method, this.path, handler); - } - }); - return this; - }; - }); - this.on = (method, path, ...handlers) => { - if (!method) - return this; - this.path = path; - 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 { - handlers.unshift(arg1); - } - handlers.map((handler) => { - this.addRoute(METHOD_NAME_ALL, this.path, handler); - }); - return this; - }; - const strict = init.strict ?? true; - delete init.strict; - Object.assign(this, init); - this.getPath = strict ? init.getPath ?? getPath : getPathNoStrict; - } - clone() { - const clone = new Hono({ - router: this.router, - getPath: this.getPath - }); - clone.routes = this.routes; - return clone; - } - route(path, app2) { - const subApp = this.basePath(path); - if (!app2) { - return subApp; - } - app2.routes.map((r) => { - const handler = app2.errorHandler === errorHandler ? r.handler : async (c, next) => (await compose([r.handler], app2.errorHandler)(c, next)).res; - subApp.addRoute(r.method, r.path, handler); - }); - return this; - } - basePath(path) { - const subApp = this.clone(); - subApp._basePath = mergePath(this._basePath, path); - return subApp; - } - onError(handler) { - this.errorHandler = handler; - return this; - } - notFound(handler) { - this.notFoundHandler = handler; - return this; - } - showRoutes() { - const length = 8; - this.routes.map((route) => { - console.log( - `\x1B[32m${route.method}\x1B[0m ${" ".repeat(length - route.method.length)} ${route.path}` - ); - }); - } - mount(path, applicationHandler, optionHandler) { - const mergedPath = mergePath(this._basePath, path); - const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length; - const handler = async (c, next) => { - let executionContext = void 0; - try { - executionContext = c.executionCtx; - } catch { - } - const options = optionHandler ? optionHandler(c) : [c.env, executionContext]; - const optionsArray = Array.isArray(options) ? options : [options]; - const queryStrings = getQueryStrings(c.req.url); - const res = await applicationHandler( - new Request( - new URL((c.req.path.slice(pathPrefixLength) || "/") + queryStrings, c.req.url), - c.req.raw - ), - ...optionsArray - ); - if (res) - return res; - await next(); - }; - this.addRoute(METHOD_NAME_ALL, mergePath(path, "*"), handler); - return this; - } - get routerName() { - this.matchRoute("GET", "/"); - return this.router.name; - } - addRoute(method, path, handler) { - method = method.toUpperCase(); - if (this._basePath) { - path = mergePath(this._basePath, path); - } - this.router.add(method, path, handler); - const r = { path, method, handler }; - this.routes.push(r); - } - matchRoute(method, path) { - return this.router.match(method, path) || { handlers: [], params: {} }; - } - 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 { handlers, params } = this.matchRoute(method, path); - const c = new Context(new HonoRequest(request, path, params), { - env, - executionCtx, - notFoundHandler: this.notFoundHandler - }); - if (handlers.length === 1) { - let res; - try { - res = handlers[0](c, async () => { - }); - if (!res) { - return this.notFoundHandler(c); - } - } catch (err) { - return this.handleError(err, c); - } - if (res instanceof Response) - return res; - if ("response" in res) { - res = res.response; - } - if (res instanceof Response) - return res; - return (async () => { - let awaited; - try { - awaited = await res; - if (awaited !== void 0 && "response" in awaited) { - awaited = awaited["response"]; - } - if (!awaited) { - return this.notFoundHandler(c); - } - } catch (err) { - return this.handleError(err, c); - } - return awaited; - })(); - } - const composed = compose(handlers, this.errorHandler, this.notFoundHandler); - return (async () => { - try { - const tmp = composed(c); - const context = tmp.constructor.name === "Promise" ? await tmp : tmp; - if (!context.finalized) { - throw new Error( - "Context is not finalized. You may forget returning Response object or `await next()`" - ); - } - return context.res; - } catch (err) { - return this.handleError(err, c); - } - })(); - } - }; - - // 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 = Symbol(); - 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 { - constructor() { - this.children = {}; - } - 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]; - const regexpStr = pattern[2] || LABEL_REG_EXP_STR; - 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 !== "") { - if (paramMap.some((p) => p[0] === name)) { - throw new Error("Duplicate param 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}` : k) + c.buildRegExpStr(); - }); - if (typeof this.index === "number") { - strList.unshift(`#${this.index}`); - } - if (strList.length === 0) { - return ""; - } - if (strList.length === 1) { - return strList[0]; - } - return "(?:" + strList.join("|") + ")"; - } - }; - - // node_modules/hono/dist/router/reg-exp-router/trie.js - var Trie = class { - constructor() { - this.context = { varIndex: 0 }; - this.root = new Node(); - } - insert(path, index, pathErrorCheckOnly) { - const paramMap = []; - 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, paramMap, this.context, pathErrorCheckOnly); - return paramMap; - } - 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 (typeof handlerIndex !== "undefined") { - indexReplacementMap[++captureIndex] = Number(handlerIndex); - return "$()"; - } - if (typeof paramIndex !== "undefined") { - paramReplacementMap[Number(paramIndex)] = ++captureIndex; - return ""; - } - return ""; - }); - return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap]; - } - }; - - // node_modules/hono/dist/router/reg-exp-router/router.js - var methodNames = [METHOD_NAME_ALL, ...METHODS].map((method) => method.toUpperCase()); - var emptyParam = {}; - var nullMatcher = [/^$/, [], {}]; - var wildcardRegExpCache = {}; - function buildWildcardRegExp(path) { - return wildcardRegExpCache[path] ?? (wildcardRegExpCache[path] = new RegExp( - path === "*" ? "" : `^${path.replace(/\/\*/, "(?:|/.*)")}$` - )); - } - function clearWildcardRegExpCache() { - wildcardRegExpCache = {}; - } - 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 = {}; - for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) { - const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i]; - if (pathErrorCheckOnly) { - staticMap[path] = { handlers, params: emptyParam }; - } else { - j++; - } - let paramMap; - try { - paramMap = trie.insert(path, j, pathErrorCheckOnly); - } catch (e) { - throw e === PATH_ERROR ? new UnsupportedPathError(path) : e; - } - if (pathErrorCheckOnly) { - continue; - } - handlerData[j] = paramMap.length === 0 ? [{ handlers, params: emptyParam }, null] : [handlers, paramMap]; - } - const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp(); - for (let i = 0, len = handlerData.length; i < len; i++) { - const paramMap = handlerData[i][1]; - if (paramMap) { - for (let j = 0, len2 = paramMap.length; j < len2; j++) { - paramMap[j][1] = paramReplacementMap[paramMap[j][1]]; - } - } - } - 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 { - constructor() { - this.name = "RegExpRouter"; - this.middleware = { [METHOD_NAME_ALL]: {} }; - this.routes = { [METHOD_NAME_ALL]: {} }; - } - add(method, path, handler) { - var _a; - const { middleware, routes } = this; - if (!middleware || !routes) { - throw new Error("Can not add a route since the matcher is already built."); - } - if (methodNames.indexOf(method) === -1) - methodNames.push(method); - if (!middleware[method]) { - ; - [middleware, routes].forEach((handlerMap) => { - handlerMap[method] = {}; - Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => { - handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]]; - }); - }); - } - if (path === "/*") { - path = "*"; - } - if (/\*$/.test(path)) { - const re = buildWildcardRegExp(path); - if (method === METHOD_NAME_ALL) { - Object.keys(middleware).forEach((m) => { - var _a2; - (_a2 = middleware[m])[path] || (_a2[path] = findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || []); - }); - } else { - (_a = middleware[method])[path] || (_a[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); - }); - } - }); - 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)); - } - }); - 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) => { - var _a2; - if (method === METHOD_NAME_ALL || method === m) { - (_a2 = routes[m])[path2] || (_a2[path2] = [ - ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || [] - ]); - routes[m][path2].push(handler); - } - }); - } - } - match(method, path) { - clearWildcardRegExpCache(); - const matchers = this.buildAllMatchers(); - this.match = (method2, path2) => { - const matcher = matchers[method2]; - const staticMatch = matcher[2][path2]; - if (staticMatch) { - return staticMatch; - } - const match = path2.match(matcher[0]); - if (!match) { - return null; - } - const index = match.indexOf("", 1); - const [handlers, paramMap] = matcher[1][index]; - if (!paramMap) { - return handlers; - } - const params = {}; - for (let i = 0, len = paramMap.length; i < len; i++) { - params[paramMap[i][0]] = match[paramMap[i][1]]; - } - return { handlers, params }; - }; - return this.match(method, path); - } - buildAllMatchers() { - const matchers = {}; - methodNames.forEach((method) => { - matchers[method] = this.buildMatcher(method) || matchers[METHOD_NAME_ALL]; - }); - this.middleware = this.routes = void 0; - 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 || (hasOwnRoute = true); - routes.push(...ownRoute); - } else if (method !== METHOD_NAME_ALL) { - routes.push( - ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]]) - ); - } - }); - if (!hasOwnRoute) { - return null; - } else { - return buildMatcherFromPreprocessedRoutes(routes); - } - } - }; - - // node_modules/hono/dist/router/smart-router/router.js - var SmartRouter = class { - constructor(init) { - this.name = "SmartRouter"; - this.routers = []; - this.routes = []; - Object.assign(this, init); - } - add(method, path, handler) { - if (!this.routes) { - throw new Error("Can not add a route since the matcher is already built."); - } - this.routes.push([method, path, handler]); - } - match(method, path) { - if (!this.routes) { - throw new Error("Fatal error"); - } - const { routers, routes } = this; - const len = routers.length; - let i = 0; - let res; - for (; i < len; i++) { - const router = routers[i]; - try { - routes.forEach((args) => { - router.add(...args); - }); - 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 || null; - } - get activeRouter() { - if (this.routes || this.routers.length !== 1) { - throw new Error("No active router has been determined yet."); - } - return this.routers[0]; - } - }; - - // node_modules/hono/dist/router/trie-router/node.js - function findParam(node, name) { - for (let i = 0, len = node.patterns.length; i < len; i++) { - if (typeof node.patterns[i] === "object" && node.patterns[i][1] === name) { - return true; - } - } - const nodes = Object.values(node.children); - for (let i = 0, len = nodes.length; i < len; i++) { - if (findParam(nodes[i], name)) { - return true; - } - } - return false; - } - var Node2 = class { - constructor(method, handler, children) { - this.order = 0; - this.children = children || {}; - this.methods = []; - this.name = ""; - if (method && handler) { - const m = {}; - m[method] = { handler, score: 0, name: this.name }; - this.methods = [m]; - } - this.patterns = []; - this.handlerSetCache = {}; - } - insert(method, path, handler) { - this.name = `${method} ${path}`; - this.order = ++this.order; - let curNode = this; - const parts = splitRoutingPath(path); - const parentPatterns = []; - const errorMessage = (name) => { - return `Duplicate param name, use another name instead of '${name}' - ${method} ${path} <--- '${name}'`; - }; - for (let i = 0, len = parts.length; i < len; i++) { - const p = parts[i]; - if (Object.keys(curNode.children).includes(p)) { - parentPatterns.push(...curNode.patterns); - curNode = curNode.children[p]; - continue; - } - curNode.children[p] = new Node2(); - const pattern = getPattern(p); - if (pattern) { - if (typeof pattern === "object") { - for (let j = 0, len2 = parentPatterns.length; j < len2; j++) { - if (typeof parentPatterns[j] === "object" && parentPatterns[j][1] === pattern[1]) { - throw new Error(errorMessage(pattern[1])); - } - } - if (Object.values(curNode.children).some((n) => findParam(n, pattern[1]))) { - throw new Error(errorMessage(pattern[1])); - } - } - curNode.patterns.push(pattern); - parentPatterns.push(...curNode.patterns); - } - parentPatterns.push(...curNode.patterns); - curNode = curNode.children[p]; - } - if (!curNode.methods.length) { - curNode.methods = []; - } - const m = {}; - const handlerSet = { handler, name: this.name, score: this.order }; - m[method] = handlerSet; - curNode.methods.push(m); - return curNode; - } - gHSets(node, method, wildcard) { - var _a, _b; - return (_a = node.handlerSetCache)[_b = `${method}:${wildcard ? "1" : "0"}`] || (_a[_b] = (() => { - const handlerSets = []; - for (let i = 0, len = node.methods.length; i < len; i++) { - const m = node.methods[i]; - const handlerSet = m[method] || m[METHOD_NAME_ALL]; - if (handlerSet !== void 0) { - handlerSets.push(handlerSet); - } - } - return handlerSets; - })()); - } - search(method, path) { - const handlerSets = []; - const params = {}; - const curNode = this; - let curNodes = [curNode]; - const parts = splitPath(path); - for (let i = 0, len2 = parts.length; i < len2; i++) { - const part = parts[i]; - const isLast = i === len2 - 1; - const tempNodes = []; - let matched = false; - for (let j = 0, len22 = curNodes.length; j < len22; j++) { - const node = curNodes[j]; - const nextNode = node.children[part]; - if (nextNode) { - if (isLast === true) { - if (nextNode.children["*"]) { - handlerSets.push(...this.gHSets(nextNode.children["*"], method, true)); - } - handlerSets.push(...this.gHSets(nextNode, method)); - matched = true; - } else { - tempNodes.push(nextNode); - } - } - for (let k = 0, len3 = node.patterns.length; k < len3; k++) { - const pattern = node.patterns[k]; - if (pattern === "*") { - const astNode = node.children["*"]; - if (astNode) { - handlerSets.push(...this.gHSets(astNode, method)); - tempNodes.push(astNode); - } - continue; - } - if (part === "") - continue; - const [key, name, matcher] = pattern; - const child = node.children[key]; - const restPathString = parts.slice(i).join("/"); - if (matcher instanceof RegExp && matcher.test(restPathString)) { - handlerSets.push(...this.gHSets(child, method)); - params[name] = restPathString; - continue; - } - if (matcher === true || matcher instanceof RegExp && matcher.test(part)) { - if (typeof key === "string") { - if (isLast === true) { - handlerSets.push(...this.gHSets(child, method)); - if (child.children["*"]) { - handlerSets.push(...this.gHSets(child.children["*"], method)); - } - } else { - tempNodes.push(child); - } - } - if (typeof name === "string" && !matched) { - params[name] = part; - } else { - if (node.children[part]) { - params[name] = part; - } - } - } - } - } - curNodes = tempNodes; - } - const len = handlerSets.length; - if (len === 0) - return null; - if (len === 1) - return { handlers: [handlerSets[0].handler], params }; - const handlers = handlerSets.sort((a, b) => { - return a.score - b.score; - }).map((s) => { - return s.handler; - }); - return { handlers, params }; - } - }; - - // node_modules/hono/dist/router/trie-router/router.js - var TrieRouter = class { - constructor() { - this.name = "TrieRouter"; - this.node = new Node2(); - } - add(method, path, handler) { - const results = checkOptionalParameter(path); - if (results) { - for (const p of results) { - this.node.insert(method, p, handler); - } - return; - } - this.node.insert(method, path, handler); - } - match(method, path) { - return this.node.search(method, path); - } - }; - - // node_modules/hono/dist/hono.js - var Hono2 = class extends Hono { - constructor(init = {}) { - super(init); - this.router = init.router ?? new SmartRouter({ - routers: [new RegExpRouter(), new TrieRouter()] - }); - } - }; - - // index.js - var app = new Hono2(); - app.get("/", (c) => { - return c.text("Hello from Hono running in Wasm Workers Server!"); - }); - app.get("/hello", (c) => { - return c.text("You can get a custom hello message by accessing /hello/your-name"); - }); - app.get("/hello/:name", (c) => { - const name = c.req.param("name"); - return c.text(`Hello ${name}! This app is running in Wasm Workers Server`); - }); - app.notFound((c) => { - return c.text("Awww! This page is missing", 404); - }); - app.fire(); -})(); +var Rt=class{},Z=class extends Rt{};var tt=t=>{let r=t.split("/");return r[0]===""&&r.shift(),r},et=t=>{let r=[];for(let e=0;;){let n=!1;if(t=t.replace(/\{[^}]+\}/g,i=>{let o=`@\\${e}`;return r[e]=[o,i],e++,n=!0,o}),!n)break}let s=t.split("/");s[0]===""&&s.shift();for(let e=r.length-1;e>=0;e--){let[n]=r[e];for(let i=s.length-1;i>=0;i--)if(s[i].indexOf(n)!==-1){s[i]=s[i].replace(n,r[e][1]);break}}return s},C={},rt=t=>{if(t==="*")return"*";let r=t.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);return r?(C[t]||(r[2]?C[t]=[t,r[1],new RegExp("^"+r[2]+"$")]:C[t]=[t,r[1],!0]),C[t]):null},B=t=>{let r=t.url.match(/^https?:\/\/[^/]+(\/[^?]*)/);return r?r[1]:""},st=t=>{let r=t.indexOf("?",8);return r===-1?"":"?"+t.slice(r+1)},nt=t=>{let r=B(t);return r.length>1&&r[r.length-1]==="/"?r.slice(0,-1):r},y=(...t)=>{let r="",s=!1;for(let e of t)r[r.length-1]==="/"&&(r=r.slice(0,-1),s=!0),e[0]!=="/"&&(e=`/${e}`),e==="/"&&s?r=`${r}/`:e!=="/"&&(r=`${r}${e}`),e==="/"&&r===""&&(r="/");return r},A=t=>{let r=t.match(/^(.+|)(\/\:[^\/]+)\?$/);if(!r)return null;let s=r[1],e=s+r[2];return[s===""?"/":s.replace(/\/$/,""),e]},F=t=>/[%+]/.test(t)?(t.indexOf("+")!==-1&&(t=t.replace(/\+/g," ")),/%/.test(t)?_(t):t):t,it=(t,r,s)=>{let e;if(!s&&r&&!/[%+]/.test(r)){let o=t.indexOf(`?${r}`,8);for(o===-1&&(o=t.indexOf(`&${r}`,8));o!==-1;){let h=t.charCodeAt(o+r.length+1);if(h===61){let c=o+r.length+2,a=t.indexOf("&",c);return F(t.slice(c,a===-1?void 0:a))}else if(h==38||isNaN(h))return"";o=t.indexOf(`&${r}`,o+1)}if(e=/[%+]/.test(t),!e)return}let n={};e??(e=/[%+]/.test(t));let i=t.indexOf("?",8);for(;i!==-1;){let o=t.indexOf("&",i+1),h=t.indexOf("=",i);h>o&&o!==-1&&(h=-1);let c=t.slice(i+1,h===-1?o===-1?void 0:o:h);if(e&&(c=F(c)),i=o,c==="")continue;let a;h===-1?a="":(a=t.slice(h+1,o===-1?void 0:o),e&&(a=F(a))),s?(n[c]??(n[c]=[])).push(a):n[c]??(n[c]=a)}return r?n[r]:n},ot=it,at=(t,r)=>it(t,r,!0),_=decodeURIComponent;var Et=/^[\w!#$%&'*.^`|~+-]+$/,bt=/^[ !#-:<-[\]-~]*$/,ht=(t,r)=>t.trim().split(";").reduce((e,n)=>{n=n.trim();let i=n.indexOf("=");if(i===-1)return e;let o=n.substring(0,i).trim();if(r&&r!==o||!Et.test(o))return e;let h=n.substring(i+1).trim();return h.startsWith('"')&&h.endsWith('"')&&(h=h.slice(1,-1)),bt.test(h)&&(e[o]=_(h)),e},{});var Ht=(t,r,s={})=>{let e=`${t}=${r}`;return s&&typeof s.maxAge=="number"&&s.maxAge>=0&&(e+=`; Max-Age=${Math.floor(s.maxAge)}`),s.domain&&(e+=`; Domain=${s.domain}`),s.path&&(e+=`; Path=${s.path}`),s.expires&&(e+=`; Expires=${s.expires.toUTCString()}`),s.httpOnly&&(e+="; HttpOnly"),s.secure&&(e+="; Secure"),s.sameSite&&(e+=`; SameSite=${s.sameSite}`),s.partitioned&&(e+="; Partitioned"),e},ct=(t,r,s={})=>(r=encodeURIComponent(r),Ht(t,r,s));var ut=class{constructor(t){this.writable=t,this.writer=t.getWriter(),this.encoder=new TextEncoder}async write(t){try{typeof t=="string"&&(t=this.encoder.encode(t)),await this.writer.write(t)}catch{}return this}async writeln(t){return await this.write(t+` +`),this}sleep(t){return new Promise(r=>setTimeout(r,t))}async close(){try{await this.writer.close()}catch{}}async pipe(t){this.writer.releaseLock(),await t.pipeTo(this.writable,{preventClose:!0}),this.writer=this.writable.getWriter()}};var ft="text/plain; charset=UTF-8",x=class{constructor(t,r){this.env={},this._var={},this.finalized=!1,this.error=void 0,this._status=200,this._h=void 0,this._pH=void 0,this._init=!0,this._renderer=s=>this.html(s),this.notFoundHandler=()=>new Response,this.render=(...s)=>this._renderer(...s),this.setRenderer=s=>{this._renderer=s},this.header=(s,e,n)=>{if(e===void 0){this._h?this._h.delete(s):this._pH&&delete this._pH[s.toLocaleLowerCase()],this.finalized&&this.res.headers.delete(s);return}n?.append?(this._h||(this._init=!1,this._h=new Headers(this._pH),this._pH={}),this._h.append(s,e)):this._h?this._h.set(s,e):(this._pH??(this._pH={}),this._pH[s.toLowerCase()]=e),this.finalized&&(n?.append?this.res.headers.append(s,e):this.res.headers.set(s,e))},this.status=s=>{this._status=s},this.set=(s,e)=>{this._var??(this._var={}),this._var[s]=e},this.get=s=>this._var?this._var[s]:void 0,this.newResponse=(s,e,n)=>{if(this._init&&!n&&!e&&this._status===200)return new Response(s,{headers:this._pH});if(e&&typeof e!="number"){let o=new Response(s,e),h=this._pH?.["content-type"];return h&&o.headers.set("content-type",h),o}let i=e??this._status;this._pH??(this._pH={}),this._h??(this._h=new Headers);for(let[o,h]of Object.entries(this._pH))this._h.set(o,h);if(this._res){this._res.headers.forEach((o,h)=>{this._h?.set(h,o)});for(let[o,h]of Object.entries(this._pH))this._h.set(o,h)}n??(n={});for(let[o,h]of Object.entries(n))if(typeof h=="string")this._h.set(o,h);else{this._h.delete(o);for(let c of h)this._h.append(o,c)}return new Response(s,{status:i,headers:this._h})},this.body=(s,e,n)=>typeof e=="number"?this.newResponse(s,e,n):this.newResponse(s,e),this.text=(s,e,n)=>{if(!this._pH){if(this._init&&!n&&!e)return new Response(s);this._pH={}}return this._pH["content-type"]&&(this._pH["content-type"]=ft),typeof e=="number"?this.newResponse(s,e,n):this.newResponse(s,e)},this.json=(s,e,n)=>{let i=JSON.stringify(s);return this._pH??(this._pH={}),this._pH["content-type"]="application/json; charset=UTF-8",typeof e=="number"?this.newResponse(i,e,n):this.newResponse(i,e)},this.jsonT=(s,e,n)=>{let i=typeof e=="number"?this.json(s,e,n):this.json(s,e);return{response:i,data:s,format:"json",status:i.status}},this.html=(s,e,n)=>(this._pH??(this._pH={}),this._pH["content-type"]="text/html; charset=UTF-8",typeof e=="number"?this.newResponse(s,e,n):this.newResponse(s,e)),this.redirect=(s,e=302)=>(this._h??(this._h=new Headers),this._h.set("Location",s),this.newResponse(null,e)),this.streamText=(s,e,n)=>(n??(n={}),this.header("content-type",ft),this.header("x-content-type-options","nosniff"),this.header("transfer-encoding","chunked"),this.stream(s,e,n)),this.stream=(s,e,n)=>{let{readable:i,writable:o}=new TransformStream,h=new ut(o);return s(h).finally(()=>h.close()),typeof e=="number"?this.newResponse(i,e,n):this.newResponse(i,e)},this.cookie=(s,e,n)=>{let i=ct(s,e,n);this.header("set-cookie",i,{append:!0})},this.notFound=()=>this.notFoundHandler(this),this.req=t,r&&(this._exCtx=r.executionCtx,this.env=r.env,r.notFoundHandler&&(this.notFoundHandler=r.notFoundHandler))}get event(){if(this._exCtx instanceof Z)return this._exCtx;throw Error("This context has no FetchEvent")}get executionCtx(){if(this._exCtx)return this._exCtx;throw Error("This context has no ExecutionContext")}get res(){return this._init=!1,this._res||(this._res=new Response("404 Not Found",{status:404}))}set res(t){this._init=!1,this._res&&t&&(this._res.headers.delete("content-type"),this._res.headers.forEach((r,s)=>{t.headers.set(s,r)})),this._res=t,this.finalized=!0}get var(){return{...this._var}}get runtime(){let t=globalThis;return t?.Deno!==void 0?"deno":t?.Bun!==void 0?"bun":typeof t?.WebSocketPair=="function"?"workerd":typeof t?.EdgeRuntime=="string"?"edge-light":t?.fastly!==void 0?"fastly":t?.__lagon__!==void 0?"lagon":t?.process?.release?.name==="node"?"node":"other"}};var I=(t,r,s)=>{let e=t.length;return(n,i)=>{let o=-1;return h(0);function h(c){if(c<=o)throw new Error("next() called multiple times");let a=t[c];o=c,c===e&&i&&(a=i);let u,l=!1;if(!a)n instanceof x&&n.finalized===!1&&s&&(u=s(n));else try{u=a(n,()=>{let f=h(c+1);return f instanceof Promise?f:Promise.resolve(f)})}catch(f){if(f instanceof Error&&n instanceof x&&r)n.error=f,u=r(f,n),l=!0;else throw f}return u instanceof Promise?u.then(f=>(f!==void 0&&"response"in f&&(f=f.response),f&&n.finalized===!1&&(n.res=f),n)).catch(async f=>{if(f instanceof Error&&n instanceof x&&r)return n.error=f,n.res=await r(f,n),n;throw f}):(u!==void 0&&"response"in u&&(u=u.response),u&&(n.finalized===!1||l)&&(n.res=u),n)}}};var lt=class extends Error{constructor(t=500,r){super(r?.message),this.res=r?.res,this.status=t}getResponse(){return this.res?this.res:new Response(this.message,{status:this.status})}};var dt=async t=>{let r={},s=t.headers.get("Content-Type");if(s&&(s.startsWith("multipart/form-data")||s.startsWith("application/x-www-form-urlencoded"))){let e=await t.formData();if(e){let n={};e.forEach((i,o)=>{o.slice(-2)==="[]"?n[o]?Array.isArray(n[o])&&n[o].push(i.toString()):n[o]=[i.toString()]:n[o]=i}),r=n}}return r};var pt=class{constructor(t,r="/",s){this.bodyCache={},this.cachedBody=e=>{let{bodyCache:n,raw:i}=this,o=n[e];return o||(n.arrayBuffer?(async()=>await new Response(n.arrayBuffer)[e]())():n[e]=i[e]())},this.raw=t,this.path=r,this.paramData=s,this.vData={}}param(t){if(this.paramData)if(t){let r=this.paramData[t];return r?/\%/.test(r)?_(r):r:void 0}else{let r={};for(let[s,e]of Object.entries(this.paramData))e&&typeof e=="string"&&(r[s]=/\%/.test(e)?_(e):e);return r}return null}query(t){return ot(this.url,t)}queries(t){return at(this.url,t)}header(t){if(t)return this.raw.headers.get(t.toLowerCase())??void 0;let r={};return this.raw.headers.forEach((s,e)=>{r[e]=s}),r}cookie(t){let r=this.raw.headers.get("Cookie");if(!r)return;let s=ht(r);return t?s[t]:s}async parseBody(){if(this.bodyCache.parsedBody)return this.bodyCache.parsedBody;let t=await dt(this);return this.bodyCache.parsedBody=t,t}json(){return this.cachedBody("json")}text(){return this.cachedBody("text")}arrayBuffer(){return this.cachedBody("arrayBuffer")}blob(){return this.cachedBody("blob")}formData(){return this.cachedBody("formData")}addValidatedData(t,r){this.vData[t]=r}valid(t){return this.vData[t]}get url(){return this.raw.url}get method(){return this.raw.method}get headers(){return this.raw.headers}get body(){return this.raw.body}get bodyUsed(){return this.raw.bodyUsed}get integrity(){return this.raw.integrity}get keepalive(){return this.raw.keepalive}get referrer(){return this.raw.referrer}get signal(){return this.raw.signal}};var d="ALL",mt="all",j=["get","post","put","delete","options","patch"],L=class extends Error{};function Pt(){return class{}}var St=t=>t.text("404 Not Found",404),gt=(t,r)=>{if(t instanceof lt)return t.getResponse();console.trace(t);let s="Internal Server Error";return r.text(s,500)},U=class extends Pt(){constructor(t={}){super(),this._basePath="/",this.path="/",this.routes=[],this.notFoundHandler=St,this.errorHandler=gt,this.head=()=>(console.warn("`app.head()` is no longer used. `app.get()` implicitly handles the HEAD method."),this),this.handleEvent=e=>this.dispatch(e.request,e,void 0,e.request.method),this.fetch=(e,n,i)=>this.dispatch(e,i,n,e.method),this.request=(e,n,i,o)=>{if(e instanceof Request)return n!==void 0&&(e=new Request(e,n)),this.fetch(e,i,o);e=e.toString();let h=/^https?:\/\//.test(e)?e:`http://localhost${y("/",e)}`,c=new Request(h,n);return this.fetch(c,i,o)},this.fire=()=>{addEventListener("fetch",e=>{e.respondWith(this.dispatch(e.request,e,void 0,e.request.method))})},[...j,mt].map(e=>{this[e]=(n,...i)=>(typeof n=="string"?this.path=n:this.addRoute(e,this.path,n),i.map(o=>{typeof o!="string"&&this.addRoute(e,this.path,o)}),this)}),this.on=(e,n,...i)=>{if(!e)return this;this.path=n;for(let o of[e].flat())i.map(h=>{this.addRoute(o.toUpperCase(),this.path,h)});return this},this.use=(e,...n)=>(typeof e=="string"?this.path=e:n.unshift(e),n.map(i=>{this.addRoute(d,this.path,i)}),this);let s=t.strict??!0;delete t.strict,Object.assign(this,t),this.getPath=s?t.getPath??B:nt}clone(){let t=new U({router:this.router,getPath:this.getPath});return t.routes=this.routes,t}route(t,r){let s=this.basePath(t);return r?(r.routes.map(e=>{let n=r.errorHandler===gt?e.handler:async(i,o)=>(await I([e.handler],r.errorHandler)(i,o)).res;s.addRoute(e.method,e.path,n)}),this):s}basePath(t){let r=this.clone();return r._basePath=y(this._basePath,t),r}onError(t){return this.errorHandler=t,this}notFound(t){return this.notFoundHandler=t,this}showRoutes(){this.routes.map(r=>{console.log(`\x1B[32m${r.method}\x1B[0m ${" ".repeat(8-r.method.length)} ${r.path}`)})}mount(t,r,s){let e=y(this._basePath,t),n=e==="/"?0:e.length,i=async(o,h)=>{let c;try{c=o.executionCtx}catch{}let a=s?s(o):[o.env,c],u=Array.isArray(a)?a:[a],l=st(o.req.url),f=await r(new Request(new URL((o.req.path.slice(n)||"/")+l,o.req.url),o.req.raw),...u);if(f)return f;await h()};return this.addRoute(d,y(t,"*"),i),this}get routerName(){return this.matchRoute("GET","/"),this.router.name}addRoute(t,r,s){t=t.toUpperCase(),this._basePath&&(r=y(this._basePath,r)),this.router.add(t,r,s);let e={path:r,method:t,handler:s};this.routes.push(e)}matchRoute(t,r){return this.router.match(t,r)||{handlers:[],params:{}}}handleError(t,r){if(t instanceof Error)return this.errorHandler(t,r);throw t}dispatch(t,r,s,e){if(e==="HEAD")return(async()=>new Response(null,await this.dispatch(t,r,s,"GET")))();let n=this.getPath(t,{env:s}),{handlers:i,params:o}=this.matchRoute(e,n),h=new x(new pt(t,n,o),{env:s,executionCtx:r,notFoundHandler:this.notFoundHandler});if(i.length===1){let a;try{if(a=i[0](h,async()=>{}),!a)return this.notFoundHandler(h)}catch(u){return this.handleError(u,h)}return a instanceof Response||("response"in a&&(a=a.response),a instanceof Response)?a:(async()=>{let u;try{if(u=await a,u!==void 0&&"response"in u&&(u=u.response),!u)return this.notFoundHandler(h)}catch(l){return this.handleError(l,h)}return u})()}let c=I(i,this.errorHandler,this.notFoundHandler);return(async()=>{try{let a=c(h),u=a.constructor.name==="Promise"?await a:a;if(!u.finalized)throw new Error("Context is not finalized. You may forget returning Response object or `await next()`");return u.res}catch(a){return this.handleError(a,h)}})()}};var D="[^/]+",H=".*",P="(?:|/.*)",S=Symbol();function Ot(t,r){return t.length===1?r.length===1?tl!==H&&l!==P))throw S;if(n)return;c=this.children[u]=new M,a!==""&&(c.varIndex=e.varIndex++)}if(!n&&a!==""){if(s.some(l=>l[0]===a))throw new Error("Duplicate param name");s.push([a,c.varIndex])}}else if(c=this.children[i],!c){if(Object.keys(this.children).some(a=>a.length>1&&a!==H&&a!==P))throw S;if(n)return;c=this.children[i]=new M}c.insert(o,r,s,e,n)}buildRegExpStr(){let r=Object.keys(this.children).sort(Ot).map(s=>{let e=this.children[s];return(typeof e.varIndex=="number"?`(${s})@${e.varIndex}`:s)+e.buildRegExpStr()});return typeof this.index=="number"&&r.unshift(`#${this.index}`),r.length===0?"":r.length===1?r[0]:"(?:"+r.join("|")+")"}};var wt=class{constructor(){this.context={varIndex:0},this.root=new M}insert(t,r,s){let e=[],n=[];for(let o=0;;){let h=!1;if(t=t.replace(/\{[^}]+\}/g,c=>{let a=`@\\${o}`;return n[o]=[a,c],o++,h=!0,a}),!h)break}let i=t.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let o=n.length-1;o>=0;o--){let[h]=n[o];for(let c=i.length-1;c>=0;c--)if(i[c].indexOf(h)!==-1){i[c]=i[c].replace(h,n[o][1]);break}}return this.root.insert(i,r,e,this.context,s),e}buildRegExp(){let t=this.root.buildRegExpStr();if(t==="")return[/^$/,[],[]];let r=0,s=[],e=[];return t=t.replace(/#(\d+)|@(\d+)|\.\*\$/g,(n,i,o)=>typeof i<"u"?(s[++r]=Number(i),"$()"):(typeof o<"u"&&(e[Number(o)]=++r),"")),[new RegExp(`^${t}`),s,e]}};var W=[d,...j].map(t=>t.toUpperCase()),yt={},$t=[/^$/,[],{}],q={};function _t(t){return q[t]??(q[t]=new RegExp(t==="*"?"":`^${t.replace(/\/\*/,"(?:|/.*)")}$`))}function Tt(){q={}}function Ct(t){let r=new wt,s=[];if(t.length===0)return $t;let e=t.map(a=>[!/\*|\/:/.test(a[0]),...a]).sort(([a,u],[l,f])=>a?1:l?-1:u.length-f.length),n={};for(let a=0,u=-1,l=e.length;an.length-e.length))if(_t(s).test(r))return[...t[s]]}}var z=class{constructor(){this.name="RegExpRouter",this.middleware={[d]:{}},this.routes={[d]:{}}}add(t,r,s){var e;let{middleware:n,routes:i}=this;if(!n||!i)throw new Error("Can not add a route since the matcher is already built.");if(W.indexOf(t)===-1&&W.push(t),n[t]||[n,i].forEach(h=>{h[t]={},Object.keys(h[d]).forEach(c=>{h[t][c]=[...h[d][c]]})}),r==="/*"&&(r="*"),/\*$/.test(r)){let h=_t(r);t===d?Object.keys(n).forEach(c=>{var a;(a=n[c])[r]||(a[r]=v(n[c],r)||v(n[d],r)||[])}):(e=n[t])[r]||(e[r]=v(n[t],r)||v(n[d],r)||[]),Object.keys(n).forEach(c=>{(t===d||t===c)&&Object.keys(n[c]).forEach(a=>{h.test(a)&&n[c][a].push(s)})}),Object.keys(i).forEach(c=>{(t===d||t===c)&&Object.keys(i[c]).forEach(a=>h.test(a)&&i[c][a].push(s))});return}let o=A(r)||[r];for(let h=0,c=o.length;h{var l;(t===d||t===u)&&((l=i[u])[a]||(l[a]=[...v(n[u],a)||v(n[d],a)||[]]),i[u][a].push(s))})}}match(t,r){Tt();let s=this.buildAllMatchers();return this.match=(e,n)=>{let i=s[e],o=i[2][n];if(o)return o;let h=n.match(i[0]);if(!h)return null;let c=h.indexOf("",1),[a,u]=i[1][c];if(!u)return a;let l={};for(let f=0,p=u.length;f{t[r]=this.buildMatcher(r)||t[d]}),this.middleware=this.routes=void 0,t}buildMatcher(t){let r=[],s=t===d;return[this.middleware,this.routes].forEach(e=>{let n=e[t]?Object.keys(e[t]).map(i=>[i,e[t][i]]):[];n.length!==0?(s||(s=!0),r.push(...n)):t!==d&&r.push(...Object.keys(e[d]).map(i=>[i,e[d][i]]))}),s?Ct(r):null}};var K=class{constructor(t){this.name="SmartRouter",this.routers=[],this.routes=[],Object.assign(this,t)}add(t,r,s){if(!this.routes)throw new Error("Can not add a route since the matcher is already built.");this.routes.push([t,r,s])}match(t,r){if(!this.routes)throw new Error("Fatal error");let{routers:s,routes:e}=this,n=s.length,i=0,o;for(;i{h.add(...c)}),o=h.match(t,r)}catch(c){if(c instanceof L)continue;throw c}this.match=h.match.bind(h),this.routers=[h],this.routes=void 0;break}if(i===n)throw new Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,o||null}get activeRouter(){if(this.routes||this.routers.length!==1)throw new Error("No active router has been determined yet.");return this.routers[0]}};function xt(t,r){for(let e=0,n=t.patterns.length;e`Duplicate param name, use another name instead of '${a}' - ${t} ${r} <--- '${a}'`;for(let a=0,u=n.length;axt(p,f[1])))throw new Error(o(f[1]))}e.patterns.push(f),i.push(...e.patterns)}i.push(...e.patterns),e=e.children[l]}e.methods.length||(e.methods=[]);let h={},c={handler:s,name:this.name,score:this.order};return h[t]=c,e.methods.push(h),e}gHSets(t,r,s){var e,n;return(e=t.handlerSetCache)[n=`${r}:${s?"1":"0"}`]||(e[n]=(()=>{let i=[];for(let o=0,h=t.methods.length;oa.score-u.score).map(a=>a.handler),params:e}}};var G=class{constructor(){this.name="TrieRouter",this.node=new Q}add(t,r,s){let e=A(r);if(e){for(let n of e)this.node.insert(t,n,s);return}this.node.insert(t,r,s)}match(t,r){return this.node.search(t,r)}};var V=class extends U{constructor(t={}){super(t),this.router=t.router??new K({routers:[new z,new G]})}};var O=new V;O.get("/",t=>t.text("Hello from Hono running in Wasm Workers Server!"));O.get("/hello",t=>t.text("You can get a custom hello message by accessing /hello/your-name"));O.get("/hello/:name",t=>{let r=t.req.param("name");return t.text(`Hello ${r}! This app is running in Wasm Workers Server`)});O.notFound(t=>t.text("Awww! This page is missing",404));var Ve=O;export{Ve as default}; diff --git a/examples/js-hono/src/index.js b/examples/js-hono/src/index.js index 088fadec..0dd6a02c 100644 --- a/examples/js-hono/src/index.js +++ b/examples/js-hono/src/index.js @@ -19,4 +19,4 @@ app.notFound((c) => { return c.text('Awww! This page is missing', 404) }) -app.fire(); +export default app; diff --git a/examples/js-hono/src/package.json b/examples/js-hono/src/package.json index 956c99d2..6fc1c3b6 100644 --- a/examples/js-hono/src/package.json +++ b/examples/js-hono/src/package.json @@ -8,7 +8,7 @@ "author": "Wasm Labs ", "license": "Apache-2.0", "scripts": { - "build": "esbuild index.js --bundle --minify --outfile=../dist/[...app].js" + "build": "esbuild index.js --bundle --minify --format=esm --outfile=../dist/[...app].js" }, "dependencies": { "esbuild": "^0.19.4", diff --git a/examples/js-modules/README.md b/examples/js-modules/README.md new file mode 100644 index 00000000..27779ecb --- /dev/null +++ b/examples/js-modules/README.md @@ -0,0 +1,21 @@ +# JavaScript modules example + +Run a JavaScript that exports the application in Wasm Workers Server. + +## Prerequisites + +* Wasm Workers Server (wws): + + ```shell-session + curl -fsSL https://workers.wasmlabs.dev/install | bash + ``` + +## Run + +```shell-session +wws https://github.com/vmware-labs/wasm-workers-server.git -i --git-folder "examples/js-modules" +``` + +## Resources + +* [JavaScript documentation](https://workers.wasmlabs.dev/docs/languages/javascript) diff --git a/examples/js-modules/index.js b/examples/js-modules/index.js new file mode 100644 index 00000000..cd3a146d --- /dev/null +++ b/examples/js-modules/index.js @@ -0,0 +1,44 @@ +/** + * Builds a reply to the given request + */ +export default { + async fetch(request) { + // Body response + const body = ` + + Wasm Workers Server + + + + + + +
+

Hello from Wasm Workers Server 👋

+
Replying to ${request.url}
+  Method: ${request.method}
+  User Agent: ${request.headers.get("user-agent")}
+  Payload: ${request.body || "-"}
+

+ This page was generated by a JavaScript (module) file running in WebAssembly. +

+
+ `; + + // Build a new response + let response = new Response(body); + + // Add a new header + response.headers.set("x-generated-by", "wasm-workers-server"); + + return response; + }, +}; diff --git a/kits/javascript/Cargo.lock b/kits/javascript/Cargo.lock new file mode 100644 index 00000000..4ab0dd7d --- /dev/null +++ b/kits/javascript/Cargo.lock @@ -0,0 +1,1138 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "futures-channel" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" + +[[package]] +name = "futures-task" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" + +[[package]] +name = "futures-util" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951dfc2e32ac02d67c90c0d65bd27009a635dc9b381a2cc7d284ab01e3a0150d" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92445bc9cc14bfa0a3ce56817dc3b5bcc227a168781a356b702410789cec0d10" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75264b2003a3913f118d35c586e535293b3e22e41f074930762929d071e092" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "tracing", + "want", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "javy" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bea151527df24f765b795a87a80d144f8cc35ef99acaed99465f1206a4501e" +dependencies = [ + "anyhow", + "quickjs-wasm-rs", + "serde-transcode", + "serde_json", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pulldown-cmark" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffade02495f22453cd593159ea2f59827aae7f53fa8323f756799b670881dcf8" +dependencies = [ + "bitflags 1.3.2", + "memchr", + "unicase", +] + +[[package]] +name = "quickjs-wasm-rs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "174a4fb51c14dcb82f1f98ec1ec3c2f26f2cd6e40f200d86c5f6eecacf40b409" +dependencies = [ + "anyhow", + "once_cell", + "quickjs-wasm-sys", + "serde", +] + +[[package]] +name = "quickjs-wasm-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1af9a5eb35f2df97dc9816b711e681b0c3cc8f5c18fdd7df0021ec4f60bbcb4" +dependencies = [ + "anyhow", + "bindgen", + "bytes", + "cc", + "futures-core", + "futures-task", + "futures-util", + "http-body-util", + "hyper", + "mio", + "native-tls", + "openssl-macros", + "tokio", + "tokio-macros", + "tokio-native-tls", + "walkdir", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaac441002f822bc9705a681810a4dd2963094b9ca0ddc41cb963a4c189189ea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5011c7e263a695dc8ca064cddb722af1be54e517a280b12a5356f98366899e5d" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-transcode" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "590c0e25c2a5bb6e85bf5c1bce768ceb86b316e7a01bdf07d2cb4ec2271990e2" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +dependencies = [ + "autocfg", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2ef2af84856a50c1d430afce2fdded0a4ec7eda868db86409b4543df0797f9" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-workers-quick-js-engine" +version = "0.1.0" +dependencies = [ + "anyhow", + "javy", + "regex", + "wit-bindgen-rust", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wit-bindgen-gen-core" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "anyhow", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-gen-rust" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "heck", + "wit-bindgen-gen-core", +] + +[[package]] +name = "wit-bindgen-gen-rust-wasm" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "heck", + "wit-bindgen-gen-core", + "wit-bindgen-gen-rust", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "async-trait", + "bitflags 1.3.2", + "wit-bindgen-rust-impl", +] + +[[package]] +name = "wit-bindgen-rust-impl" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "proc-macro2", + "syn 1.0.109", + "wit-bindgen-gen-core", + "wit-bindgen-gen-rust-wasm", +] + +[[package]] +name = "wit-parser" +version = "0.2.0" +source = "git+https://github.com/bytecodealliance/wit-bindgen?rev=cb871cfa1ee460b51eb1d144b175b9aab9c50aba#cb871cfa1ee460b51eb1d144b175b9aab9c50aba" +dependencies = [ + "anyhow", + "id-arena", + "pulldown-cmark", + "unicode-normalization", + "unicode-xid", +] diff --git a/kits/javascript/Cargo.toml b/kits/javascript/Cargo.toml index b586dffc..3119d708 100644 --- a/kits/javascript/Cargo.toml +++ b/kits/javascript/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0" -javy = { version = "1.0.0", features = ["json"] } +javy = { version = "2.0.0", features = ["json"] } +regex = "1.10.1" # Use an old version until we add support for components. wit-bindgen-rust = { git = "https://github.com/bytecodealliance/wit-bindgen", rev = "cb871cfa1ee460b51eb1d144b175b9aab9c50aba" } diff --git a/kits/javascript/Makefile b/kits/javascript/Makefile index 1fedb122..5b628f08 100644 --- a/kits/javascript/Makefile +++ b/kits/javascript/Makefile @@ -2,4 +2,4 @@ build: cargo build --target wasm32-wasi --release && \ - cp ../../target/wasm32-wasi/release/wasm-workers-quick-js-engine.wasm ./ \ No newline at end of file + cp ./target/wasm32-wasi/release/wasm-workers-quick-js-engine.wasm ./ diff --git a/kits/javascript/shims/index.js b/kits/javascript/shims/index.js index 877d5dfc..20bb9ccb 100644 --- a/kits/javascript/shims/index.js +++ b/kits/javascript/shims/index.js @@ -19,7 +19,7 @@ globalThis.TextDecoder = TextDecoder; // Main logic let handlerFunction; -let addEventListener = (_eventName, handler) => { +globalThis.addEventListener = (_eventName, handler) => { // Store the callback globally handlerFunction = handler; }; @@ -60,10 +60,10 @@ const requestToHandler = input => { }; // This is the entrypoint for the project. -entrypoint = requestToHandler; +globalThis.entrypoint = requestToHandler; // Set the result -result = {}; +globalThis.result = {}; // Save errors -error = null +globalThis.error = null diff --git a/kits/javascript/src/main.rs b/kits/javascript/src/main.rs index d74c2d4d..88280e08 100644 --- a/kits/javascript/src/main.rs +++ b/kits/javascript/src/main.rs @@ -6,6 +6,7 @@ mod error; use bindings::load_bindings_into_global; use javy::{json, Runtime}; +use regex::Regex; use std::{ env, fs, io::{stdin, stdout, Read, Write}, @@ -17,6 +18,34 @@ wit_bindgen_rust::import!({paths: ["../../wit/core/http.wit"]}); // JS polyfill static POLYFILL: &str = include_str!("../shims/dist/index.js"); +/// Determine the worker JS type +enum JSWorkerType { + /// Relies on the global scope. No ECMA modules. + Global, + /// Exports a default function which is the one replying to the events. + DefaultExport, +} + +/// Identify the worker source code to run it properly. +fn identify_type(src: &str) -> JSWorkerType { + // Detect default exported functions and objects + let default_regex = Regex::new(r"(?-u)export\s+default\s+\w+;?").unwrap(); + // Detect default exported object + let default_block_regex = Regex::new(r"export\s+default\s*\{([\s\n\r]*.*)+\};?").unwrap(); + // Detect exported functions with the "as" syntax like "export { app as default }"; + let default_as_regex = + Regex::new(r"(?-u)export\s*\{[\s\n\r]*\w+\s+(as default){1}[\s\n\r]*\};?").unwrap(); + + if default_regex.is_match(src) + || default_block_regex.is_match(src) + || default_as_regex.is_match(src) + { + JSWorkerType::DefaultExport + } else { + JSWorkerType::Global + } +} + fn main() { let runtime = Runtime::default(); let context = runtime.context(); @@ -49,7 +78,25 @@ fn main() { }, } - context.eval_global("handler.js", &contents).unwrap(); + // Checks if the given code uses ECMAScript modules. Currently, we don't plan to integrate + // a full JavaScript parser for this, so we are going to rely on regexps. This implementation + // has limitations like detecting "// export default app;" as a module. In the future, + // we may add more complete checks. + match identify_type(&contents) { + JSWorkerType::DefaultExport => { + let _ = context.eval_module("handler.mjs", &contents).unwrap(); + let _ = context + .eval_module( + "runtime.mjs", + &format!("import {{ default as handler }} from 'handler.mjs'; addEventListener('fetch', (e) => {{ e.respondWith(handler.fetch(e.request)) }});"), + ) + .unwrap(); + } + _ => { + context.eval_global("handler.js", &contents).unwrap(); + } + } + let global = context.global_object().unwrap(); let entrypoint = global.get_property("entrypoint").unwrap(); diff --git a/kits/javascript/wasm-workers-quick-js-engine.wasm b/kits/javascript/wasm-workers-quick-js-engine.wasm index 77a5d241..6ace5d47 100755 Binary files a/kits/javascript/wasm-workers-quick-js-engine.wasm and b/kits/javascript/wasm-workers-quick-js-engine.wasm differ diff --git a/tests/e2e.rs b/tests/e2e.rs index 39f868d1..0a69e671 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -206,6 +206,16 @@ mod test { "http://localhost:8080", "This page was generated by a JavaScript (async worker) file", ), + ( + "js-modules", + "http://localhost:8080", + "This page was generated by a JavaScript (module) file", + ), + ( + &format!("js-hono{}dist", std::path::MAIN_SEPARATOR_STR), + "http://localhost:8080", + "Hello from Hono", + ), ( "js-json", "http://localhost:8080/handler",