elysia
Version:
Ergonomic Framework for Human
1,263 lines (1,253 loc) • 303 kB
JavaScript
// node_modules/memoirist/dist/index.mjs
var createNode = (part, inert) => {
let inertMap = inert?.length ? {} : null;
if (inertMap)
for (let child of inert)
inertMap[child.part.charCodeAt(0)] = child;
return {
part,
store: null,
inert: inertMap,
params: null,
wildcardStore: null
};
}, cloneNode = (node, part) => ({
...node,
part
}), createParamNode = (name) => ({
name,
store: null,
inert: null
}), Memoirist = class _Memoirist {
constructor(config = {}) {
this.config = config, config.lazy && (this.find = this.lazyFind);
}
root = {};
history = [];
deferred = [];
static regex = {
static: /:.+?(?=\/|$)/,
params: /:.+?(?=\/|$)/g,
optionalParams: /(\/:\w+\?)/g
};
lazyFind = (method, url) => this.config.lazy ? (this.build(), this.find(method, url)) : this.find;
build() {
if (this.config.lazy) {
for (let [method, path, store] of this.deferred)
this.add(method, path, store, { lazy: !1, ignoreHistory: !0 });
this.deferred = [], this.find = (method, url) => {
let root = this.root[method];
return root ? matchRoute(url, url.length, root, 0) : null;
};
}
}
add(method, path, store, {
ignoreError = !1,
ignoreHistory = !1,
lazy = this.config.lazy
} = {}) {
if (lazy)
return this.find = this.lazyFind, this.deferred.push([method, path, store]), store;
if (typeof path != "string")
throw new TypeError("Route path must be a string");
path === "" ? path = "/" : path[0] !== "/" && (path = `/${path}`);
let isWildcard = path[path.length - 1] === "*", optionalParams = path.match(_Memoirist.regex.optionalParams);
if (optionalParams) {
let originalPath = path.replaceAll("?", "");
this.add(method, originalPath, store, {
ignoreError,
ignoreHistory,
lazy
});
for (let i = 0; i < optionalParams.length; i++) {
let newPath = path.replace(optionalParams[i], "");
this.add(method, newPath, store, {
ignoreError: !0,
ignoreHistory,
lazy
});
}
return store;
}
if (optionalParams && (path = path.replaceAll("?", "")), this.history.find(([m, p, s]) => m === method && p === path))
return store;
(isWildcard || optionalParams && path.charCodeAt(path.length - 1) === 63) && (path = path.slice(0, -1)), ignoreHistory || this.history.push([method, path, store]);
let inertParts = path.split(_Memoirist.regex.static), paramParts = path.match(_Memoirist.regex.params) || [];
inertParts[inertParts.length - 1] === "" && inertParts.pop();
let node;
this.root[method] ? node = this.root[method] : node = this.root[method] = createNode("/");
let paramPartsIndex = 0;
for (let i = 0; i < inertParts.length; ++i) {
let part = inertParts[i];
if (i > 0) {
let param = paramParts[paramPartsIndex++].slice(1);
if (node.params === null)
node.params = createParamNode(param);
else if (node.params.name !== param) {
if (ignoreError)
return store;
throw new Error(
`Cannot create route "${path}" with parameter "${param}" because a route already exists with a different parameter name ("${node.params.name}") in the same location`
);
}
let params = node.params;
if (params.inert === null) {
node = params.inert = createNode(part);
continue;
}
node = params.inert;
}
for (let j = 0; ; ) {
if (j === part.length) {
if (j < node.part.length) {
let childNode = cloneNode(node, node.part.slice(j));
Object.assign(node, createNode(part, [childNode]));
}
break;
}
if (j === node.part.length) {
node.inert === null && (node.inert = {});
let inert = node.inert[part.charCodeAt(j)];
if (inert) {
node = inert, part = part.slice(j), j = 0;
continue;
}
let childNode = createNode(part.slice(j));
node.inert[part.charCodeAt(j)] = childNode, node = childNode;
break;
}
if (part[j] !== node.part[j]) {
let existingChild = cloneNode(node, node.part.slice(j)), newChild = createNode(part.slice(j));
Object.assign(
node,
createNode(node.part.slice(0, j), [
existingChild,
newChild
])
), node = newChild;
break;
}
++j;
}
}
if (paramPartsIndex < paramParts.length) {
let name = paramParts[paramPartsIndex].slice(1);
if (node.params === null)
node.params = createParamNode(name);
else if (node.params.name !== name) {
if (ignoreError)
return store;
throw new Error(
`Cannot create route "${path}" with parameter "${name}" because a route already exists with a different parameter name ("${node.params.name}") in the same location`
);
}
return node.params.store === null && (node.params.store = store), node.params.store;
}
return isWildcard ? (node.wildcardStore === null && (node.wildcardStore = store), node.wildcardStore) : (node.store === null && (node.store = store), node.store);
}
find(method, url) {
let root = this.root[method];
return root ? matchRoute(url, url.length, root, 0) : null;
}
}, matchRoute = (url, urlLength, node, startIndex) => {
let part = node.part, length = part.length, endIndex = startIndex + length;
if (length > 1) {
if (endIndex > urlLength)
return null;
if (length < 15) {
for (let i = 1, j = startIndex + 1; i < length; ++i, ++j)
if (part.charCodeAt(i) !== url.charCodeAt(j))
return null;
} else if (url.slice(startIndex, endIndex) !== part)
return null;
}
if (endIndex === urlLength)
return node.store !== null ? {
store: node.store,
params: {}
} : node.wildcardStore !== null ? {
store: node.wildcardStore,
params: { "*": "" }
} : null;
if (node.inert !== null) {
let inert = node.inert[url.charCodeAt(endIndex)];
if (inert !== void 0) {
let route = matchRoute(url, urlLength, inert, endIndex);
if (route !== null)
return route;
}
}
if (node.params !== null) {
let { store, name, inert } = node.params, slashIndex = url.indexOf("/", endIndex);
if (slashIndex !== endIndex) {
if (slashIndex === -1 || slashIndex >= urlLength) {
if (store !== null) {
let params = {};
return params[name] = url.substring(endIndex, urlLength), {
store,
params
};
}
} else if (inert !== null) {
let route = matchRoute(url, urlLength, inert, slashIndex);
if (route !== null)
return route.params[name] = url.substring(endIndex, slashIndex), route;
}
}
}
return node.wildcardStore !== null ? {
store: node.wildcardStore,
params: {
"*": url.substring(endIndex, urlLength)
}
} : null;
};
// src/index.ts
import {
Kind as Kind5
} from "@sinclair/typebox";
// src/type-system/index.ts
import { Type, Kind as Kind2 } from "@sinclair/typebox";
// src/type-system/format.ts
import { FormatRegistry } from "@sinclair/typebox";
var fullFormats = {
// date: http://tools.ietf.org/html/rfc3339#section-5.6
date,
// date-time: http://tools.ietf.org/html/rfc3339#section-5.6
time: getTime(!0),
"date-time": getDateTime(!0),
"iso-time": getTime(!1),
"iso-date-time": getDateTime(!1),
// duration: https://tools.ietf.org/html/rfc3339#appendix-A
duration: /^P(?!$)((\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+S)?)?|(\d+W)?)$/,
uri,
"uri-reference": /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,
// uri-template: https://tools.ietf.org/html/rfc6570
"uri-template": /^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,
// For the source: https://gist.github.com/dperini/729294
// For test cases: https://mathiasbynens.be/demo/url-regex
url: /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)(?:\.(?:[a-z0-9\u{00a1}-\u{ffff}]+-)*[a-z0-9\u{00a1}-\u{ffff}]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,
email: /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i,
hostname: /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,
// optimized https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9780596802837/ch07s16.html
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/,
ipv6: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,
regex,
// uuid: http://tools.ietf.org/html/rfc4122
uuid: /^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,
// JSON-pointer: https://tools.ietf.org/html/rfc6901
// uri fragment: https://tools.ietf.org/html/rfc3986#appendix-A
"json-pointer": /^(?:\/(?:[^~/]|~0|~1)*)*$/,
"json-pointer-uri-fragment": /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,
// relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00
"relative-json-pointer": /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,
// the following formats are used by the openapi specification: https://spec.openapis.org/oas/v3.0.0#data-types
// byte: https://github.com/miguelmota/is-base64
byte,
// signed 32 bit integer
int32: { type: "number", validate: validateInt32 },
// signed 64 bit integer
int64: { type: "number", validate: validateInt64 },
// C-type float
float: { type: "number", validate: validateNumber },
// C-type double
double: { type: "number", validate: validateNumber },
// hint to the UI to hide input strings
password: !0,
// unchecked string payload
binary: !0
};
function isLeapYear(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
var DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/, DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
function date(str) {
let matches = DATE.exec(str);
if (!matches) return !1;
let year = +matches[1], month = +matches[2], day = +matches[3];
return month >= 1 && month <= 12 && day >= 1 && day <= (month === 2 && isLeapYear(year) ? 29 : DAYS[month]);
}
var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
function getTime(strictTimeZone) {
return function(str) {
let matches = TIME.exec(str);
if (!matches) return !1;
let hr = +matches[1], min = +matches[2], sec = +matches[3], tz = matches[4], tzSign = matches[5] === "-" ? -1 : 1, tzH = +(matches[6] || 0), tzM = +(matches[7] || 0);
if (tzH > 23 || tzM > 59 || strictTimeZone && !tz) return !1;
if (hr <= 23 && min <= 59 && sec < 60) return !0;
let utcMin = min - tzM * tzSign, utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0);
return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61;
};
}
var parseDateTimeEmptySpace = (str) => str.charCodeAt(str.length - 6) === 32 ? str.slice(0, -6) + "+" + str.slice(-5) : str, DATE_TIME_SEPARATOR = /t|\s/i;
function getDateTime(strictTimeZone) {
let time = getTime(strictTimeZone);
return function(str) {
let dateTime = str.split(DATE_TIME_SEPARATOR);
return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1]);
};
}
var NOT_URI_FRAGMENT = /\/|:/, URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
function uri(str) {
return NOT_URI_FRAGMENT.test(str) && URI.test(str);
}
var BYTE = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm;
function byte(str) {
return BYTE.lastIndex = 0, BYTE.test(str);
}
var MIN_INT32 = -(2 ** 31), MAX_INT32 = 2 ** 31 - 1;
function validateInt32(value) {
return Number.isInteger(value) && value <= MAX_INT32 && value >= MIN_INT32;
}
function validateInt64(value) {
return Number.isInteger(value);
}
function validateNumber() {
return !0;
}
var Z_ANCHOR = /[^\\]\\Z/;
function regex(str) {
if (Z_ANCHOR.test(str)) return !1;
try {
return new RegExp(str), !0;
} catch {
return !1;
}
}
var isISO8601 = /(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/, isFormalDate = /(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{2}\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT(?:\+|-)\d{4}\s\([^)]+\)/, isShortenDate = /^(?:(?:(?:(?:0?[1-9]|[12][0-9]|3[01])[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:19|20)\d{2})|(?:(?:19|20)\d{2}[/\s-](?:0?[1-9]|1[0-2])[/\s-](?:0?[1-9]|[12][0-9]|3[01]))))(?:\s(?:1[012]|0?[1-9]):[0-5][0-9](?::[0-5][0-9])?(?:\s[AP]M)?)?$/, _validateDate = fullFormats.date, _validateDateTime = fullFormats["date-time"];
FormatRegistry.Has("date") || FormatRegistry.Set("date", (value) => {
let temp = parseDateTimeEmptySpace(value).replace(/"/g, "");
if (isISO8601.test(temp) || isFormalDate.test(temp) || isShortenDate.test(temp) || _validateDate(temp)) {
let date2 = new Date(temp);
if (!Number.isNaN(date2.getTime())) return !0;
}
return !1;
});
FormatRegistry.Has("date-time") || FormatRegistry.Set("date-time", (value) => {
let temp = value.replace(/"/g, "");
if (isISO8601.test(temp) || isFormalDate.test(temp) || isShortenDate.test(temp) || _validateDateTime(temp)) {
let date2 = new Date(temp);
if (!Number.isNaN(date2.getTime())) return !0;
}
return !1;
});
Object.entries(fullFormats).forEach((formatEntry) => {
let [formatName, formatValue] = formatEntry;
FormatRegistry.Has(formatName) || (formatValue instanceof RegExp ? FormatRegistry.Set(formatName, (value) => formatValue.test(value)) : typeof formatValue == "function" && FormatRegistry.Set(formatName, formatValue));
});
FormatRegistry.Has("numeric") || FormatRegistry.Set("numeric", (value) => !!value && !isNaN(+value));
FormatRegistry.Has("integer") || FormatRegistry.Set(
"integer",
(value) => !!value && Number.isInteger(+value)
);
FormatRegistry.Has("boolean") || FormatRegistry.Set(
"boolean",
(value) => value === "true" || value === "false"
);
FormatRegistry.Has("ObjectString") || FormatRegistry.Set("ObjectString", (value) => {
let start = value.charCodeAt(0);
if ((start === 9 || start === 10 || start === 32) && (start = value.trimStart().charCodeAt(0)), start !== 123 && start !== 91) return !1;
try {
return JSON.parse(value), !0;
} catch {
return !1;
}
});
FormatRegistry.Has("ArrayString") || FormatRegistry.Set("ArrayString", (value) => {
let start = value.charCodeAt(0);
if ((start === 9 || start === 10 || start === 32) && (start = value.trimStart().charCodeAt(0)), start !== 123 && start !== 91) return !1;
try {
return JSON.parse(value), !0;
} catch {
return !1;
}
});
// src/type-system/utils.ts
import {
Kind,
TypeRegistry,
Unsafe
} from "@sinclair/typebox";
import { Value as Value2 } from "@sinclair/typebox/value";
import { TypeCompiler } from "@sinclair/typebox/compiler";
// src/universal/utils.ts
var isBun = typeof Bun < "u";
// src/universal/file.ts
var mime2 = {
aac: "audio/aac",
abw: "application/x-abiword",
ai: "application/postscript",
arc: "application/octet-stream",
avi: "video/x-msvideo",
azw: "application/vnd.amazon.ebook",
bin: "application/octet-stream",
bz: "application/x-bzip",
bz2: "application/x-bzip2",
csh: "application/x-csh",
css: "text/css",
csv: "text/csv",
doc: "application/msword",
dll: "application/octet-stream",
eot: "application/vnd.ms-fontobject",
epub: "application/epub+zip",
gif: "image/gif",
htm: "text/html",
html: "text/html",
ico: "image/x-icon",
ics: "text/calendar",
jar: "application/java-archive",
jpeg: "image/jpeg",
jpg: "image/jpeg",
js: "application/javascript",
json: "application/json",
mid: "audio/midi",
midi: "audio/midi",
mp2: "audio/mpeg",
mp3: "audio/mpeg",
mp4: "video/mp4",
mpa: "video/mpeg",
mpe: "video/mpeg",
mpeg: "video/mpeg",
mpkg: "application/vnd.apple.installer+xml",
odp: "application/vnd.oasis.opendocument.presentation",
ods: "application/vnd.oasis.opendocument.spreadsheet",
odt: "application/vnd.oasis.opendocument.text",
oga: "audio/ogg",
ogv: "video/ogg",
ogx: "application/ogg",
otf: "font/otf",
png: "image/png",
pdf: "application/pdf",
ppt: "application/vnd.ms-powerpoint",
rar: "application/x-rar-compressed",
rtf: "application/rtf",
sh: "application/x-sh",
svg: "image/svg+xml",
swf: "application/x-shockwave-flash",
tar: "application/x-tar",
tif: "image/tiff",
tiff: "image/tiff",
ts: "application/typescript",
ttf: "font/ttf",
txt: "text/plain",
vsd: "application/vnd.visio",
wav: "audio/x-wav",
weba: "audio/webm",
webm: "video/webm",
webp: "image/webp",
woff: "font/woff",
woff2: "font/woff2",
xhtml: "application/xhtml+xml",
xls: "application/vnd.ms-excel",
xlsx: "application/vnd.ms-excel",
xlsx_OLD: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
xml: "application/xml",
xul: "application/vnd.mozilla.xul+xml",
zip: "application/zip",
"3gp": "video/3gpp",
"3gp_DOES_NOT_CONTAIN_VIDEO": "audio/3gpp",
"3gp2": "video/3gpp2",
"3gp2_DOES_NOT_CONTAIN_VIDEO": "audio/3gpp2",
"7z": "application/x-7z-compressed"
}, getFileExtension = (path) => {
let index = path.lastIndexOf(".");
return index === -1 ? "" : path.slice(index + 1);
}, file = (path) => new ElysiaFile(path), createReadStream, stat, ElysiaFile = class {
constructor(path) {
this.path = path;
if (isBun) this.value = Bun.file(path);
else if (typeof window < "u")
console.warn("Browser environment does not support file");
else if (!createReadStream || !stat)
try {
this.value = import("fs").then((fs) => (createReadStream = fs.createReadStream, fs.createReadStream(path))), this.stats = import("fs/promises").then((fs) => (stat = fs.stat, fs.stat(path)));
} catch {
}
else
this.value = createReadStream(path), this.stats = stat(path);
}
get type() {
return (
// @ts-ignore
mime2[getFileExtension(this.path)] || "application/octet-stream"
);
}
get length() {
return isBun ? this.value.size : this.stats?.then((x) => x.size) ?? 0;
}
};
// src/error.ts
import { Value } from "@sinclair/typebox/value";
// src/utils.ts
var hasHeaderShorthand = "toJSON" in new Headers(), replaceUrlPath = (url, pathname) => {
let urlObject = new URL(url);
return urlObject.pathname = pathname, urlObject.toString();
}, isClass = (v) => typeof v == "function" && /^\s*class\s+/.test(v.toString()) || // Handle Object.create(null)
v.toString && // Handle import * as Sentry from '@sentry/bun'
// This also handle [object Date], [object Array]
// and FFI value like [object Prisma]
v.toString().startsWith("[object ") && v.toString() !== "[object Object]" || // If object prototype is not pure, then probably a class-like object
isNotEmpty(Object.getPrototypeOf(v)), isObject = (item) => item && typeof item == "object" && !Array.isArray(item), mergeDeep = (target, source, options) => {
let skipKeys = options?.skipKeys, override = options?.override ?? !0;
if (!isObject(target) || !isObject(source)) return target;
for (let [key, value] of Object.entries(source))
if (!skipKeys?.includes(key)) {
if (!isObject(value) || !(key in target) || isClass(value)) {
(override || !(key in target)) && (target[key] = value);
continue;
}
target[key] = mergeDeep(
target[key],
value,
{ skipKeys, override }
);
}
return target;
}, mergeCookie = (a, b) => {
let v = mergeDeep(Object.assign({}, a), b, {
skipKeys: ["properties"]
});
return v.properties && delete v.properties, v;
}, mergeObjectArray = (a, b) => {
if (!b) return a;
let array = [], checksums = [];
if (a) {
Array.isArray(a) || (a = [a]);
for (let item of a)
array.push(item), item.checksum && checksums.push(item.checksum);
}
if (b) {
Array.isArray(b) || (b = [b]);
for (let item of b)
checksums.includes(item.checksum) || array.push(item);
}
return array;
}, primitiveHooks = [
"start",
"request",
"parse",
"transform",
"resolve",
"beforeHandle",
"afterHandle",
"mapResponse",
"afterResponse",
"trace",
"error",
"stop",
"body",
"headers",
"params",
"query",
"response",
"type",
"detail"
], primitiveHookMap = primitiveHooks.reduce(
(acc, x) => (acc[x] = !0, acc),
{}
), mergeResponse = (a, b) => {
let isRecordNumber = (x) => typeof x == "object" && Object.keys(x).every(isNumericString);
return isRecordNumber(a) && isRecordNumber(b) ? Object.assign(a, b) : a && !isRecordNumber(a) && isRecordNumber(b) ? Object.assign({ 200: a }, b) : b ?? a;
}, mergeSchemaValidator = (a, b) => !a && !b ? {
body: void 0,
headers: void 0,
params: void 0,
query: void 0,
cookie: void 0,
response: void 0
} : {
body: b?.body ?? a?.body,
headers: b?.headers ?? a?.headers,
params: b?.params ?? a?.params,
query: b?.query ?? a?.query,
cookie: b?.cookie ?? a?.cookie,
// @ts-ignore ? This order is correct - SaltyAom
response: mergeResponse(
// @ts-ignore
a?.response,
// @ts-ignore
b?.response
)
}, mergeHook = (a, b) => {
if (!Object.values(b).find((x) => x != null))
return { ...a };
let hook = {
...a,
...b,
// Merge local hook first
// @ts-ignore
body: b?.body ?? a?.body,
// @ts-ignore
headers: b?.headers ?? a?.headers,
// @ts-ignore
params: b?.params ?? a?.params,
// @ts-ignore
query: b?.query ?? a?.query,
// @ts-ignore
cookie: b?.cookie ?? a?.cookie,
// ? This order is correct - SaltyAom
response: mergeResponse(
// @ts-ignore
a?.response,
// @ts-ignore
b?.response
),
type: a?.type || b?.type,
detail: mergeDeep(
// @ts-ignore
b?.detail ?? {},
// @ts-ignore
a?.detail ?? {}
),
parse: mergeObjectArray(a?.parse, b?.parse),
transform: mergeObjectArray(a?.transform, b?.transform),
beforeHandle: mergeObjectArray(
mergeObjectArray(
// @ts-ignore
fnToContainer(a?.resolve, "resolve"),
a?.beforeHandle
),
mergeObjectArray(
fnToContainer(b.resolve, "resolve"),
b?.beforeHandle
)
),
afterHandle: mergeObjectArray(a?.afterHandle, b?.afterHandle),
mapResponse: mergeObjectArray(a?.mapResponse, b?.mapResponse),
afterResponse: mergeObjectArray(
a?.afterResponse,
b?.afterResponse
),
trace: mergeObjectArray(a?.trace, b?.trace),
error: mergeObjectArray(a?.error, b?.error)
};
return hook.resolve && delete hook.resolve, hook;
}, lifeCycleToArray = (a) => {
a.parse && !Array.isArray(a.parse) && (a.parse = [a.parse]), a.transform && !Array.isArray(a.transform) && (a.transform = [a.transform]), a.afterHandle && !Array.isArray(a.afterHandle) && (a.afterHandle = [a.afterHandle]), a.mapResponse && !Array.isArray(a.mapResponse) && (a.mapResponse = [a.mapResponse]), a.afterResponse && !Array.isArray(a.afterResponse) && (a.afterResponse = [a.afterResponse]), a.trace && !Array.isArray(a.trace) && (a.trace = [a.trace]), a.error && !Array.isArray(a.error) && (a.error = [a.error]);
let beforeHandle = [];
return a.resolve && (beforeHandle = fnToContainer(
// @ts-expect-error
Array.isArray(a.resolve) ? a.resolve : [a.resolve],
"resolve"
), delete a.resolve), a.beforeHandle && (beforeHandle.length ? beforeHandle = beforeHandle.concat(
Array.isArray(a.beforeHandle) ? a.beforeHandle : [a.beforeHandle]
) : beforeHandle = Array.isArray(a.beforeHandle) ? a.beforeHandle : [a.beforeHandle]), beforeHandle.length && (a.beforeHandle = beforeHandle), a;
}, isBun2 = typeof Bun < "u", hasBunHash = isBun2 && typeof Bun.hash == "function", checksum = (s) => {
if (hasBunHash) return Bun.hash(s);
let h = 9;
for (let i = 0; i < s.length; ) h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
return h = h ^ h >>> 9;
}, injectChecksum = (checksum2, x) => {
if (!x) return;
if (!Array.isArray(x)) {
let fn = x;
return checksum2 && !fn.checksum && (fn.checksum = checksum2), fn.scope === "scoped" && (fn.scope = "local"), fn;
}
let fns = [...x];
for (let fn of fns)
checksum2 && !fn.checksum && (fn.checksum = checksum2), fn.scope === "scoped" && (fn.scope = "local");
return fns;
}, mergeLifeCycle = (a, b, checksum2) => ({
start: mergeObjectArray(
a.start,
injectChecksum(checksum2, b?.start)
),
request: mergeObjectArray(
a.request,
injectChecksum(checksum2, b?.request)
),
parse: mergeObjectArray(
a.parse,
injectChecksum(checksum2, b?.parse)
),
transform: mergeObjectArray(
a.transform,
injectChecksum(checksum2, b?.transform)
),
beforeHandle: mergeObjectArray(
mergeObjectArray(
// @ts-ignore
fnToContainer(a.resolve, "resolve"),
a.beforeHandle
),
injectChecksum(
checksum2,
mergeObjectArray(
fnToContainer(b?.resolve, "resolve"),
b?.beforeHandle
)
)
),
afterHandle: mergeObjectArray(
a.afterHandle,
injectChecksum(checksum2, b?.afterHandle)
),
mapResponse: mergeObjectArray(
a.mapResponse,
injectChecksum(checksum2, b?.mapResponse)
),
afterResponse: mergeObjectArray(
a.afterResponse,
injectChecksum(checksum2, b?.afterResponse)
),
// Already merged on Elysia._use, also logic is more complicated, can't directly merge
trace: mergeObjectArray(
a.trace,
injectChecksum(checksum2, b?.trace)
),
error: mergeObjectArray(
a.error,
injectChecksum(checksum2, b?.error)
),
stop: mergeObjectArray(
a.stop,
injectChecksum(checksum2, b?.stop)
)
}), asHookType = (fn, inject, { skipIfHasType = !1 }) => {
if (!fn) return fn;
if (!Array.isArray(fn))
return skipIfHasType ? fn.scope ??= inject : fn.scope = inject, fn;
for (let x of fn)
skipIfHasType ? x.scope ??= inject : x.scope = inject;
return fn;
}, filterGlobal = (fn) => {
if (!fn) return fn;
if (!Array.isArray(fn))
switch (fn.scope) {
case "global":
case "scoped":
return { ...fn };
default:
return { fn };
}
let array = [];
for (let x of fn)
switch (x.scope) {
case "global":
case "scoped":
array.push({
...x
});
break;
}
return array;
}, filterGlobalHook = (hook) => ({
// rest is validator
...hook,
type: hook?.type,
detail: hook?.detail,
parse: filterGlobal(hook?.parse),
transform: filterGlobal(hook?.transform),
beforeHandle: filterGlobal(hook?.beforeHandle),
afterHandle: filterGlobal(hook?.afterHandle),
mapResponse: filterGlobal(hook?.mapResponse),
afterResponse: filterGlobal(hook?.afterResponse),
error: filterGlobal(hook?.error),
trace: filterGlobal(hook?.trace)
}), StatusMap = {
Continue: 100,
"Switching Protocols": 101,
Processing: 102,
"Early Hints": 103,
OK: 200,
Created: 201,
Accepted: 202,
"Non-Authoritative Information": 203,
"No Content": 204,
"Reset Content": 205,
"Partial Content": 206,
"Multi-Status": 207,
"Already Reported": 208,
"Multiple Choices": 300,
"Moved Permanently": 301,
Found: 302,
"See Other": 303,
"Not Modified": 304,
"Temporary Redirect": 307,
"Permanent Redirect": 308,
"Bad Request": 400,
Unauthorized: 401,
"Payment Required": 402,
Forbidden: 403,
"Not Found": 404,
"Method Not Allowed": 405,
"Not Acceptable": 406,
"Proxy Authentication Required": 407,
"Request Timeout": 408,
Conflict: 409,
Gone: 410,
"Length Required": 411,
"Precondition Failed": 412,
"Payload Too Large": 413,
"URI Too Long": 414,
"Unsupported Media Type": 415,
"Range Not Satisfiable": 416,
"Expectation Failed": 417,
"I'm a teapot": 418,
"Misdirected Request": 421,
"Unprocessable Content": 422,
Locked: 423,
"Failed Dependency": 424,
"Too Early": 425,
"Upgrade Required": 426,
"Precondition Required": 428,
"Too Many Requests": 429,
"Request Header Fields Too Large": 431,
"Unavailable For Legal Reasons": 451,
"Internal Server Error": 500,
"Not Implemented": 501,
"Bad Gateway": 502,
"Service Unavailable": 503,
"Gateway Timeout": 504,
"HTTP Version Not Supported": 505,
"Variant Also Negotiates": 506,
"Insufficient Storage": 507,
"Loop Detected": 508,
"Not Extended": 510,
"Network Authentication Required": 511
}, InvertedStatusMap = Object.fromEntries(
Object.entries(StatusMap).map(([k, v]) => [v, k])
);
function removeTrailingEquals(digest) {
let trimmedDigest = digest;
for (; trimmedDigest.endsWith("="); )
trimmedDigest = trimmedDigest.slice(0, -1);
return trimmedDigest;
}
var encoder = new TextEncoder(), signCookie = async (val, secret) => {
if (typeof val != "string")
throw new TypeError("Cookie value must be provided as a string.");
if (secret === null) throw new TypeError("Secret key must be provided.");
let secretKey = await crypto.subtle.importKey(
"raw",
encoder.encode(secret),
{ name: "HMAC", hash: "SHA-256" },
!1,
["sign"]
), hmacBuffer = await crypto.subtle.sign(
"HMAC",
secretKey,
encoder.encode(val)
);
return val + "." + removeTrailingEquals(Buffer.from(hmacBuffer).toString("base64"));
}, unsignCookie = async (input, secret) => {
if (typeof input != "string")
throw new TypeError("Signed cookie string must be provided.");
if (secret === null) throw new TypeError("Secret key must be provided.");
let tentativeValue = input.slice(0, input.lastIndexOf("."));
return await signCookie(tentativeValue, secret) === input ? tentativeValue : !1;
}, traceBackMacro = (extension, property, manage) => {
if (!(!extension || typeof extension != "object" || !property))
for (let [key, value] of Object.entries(property)) {
if (primitiveHookMap[key] || !(key in extension)) continue;
let v = extension[key];
if (typeof v == "function") {
let hook = v(value);
if (typeof hook == "object")
for (let [k, v2] of Object.entries(hook))
manage(k)({
fn: v2
});
}
delete property[key];
}
}, createMacroManager = ({
globalHook,
localHook
}) => (stackName) => (type, fn) => {
if (typeof type == "function" && (type = {
fn: type
}), stackName === "resolve" && (type = {
...type,
subType: "resolve"
}), localHook[stackName] || (localHook[stackName] = []), typeof localHook[stackName] == "function" && (localHook[stackName] = [localHook[stackName]]), Array.isArray(localHook[stackName]) || (localHook[stackName] = [localHook[stackName]]), "fn" in type || Array.isArray(type)) {
Array.isArray(type) ? localHook[stackName] = localHook[stackName].concat(type) : localHook[stackName].push(type);
return;
}
let { insert = "after", stack = "local" } = type;
typeof fn == "function" && (fn = { fn }), stack === "global" ? Array.isArray(fn) ? insert === "before" ? globalHook[stackName] = fn.concat(
globalHook[stackName]
) : globalHook[stackName] = globalHook[stackName].concat(fn) : insert === "before" ? globalHook[stackName].unshift(fn) : globalHook[stackName].push(fn) : Array.isArray(fn) ? insert === "before" ? localHook[stackName] = fn.concat(localHook[stackName]) : localHook[stackName] = localHook[stackName].concat(fn) : insert === "before" ? localHook[stackName].unshift(fn) : localHook[stackName].push(fn);
}, parseNumericString = (message) => {
if (typeof message == "number") return message;
if (message.length < 16) {
if (message.trim().length === 0) return null;
let length = Number(message);
return Number.isNaN(length) ? null : length;
}
if (message.length === 16) {
if (message.trim().length === 0) return null;
let number = Number(message);
return Number.isNaN(number) || number.toString() !== message ? null : number;
}
return null;
}, isNumericString = (message) => parseNumericString(message) !== null, PromiseGroup = class {
constructor(onError = console.error, onFinally = () => {
}) {
this.onError = onError;
this.onFinally = onFinally;
this.root = null;
this.promises = [];
}
/**
* The number of promises still being awaited.
*/
get size() {
return this.promises.length;
}
/**
* Add a promise to the group.
* @returns The promise that was added.
*/
add(promise) {
return this.promises.push(promise), this.root ||= this.drain(), this.promises.length === 1 && this.then(this.onFinally), promise;
}
async drain() {
for (; this.promises.length > 0; ) {
try {
await this.promises[0];
} catch (error2) {
this.onError(error2);
}
this.promises.shift();
}
this.root = null;
}
// Allow the group to be awaited.
then(onfulfilled, onrejected) {
return (this.root ?? Promise.resolve()).then(onfulfilled, onrejected);
}
}, fnToContainer = (fn, subType) => {
if (!fn) return fn;
if (!Array.isArray(fn)) {
if (typeof fn == "function" || typeof fn == "string")
return subType ? { fn, subType } : { fn };
if ("fn" in fn) return fn;
}
let fns = [];
for (let x of fn)
typeof x == "function" || typeof x == "string" ? fns.push(subType ? { fn: x, subType } : { fn: x }) : "fn" in x && fns.push(x);
return fns;
}, localHookToLifeCycleStore = (a) => (a.start && (a.start = fnToContainer(a.start)), a.request && (a.request = fnToContainer(a.request)), a.parse && (a.parse = fnToContainer(a.parse)), a.transform && (a.transform = fnToContainer(a.transform)), a.beforeHandle && (a.beforeHandle = fnToContainer(a.beforeHandle)), a.afterHandle && (a.afterHandle = fnToContainer(a.afterHandle)), a.mapResponse && (a.mapResponse = fnToContainer(a.mapResponse)), a.afterResponse && (a.afterResponse = fnToContainer(a.afterResponse)), a.trace && (a.trace = fnToContainer(a.trace)), a.error && (a.error = fnToContainer(a.error)), a.stop && (a.stop = fnToContainer(a.stop)), a), lifeCycleToFn = (a) => {
let lifecycle = /* @__PURE__ */ Object.create(null);
return a.start?.map && (lifecycle.start = a.start.map((x) => x.fn)), a.request?.map && (lifecycle.request = a.request.map((x) => x.fn)), a.parse?.map && (lifecycle.parse = a.parse.map((x) => x.fn)), a.transform?.map && (lifecycle.transform = a.transform.map((x) => x.fn)), a.beforeHandle?.map && (lifecycle.beforeHandle = a.beforeHandle.map((x) => x.fn)), a.afterHandle?.map && (lifecycle.afterHandle = a.afterHandle.map((x) => x.fn)), a.mapResponse?.map && (lifecycle.mapResponse = a.mapResponse.map((x) => x.fn)), a.afterResponse?.map && (lifecycle.afterResponse = a.afterResponse.map((x) => x.fn)), a.error?.map && (lifecycle.error = a.error.map((x) => x.fn)), a.stop?.map && (lifecycle.stop = a.stop.map((x) => x.fn)), a.trace?.map ? lifecycle.trace = a.trace.map((x) => x.fn) : lifecycle.trace = [], lifecycle;
}, cloneInference = (inference) => ({
body: inference.body,
cookie: inference.cookie,
headers: inference.headers,
query: inference.query,
set: inference.set,
server: inference.server,
path: inference.path,
route: inference.route,
url: inference.url
}), redirect = (url, status2 = 302) => Response.redirect(url, status2), ELYSIA_FORM_DATA = Symbol("ElysiaFormData"), ELYSIA_REQUEST_ID = Symbol("ElysiaRequestId"), form = (items) => {
let formData = new FormData();
if (formData[ELYSIA_FORM_DATA] = {}, items)
for (let [key, value] of Object.entries(items)) {
if (Array.isArray(value)) {
formData[ELYSIA_FORM_DATA][key] = [];
for (let v of value)
value instanceof File ? formData.append(key, value, value.name) : value instanceof ElysiaFile ? formData.append(key, value.value, value.value?.name) : formData.append(key, value), formData[ELYSIA_FORM_DATA][key].push(value);
continue;
}
value instanceof File ? formData.append(key, value, value.name) : value instanceof ElysiaFile ? formData.append(key, value.value, value.value?.name) : formData.append(key, value), formData[ELYSIA_FORM_DATA][key] = value;
}
return formData;
}, randomId = () => {
let uuid = crypto.randomUUID();
return uuid.slice(0, 8) + uuid.slice(24, 32);
}, deduplicateChecksum = (array) => {
if (!array.length) return [];
let hashes = [];
for (let i = 0; i < array.length; i++) {
let item = array[i];
item.checksum && (hashes.includes(item.checksum) && (array.splice(i, 1), i--), hashes.push(item.checksum));
}
return array;
}, promoteEvent = (events, as = "scoped") => {
if (events) {
if (as === "scoped") {
for (let event of events)
"scope" in event && event.scope === "local" && (event.scope = "scoped");
return;
}
for (let event of events) "scope" in event && (event.scope = "global");
}
}, getLoosePath = (path) => path.charCodeAt(path.length - 1) === 47 ? path.slice(0, path.length - 1) : path + "/", isNotEmpty = (obj) => {
if (!obj) return !1;
for (let _ in obj) return !0;
return !1;
}, encodePath = (path, { dynamic = !1 } = {}) => {
let encoded = encodeURIComponent(path).replace(/%2F/g, "/");
return dynamic && (encoded = encoded.replace(/%3A/g, ":").replace(/%3F/g, "?")), encoded;
}, supportPerMethodInlineHandler = (() => {
if (typeof Bun > "u") return !0;
let semver = Bun.version.split(".");
return !(+semver[0] < 1 || +semver[1] < 2 || +semver[2] < 14);
})(), sse = (payload) => (typeof payload == "string" && (payload = {
data: payload
}), payload.id === void 0 && (payload.id = randomId()), payload.toStream = () => {
let payloadString = "";
return payload.id !== void 0 && payload.id !== null && (payloadString += `id: ${payload.id}
`), payload.event && (payloadString += `event: ${payload.event}
`), payload.retry !== void 0 && (payloadString += `retry: ${payload.retry}
`), payload.data === null ? payloadString += `data: null
` : typeof payload.data == "string" ? payloadString += `data: ${payload.data}
` : typeof payload.data == "object" && (payloadString += `data: ${JSON.stringify(payload.data)}
`), payloadString && (payloadString += `
`), payloadString;
}, payload);
// src/error.ts
var env = typeof Bun < "u" ? Bun.env : typeof process < "u" ? process?.env : void 0, ERROR_CODE = Symbol("ElysiaErrorCode"), isProduction = (env?.NODE_ENV ?? env?.ENV) === "production", emptyHttpStatus = {
101: void 0,
204: void 0,
205: void 0,
304: void 0,
307: void 0,
308: void 0
}, ElysiaCustomStatusResponse = class {
constructor(code, response) {
let res = response ?? (code in InvertedStatusMap ? (
// @ts-expect-error Always correct
InvertedStatusMap[code]
) : code);
this.code = StatusMap[code] ?? code, code in emptyHttpStatus ? this.response = void 0 : this.response = res;
}
}, status = (code, response) => new ElysiaCustomStatusResponse(code, response), error = status, InternalServerError = class extends Error {
constructor(message) {
super(message ?? "INTERNAL_SERVER_ERROR");
this.code = "INTERNAL_SERVER_ERROR";
this.status = 500;
}
}, NotFoundError = class extends Error {
constructor(message) {
super(message ?? "NOT_FOUND");
this.code = "NOT_FOUND";
this.status = 404;
}
}, ParseError = class extends Error {
constructor(cause) {
super("Bad Request", {
cause
});
this.code = "PARSE";
this.status = 400;
}
}, InvalidCookieSignature = class extends Error {
constructor(key, message) {
super(message ?? `"${key}" has invalid cookie signature`);
this.key = key;
this.code = "INVALID_COOKIE_SIGNATURE";
this.status = 400;
}
}, mapValueError = (error2) => {
if (!error2)
return {
summary: void 0
};
let { message, path, value, type } = error2, property = path.slice(1).replaceAll("/", "."), isRoot = path === "";
switch (type) {
case 42:
return {
...error2,
summary: isRoot ? "Value should not be provided" : `Property '${property}' should not be provided`
};
case 45:
return {
...error2,
summary: isRoot ? "Value is missing" : `Property '${property}' is missing`
};
case 50:
let quoteIndex = message.indexOf("'"), format = message.slice(
quoteIndex + 1,
message.indexOf("'", quoteIndex + 1)
);
return {
...error2,
summary: isRoot ? "Value should be an email" : `Property '${property}' should be ${format}`
};
case 54:
return {
...error2,
summary: `${message.slice(0, 9).trim()} property '${property}' to be ${message.slice(8).trim()} but found: ${value}`
};
case 62:
let union = error2.schema.anyOf.map((x) => `'${x?.format ?? x.type}'`).join(", ");
return {
...error2,
summary: isRoot ? `Value should be one of ${union}` : `Property '${property}' should be one of: ${union}`
};
default:
return { summary: message, ...error2 };
}
}, InvalidFileType = class _InvalidFileType extends Error {
constructor(property, expected, message = `"${property}" has invalid file type`) {
super(message);
this.property = property;
this.expected = expected;
this.message = message;
this.code = "INVALID_FILE_TYPE";
this.status = 422;
Object.setPrototypeOf(this, _InvalidFileType.prototype);
}
toResponse(headers) {
return isProduction ? new Response(
JSON.stringify({
type: "validation",
on: "body"
}),
{
status: 422,
headers: {
...headers,
"content-type": "application/json"
}
}
) : new Response(
JSON.stringify({
type: "validation",
on: "body",
summary: "Invalid file type",
message: this.message,
property: this.property,
expected: this.expected
}),
{
status: 422,
headers: {
...headers,
"content-type": "application/json"
}
}
);
}
}, ValidationError = class _ValidationError extends Error {
constructor(type, validator, value, errors) {
value && typeof value == "object" && value instanceof ElysiaCustomStatusResponse && (value = value.response);
let error2 = errors?.First() || (isProduction ? void 0 : "Errors" in validator ? validator.Errors(value).First() : Value.Errors(validator, value).First()), customError = error2?.schema?.message || error2?.schema?.error !== void 0 ? typeof error2.schema.error == "function" ? error2.schema.error({
type,
validator,
value,
get errors() {
return [...validator.Errors(value)].map(
mapValueError
);
}
}) : error2.schema.error : void 0, accessor = error2?.path || "root", message = "";
if (customError !== void 0)
message = typeof customError == "object" ? JSON.stringify(customError) : customError + "";
else if (isProduction)
message = JSON.stringify({
type: "validation",
on: type,
summary: mapValueError(error2).summary,
message: error2?.message,
found: value
});
else {
let schema = validator?.schema ?? validator, errors2 = "Errors" in validator ? [...validator.Errors(value)].map(mapValueError) : [...Value.Errors(validator, value)].map(mapValueError), expected;
try {
expected = Value.Create(schema);
} catch (error3) {
expected = {
type: "Could not create expected value",
// @ts-expect-error
message: error3?.message,
error: error3
};
}
message = JSON.stringify(
{
type: "validation",
on: type,
summary: mapValueError(error2).summary,
property: accessor,
message: error2?.message,
expected,
found: value,
errors: errors2
},
null,
2
);
}
super(message);
this.type = type;
this.validator = validator;
this.value = value;
this.code = "VALIDATION";
this.status = 422;
Object.setPrototypeOf(this, _ValidationError.prototype);
}
get all() {
return "Errors" in this.validator ? [...this.validator.Errors(this.value)].map(mapValueError) : (
// @ts-ignore
[...Value.Errors(this.validator, this.value)].map(mapValueError)
);
}
static simplifyModel(validator) {
let model = "schema" in validator ? validator.schema : validator;
try {
return Value.Create(model);
} catch {
return model;
}
}
get model() {
return _ValidationError.simplifyModel(this.validator);
}
toResponse(headers) {
return new Response(this.message, {
status: 400,
headers: {
...headers,
"content-type": "application/json"
}
});
}
};
// src/type-system/utils.ts
var tryParse = (v, schema) => {
try {
return JSON.parse(v);
} catch {
throw new ValidationError("property", schema, v);
}
};
function createType(kind, func) {
return TypeRegistry.Has(kind) || TypeRegistry.Set(kind, func), (options = {}) => Unsafe({ ...options, [Kind]: kind });
}
var compile = (schema) => {
try {
let compiler = TypeCompiler.Compile(schema);
return compiler.Create = () => Value2.Create(schema), compiler.Error = (v) => new ValidationError("property", schema, v, compiler.Errors(v)), compiler;
} catch {
return {
Check: (v) => Value2.Check(schema, v),
CheckThrow: (v) => {
if (!Value2.Check(schema, v))
throw new ValidationError(
"property",
schema,
v,
Value2.Errors(schema, v)
);
},
Decode: (v) => Value2.Decode(schema, v),
Create: () => Value2.Create(schema),
Error: (v) => new ValidationError(
"property",
schema,
v,
Value2.Errors(schema, v)
)
};
}
}, parseFileUnit = (size) => {
if (typeof size == "string")
switch (size.slice(-1)) {
case "k":
return +size.slice(0, size.length - 1) * 1024;
case "m":
return +size.slice(0, size.length -