1951 lines
70 KiB
JavaScript
1951 lines
70 KiB
JavaScript
"use strict";
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: !0 });
|
|
}, __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from == "object" || typeof from == "function")
|
|
for (let key of __getOwnPropNames(from))
|
|
!__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
// file that has been converted to a CommonJS file using a Babel-
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
|
|
mod
|
|
)), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
|
|
var index_exports = {};
|
|
__export(index_exports, {
|
|
Cookie: () => import_cookies.Cookie,
|
|
ELYSIA_FORM_DATA: () => import_utils4.ELYSIA_FORM_DATA,
|
|
ELYSIA_REQUEST_ID: () => import_utils4.ELYSIA_REQUEST_ID,
|
|
ELYSIA_TRACE: () => import_trace2.ELYSIA_TRACE,
|
|
ERROR_CODE: () => import_error2.ERROR_CODE,
|
|
Elysia: () => Elysia,
|
|
ElysiaCustomStatusResponse: () => import_error2.ElysiaCustomStatusResponse,
|
|
ElysiaFile: () => import_file.ElysiaFile,
|
|
ElysiaStatus: () => import_error2.ElysiaStatus,
|
|
InternalServerError: () => import_error2.InternalServerError,
|
|
InvalidCookieSignature: () => import_error2.InvalidCookieSignature,
|
|
InvalidFileType: () => import_error2.InvalidFileType,
|
|
InvertedStatusMap: () => import_utils4.InvertedStatusMap,
|
|
NotFoundError: () => import_error2.NotFoundError,
|
|
ParseError: () => import_error2.ParseError,
|
|
StatusMap: () => import_utils4.StatusMap,
|
|
TypeSystemPolicy: () => import_system.TypeSystemPolicy,
|
|
ValidationError: () => import_error2.ValidationError,
|
|
checksum: () => import_utils4.checksum,
|
|
cloneInference: () => import_utils4.cloneInference,
|
|
deduplicateChecksum: () => import_utils4.deduplicateChecksum,
|
|
default: () => Elysia,
|
|
env: () => import_env2.env,
|
|
file: () => import_file.file,
|
|
fileType: () => import_utils3.fileType,
|
|
form: () => import_utils4.form,
|
|
getResponseSchemaValidator: () => import_schema2.getResponseSchemaValidator,
|
|
getSchemaValidator: () => import_schema2.getSchemaValidator,
|
|
mapValueError: () => import_error2.mapValueError,
|
|
mergeHook: () => import_utils4.mergeHook,
|
|
mergeObjectArray: () => import_utils4.mergeObjectArray,
|
|
redirect: () => import_utils4.redirect,
|
|
replaceSchemaType: () => import_replace_schema2.replaceSchemaTypeFromManyOptions,
|
|
replaceUrlPath: () => import_utils4.replaceUrlPath,
|
|
serializeCookie: () => import_cookies.serializeCookie,
|
|
sse: () => import_utils4.sse,
|
|
status: () => import_error2.status,
|
|
t: () => import_type_system2.t,
|
|
validationDetail: () => import_utils3.validationDetail
|
|
});
|
|
module.exports = __toCommonJS(index_exports);
|
|
var import_memoirist = require("memoirist"), import_typebox = require("@sinclair/typebox"), import_fast_decode_uri_component = __toESM(require("fast-decode-uri-component")), import_type_system = require('./type-system/index.js'), import_sucrose = require('./sucrose.js'), import_bun = require('./adapter/bun/index.js'), import_web_standard = require('./adapter/web-standard/index.js'), import_env = require('./universal/env.js'), import_utils = require('./utils.js'), import_schema = require('./schema.js'), import_compose = require('./compose.js'), import_trace = require('./trace.js'), import_utils2 = require('./utils.js'), import_dynamic_handle = require('./dynamic-handle.js'), import_error = require('./error.js'), import_replace_schema = require('./replace-schema.js'), import_type_system2 = require('./type-system/index.js'), import_utils3 = require('./type-system/utils.js'), import_cookies = require('./cookies.js'), import_trace2 = require('./trace.js'), import_schema2 = require('./schema.js'), import_replace_schema2 = require('./replace-schema.js'), import_utils4 = require('./utils.js'), import_error2 = require('./error.js'), import_env2 = require('./universal/env.js'), import_file = require('./universal/file.js'), import_system = require("@sinclair/typebox/system"), _a;
|
|
_a = Symbol.dispose;
|
|
const _Elysia = class _Elysia {
|
|
constructor(config = {}) {
|
|
this.server = null;
|
|
this.dependencies = {};
|
|
this["~Prefix"] = "";
|
|
this["~Singleton"] = null;
|
|
this["~Definitions"] = null;
|
|
this["~Metadata"] = null;
|
|
this["~Ephemeral"] = null;
|
|
this["~Volatile"] = null;
|
|
this["~Routes"] = null;
|
|
this.singleton = {
|
|
decorator: {},
|
|
store: {},
|
|
derive: {},
|
|
resolve: {}
|
|
};
|
|
this.definitions = {
|
|
typebox: import_type_system.t.Module({}),
|
|
type: {},
|
|
error: {}
|
|
};
|
|
this.extender = {
|
|
macro: {},
|
|
higherOrderFunctions: []
|
|
};
|
|
this.validator = {
|
|
global: null,
|
|
scoped: null,
|
|
local: null,
|
|
getCandidate() {
|
|
return !this.global && !this.scoped && !this.local ? {
|
|
body: void 0,
|
|
headers: void 0,
|
|
params: void 0,
|
|
query: void 0,
|
|
cookie: void 0,
|
|
response: void 0
|
|
} : (0, import_utils.mergeSchemaValidator)(
|
|
(0, import_utils.mergeSchemaValidator)(this.global, this.scoped),
|
|
this.local
|
|
);
|
|
}
|
|
};
|
|
this.standaloneValidator = {
|
|
global: null,
|
|
scoped: null,
|
|
local: null
|
|
};
|
|
this.event = {};
|
|
this.router = {
|
|
"~http": void 0,
|
|
get http() {
|
|
return this["~http"] || (this["~http"] = new import_memoirist.Memoirist({
|
|
lazy: !0,
|
|
onParam: import_fast_decode_uri_component.default
|
|
})), this["~http"];
|
|
},
|
|
"~dynamic": void 0,
|
|
// Use in non-AOT mode
|
|
get dynamic() {
|
|
return this["~dynamic"] || (this["~dynamic"] = new import_memoirist.Memoirist({
|
|
onParam: import_fast_decode_uri_component.default
|
|
})), this["~dynamic"];
|
|
},
|
|
// Static Router
|
|
static: {},
|
|
// Native Static Response
|
|
response: {},
|
|
history: []
|
|
};
|
|
this.routeTree = {};
|
|
this.inference = {
|
|
body: !1,
|
|
cookie: !1,
|
|
headers: !1,
|
|
query: !1,
|
|
set: !1,
|
|
server: !1,
|
|
path: !1,
|
|
route: !1,
|
|
url: !1
|
|
};
|
|
this["~parser"] = {};
|
|
this.handle = async (request) => this.fetch(request);
|
|
this.handleError = async (context, error) => (this.handleError = this.config.aot ? (0, import_compose.composeErrorHandler)(this) : (0, import_dynamic_handle.createDynamicErrorHandler)(this))(context, error);
|
|
/**
|
|
* ### listen
|
|
* Assign current instance to port and start serving
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .get("/", () => 'hi')
|
|
* .listen(3000)
|
|
* ```
|
|
*/
|
|
this.listen = (options, callback) => (this["~adapter"].listen(this)(options, callback), this);
|
|
/**
|
|
* ### stop
|
|
* Stop server from serving
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* const app = new Elysia()
|
|
* .get("/", () => 'hi')
|
|
* .listen(3000)
|
|
*
|
|
* // Sometime later
|
|
* app.stop()
|
|
* ```
|
|
*
|
|
* @example
|
|
* ```typescript
|
|
* const app = new Elysia()
|
|
* .get("/", () => 'hi')
|
|
* .listen(3000)
|
|
*
|
|
* app.stop(true) // Abruptly any requests inflight
|
|
* ```
|
|
*/
|
|
this.stop = async (closeActiveConnections) => (await this["~adapter"].stop?.(this, closeActiveConnections), this);
|
|
this[_a] = () => {
|
|
this.server && this.stop();
|
|
};
|
|
config.tags && (config.detail ? config.detail.tags = config.tags : config.detail = {
|
|
tags: config.tags
|
|
}), this.config = {
|
|
aot: import_env.env.ELYSIA_AOT !== "false",
|
|
nativeStaticResponse: !0,
|
|
encodeSchema: !0,
|
|
normalize: !0,
|
|
...config,
|
|
prefix: config.prefix ? config.prefix.charCodeAt(0) === 47 ? config.prefix : `/${config.prefix}` : void 0,
|
|
cookie: {
|
|
path: "/",
|
|
...config?.cookie
|
|
},
|
|
experimental: config?.experimental ?? {},
|
|
seed: config?.seed === void 0 ? "" : config?.seed
|
|
}, this["~adapter"] = config.adapter ?? (typeof Bun < "u" ? import_bun.BunAdapter : import_web_standard.WebStandardAdapter), config?.analytic && (config?.name || config?.seed !== void 0) && (this.telemetry = {
|
|
stack: new Error().stack
|
|
});
|
|
}
|
|
get store() {
|
|
return this.singleton.store;
|
|
}
|
|
get decorator() {
|
|
return this.singleton.decorator;
|
|
}
|
|
get routes() {
|
|
return this.router.history;
|
|
}
|
|
getGlobalRoutes() {
|
|
return this.router.history;
|
|
}
|
|
getGlobalDefinitions() {
|
|
return this.definitions;
|
|
}
|
|
getServer() {
|
|
return this.server;
|
|
}
|
|
getParent() {
|
|
return null;
|
|
}
|
|
get promisedModules() {
|
|
return this._promisedModules || (this._promisedModules = new import_utils.PromiseGroup(console.error, () => {
|
|
})), this._promisedModules;
|
|
}
|
|
env(model, _env = import_env.env) {
|
|
if ((0, import_schema.getSchemaValidator)(model, {
|
|
modules: this.definitions.typebox,
|
|
dynamic: !0,
|
|
additionalProperties: !0,
|
|
coerce: !0,
|
|
sanitize: () => this.config.sanitize
|
|
}).Check(_env) === !1) {
|
|
const error = new import_error.ValidationError("env", model, _env);
|
|
throw new Error(error.all.map((x) => x.summary).join(`
|
|
`));
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* @private DO_NOT_USE_OR_YOU_WILL_BE_FIRED
|
|
* @version 1.1.0
|
|
*
|
|
* ! Do not use unless you know exactly what you are doing
|
|
* ? Add Higher order function to Elysia.fetch
|
|
*/
|
|
wrap(fn) {
|
|
return this.extender.higherOrderFunctions.push({
|
|
checksum: (0, import_utils2.checksum)(
|
|
JSON.stringify({
|
|
name: this.config.name,
|
|
seed: this.config.seed,
|
|
content: fn.toString()
|
|
})
|
|
),
|
|
fn
|
|
}), this;
|
|
}
|
|
get models() {
|
|
const models = {};
|
|
for (const name of Object.keys(this.definitions.type))
|
|
models[name] = (0, import_schema.getSchemaValidator)(
|
|
this.definitions.typebox.Import(name),
|
|
{
|
|
models: this.definitions.type
|
|
}
|
|
);
|
|
return models.modules = this.definitions.typebox, models;
|
|
}
|
|
add(method, path, handle, localHook, options) {
|
|
const skipPrefix = options?.skipPrefix ?? !1, allowMeta = options?.allowMeta ?? !1;
|
|
localHook ??= {}, this.applyMacro(localHook);
|
|
let standaloneValidators = [];
|
|
if (localHook.standaloneValidator && (standaloneValidators = standaloneValidators.concat(
|
|
localHook.standaloneValidator
|
|
)), this.standaloneValidator.local && (standaloneValidators = standaloneValidators.concat(
|
|
this.standaloneValidator.local
|
|
)), this.standaloneValidator.scoped && (standaloneValidators = standaloneValidators.concat(
|
|
this.standaloneValidator.scoped
|
|
)), this.standaloneValidator.global && (standaloneValidators = standaloneValidators.concat(
|
|
this.standaloneValidator.global
|
|
)), path !== "" && path.charCodeAt(0) !== 47 && (path = "/" + path), this.config.prefix && !skipPrefix && (path = this.config.prefix + path), localHook?.type)
|
|
switch (localHook.type) {
|
|
case "text":
|
|
localHook.type = "text/plain";
|
|
break;
|
|
case "json":
|
|
localHook.type = "application/json";
|
|
break;
|
|
case "formdata":
|
|
localHook.type = "multipart/form-data";
|
|
break;
|
|
case "urlencoded":
|
|
localHook.type = "application/x-www-form-urlencoded";
|
|
break;
|
|
case "arrayBuffer":
|
|
localHook.type = "application/octet-stream";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
const instanceValidator = this.validator.getCandidate(), cloned = {
|
|
body: localHook?.body ?? instanceValidator?.body,
|
|
headers: localHook?.headers ?? instanceValidator?.headers,
|
|
params: localHook?.params ?? instanceValidator?.params,
|
|
query: localHook?.query ?? instanceValidator?.query,
|
|
cookie: localHook?.cookie ?? instanceValidator?.cookie,
|
|
response: localHook?.response ?? instanceValidator?.response
|
|
}, shouldPrecompile = this.config.precompile === !0 || typeof this.config.precompile == "object" && this.config.precompile.compose === !0, createValidator = () => {
|
|
const models = this.definitions.type, dynamic = !this.config.aot, normalize = this.config.normalize, modules = this.definitions.typebox, sanitize = () => this.config.sanitize, cookieValidator = () => {
|
|
if (cloned.cookie || standaloneValidators.find((x) => x.cookie))
|
|
return (0, import_schema.getCookieValidator)({
|
|
modules,
|
|
validator: cloned.cookie,
|
|
defaultConfig: this.config.cookie,
|
|
normalize,
|
|
config: cloned.cookie?.config ?? {},
|
|
dynamic,
|
|
models,
|
|
validators: standaloneValidators.map((x) => x.cookie),
|
|
sanitize
|
|
});
|
|
};
|
|
return shouldPrecompile ? {
|
|
body: (0, import_schema.getSchemaValidator)(cloned.body, {
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
additionalCoerce: (() => {
|
|
const resolved = (0, import_schema.resolveSchema)(
|
|
cloned.body,
|
|
models,
|
|
modules
|
|
);
|
|
return resolved && import_typebox.Kind in resolved && ((0, import_schema.hasType)("File", resolved) || (0, import_schema.hasType)("Files", resolved)) ? (0, import_replace_schema.coerceFormData)() : (0, import_replace_schema.coercePrimitiveRoot)();
|
|
})(),
|
|
validators: standaloneValidators.map((x) => x.body),
|
|
sanitize
|
|
}),
|
|
headers: (0, import_schema.getSchemaValidator)(cloned.headers, {
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
additionalProperties: !0,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.stringToStructureCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.headers
|
|
),
|
|
sanitize
|
|
}),
|
|
params: (0, import_schema.getSchemaValidator)(cloned.params, {
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.stringToStructureCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.params
|
|
),
|
|
sanitize
|
|
}),
|
|
query: (0, import_schema.getSchemaValidator)(cloned.query, {
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.queryCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.query
|
|
),
|
|
sanitize
|
|
}),
|
|
cookie: cookieValidator(),
|
|
response: (0, import_schema.getResponseSchemaValidator)(cloned.response, {
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
validators: standaloneValidators.map(
|
|
(x) => x.response
|
|
),
|
|
sanitize
|
|
})
|
|
} : {
|
|
createBody() {
|
|
return this.body ? this.body : this.body = (0, import_schema.getSchemaValidator)(
|
|
cloned.body,
|
|
{
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
additionalCoerce: (() => {
|
|
const resolved = (0, import_schema.resolveSchema)(
|
|
cloned.body,
|
|
models,
|
|
modules
|
|
);
|
|
return resolved && import_typebox.Kind in resolved && ((0, import_schema.hasType)("File", resolved) || (0, import_schema.hasType)("Files", resolved)) ? (0, import_replace_schema.coerceFormData)() : (0, import_replace_schema.coercePrimitiveRoot)();
|
|
})(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.body
|
|
),
|
|
sanitize
|
|
}
|
|
);
|
|
},
|
|
createHeaders() {
|
|
return this.headers ? this.headers : this.headers = (0, import_schema.getSchemaValidator)(
|
|
cloned.headers,
|
|
{
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
additionalProperties: !normalize,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.stringToStructureCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.headers
|
|
),
|
|
sanitize
|
|
}
|
|
);
|
|
},
|
|
createParams() {
|
|
return this.params ? this.params : this.params = (0, import_schema.getSchemaValidator)(
|
|
cloned.params,
|
|
{
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.stringToStructureCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.params
|
|
),
|
|
sanitize
|
|
}
|
|
);
|
|
},
|
|
createQuery() {
|
|
return this.query ? this.query : this.query = (0, import_schema.getSchemaValidator)(
|
|
cloned.query,
|
|
{
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
coerce: !0,
|
|
additionalCoerce: (0, import_replace_schema.queryCoercions)(),
|
|
validators: standaloneValidators.map(
|
|
(x) => x.query
|
|
),
|
|
sanitize
|
|
}
|
|
);
|
|
},
|
|
createCookie() {
|
|
return this.cookie ? this.cookie : this.cookie = cookieValidator();
|
|
},
|
|
createResponse() {
|
|
return this.response ? this.response : this.response = (0, import_schema.getResponseSchemaValidator)(
|
|
cloned.response,
|
|
{
|
|
modules,
|
|
dynamic,
|
|
models,
|
|
normalize,
|
|
validators: standaloneValidators.map(
|
|
(x) => x.response
|
|
),
|
|
sanitize
|
|
}
|
|
);
|
|
}
|
|
};
|
|
};
|
|
(instanceValidator.body || instanceValidator.cookie || instanceValidator.headers || instanceValidator.params || instanceValidator.query || instanceValidator.response) && (localHook = (0, import_utils2.mergeHook)(localHook, instanceValidator)), localHook.tags && (localHook.detail ? localHook.detail.tags = localHook.tags : localHook.detail = {
|
|
tags: localHook.tags
|
|
}), (0, import_utils.isNotEmpty)(this.config.detail) && (localHook.detail = (0, import_utils.mergeDeep)(
|
|
Object.assign({}, this.config.detail),
|
|
localHook.detail
|
|
));
|
|
const hooks = (0, import_utils.isNotEmpty)(this.event) ? (0, import_utils2.mergeHook)(this.event, (0, import_utils.localHookToLifeCycleStore)(localHook)) : { ...(0, import_utils.lifeCycleToArray)((0, import_utils.localHookToLifeCycleStore)(localHook)) };
|
|
if (standaloneValidators.length && Object.assign(hooks, {
|
|
standaloneValidator: standaloneValidators
|
|
}), this.config.aot === !1) {
|
|
const validator = createValidator();
|
|
this.router.dynamic.add(method, path, {
|
|
validator,
|
|
hooks,
|
|
content: localHook?.type,
|
|
handle,
|
|
route: path
|
|
});
|
|
const encoded = (0, import_utils.encodePath)(path, { dynamic: !0 });
|
|
if (path !== encoded && this.router.dynamic.add(method, encoded, {
|
|
validator,
|
|
hooks,
|
|
content: localHook?.type,
|
|
handle,
|
|
route: path
|
|
}), !this.config.strictPath) {
|
|
const loosePath = (0, import_utils.getLoosePath)(path);
|
|
this.router.dynamic.add(method, loosePath, {
|
|
validator,
|
|
hooks,
|
|
content: localHook?.type,
|
|
handle,
|
|
route: path
|
|
});
|
|
const encoded2 = (0, import_utils.encodePath)(loosePath);
|
|
loosePath !== encoded2 && this.router.dynamic.add(method, loosePath, {
|
|
validator,
|
|
hooks,
|
|
content: localHook?.type,
|
|
handle,
|
|
route: path
|
|
});
|
|
}
|
|
this.router.history.push({
|
|
method,
|
|
path,
|
|
composed: null,
|
|
handler: handle,
|
|
compile: void 0,
|
|
hooks
|
|
});
|
|
return;
|
|
}
|
|
const adapter = this["~adapter"].handler, nativeStaticHandler = typeof handle != "function" ? () => {
|
|
const context = {
|
|
redirect: import_utils.redirect,
|
|
request: this["~adapter"].isWebStandard ? new Request(`http://ely.sia${path}`, {
|
|
method
|
|
}) : void 0,
|
|
server: null,
|
|
set: {
|
|
headers: Object.assign({}, this.setHeaders)
|
|
},
|
|
status: import_error.status,
|
|
store: this.store
|
|
};
|
|
try {
|
|
this.event.request?.map((x) => {
|
|
if (typeof x.fn == "function")
|
|
return x.fn(context);
|
|
if (typeof x == "function") return x(context);
|
|
});
|
|
} catch (error) {
|
|
let res;
|
|
context.error = error, this.event.error?.some((x) => {
|
|
if (typeof x.fn == "function")
|
|
return res = x.fn(context);
|
|
if (typeof x == "function")
|
|
return res = x(context);
|
|
}), res !== void 0 && (handle = res);
|
|
}
|
|
const fn = adapter.createNativeStaticHandler?.(
|
|
handle,
|
|
hooks,
|
|
context.set
|
|
);
|
|
return fn instanceof Promise ? fn.then((fn2) => {
|
|
if (fn2) return fn2;
|
|
}) : fn?.();
|
|
} : void 0, useNativeStaticResponse = this.config.nativeStaticResponse === !0, addResponsePath = (path2) => {
|
|
!useNativeStaticResponse || !nativeStaticHandler || (import_utils.supportPerMethodInlineHandler ? this.router.response[path2] ? this.router.response[path2][method] = nativeStaticHandler() : this.router.response[path2] = {
|
|
[method]: nativeStaticHandler()
|
|
} : this.router.response[path2] = nativeStaticHandler());
|
|
};
|
|
addResponsePath(path);
|
|
let _compiled;
|
|
const compile = () => {
|
|
if (_compiled) return _compiled;
|
|
const compiled = (0, import_compose.composeHandler)({
|
|
app: this,
|
|
path,
|
|
method,
|
|
hooks,
|
|
validator: createValidator(),
|
|
handler: typeof handle != "function" && typeof adapter.createStaticHandler != "function" ? () => handle : handle,
|
|
allowMeta,
|
|
inference: this.inference
|
|
});
|
|
return this.router.history[index] && (_compiled = this.router.history[index].composed = compiled), compiled;
|
|
};
|
|
let oldIndex;
|
|
if (`${method}_${path}` in this.routeTree)
|
|
for (let i = 0; i < this.router.history.length; i++) {
|
|
const route2 = this.router.history[i];
|
|
if (route2.path === path && route2.method === method) {
|
|
oldIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
else this.routeTree[`${method}_${path}`] = this.router.history.length;
|
|
const index = oldIndex ?? this.router.history.length, route = this.router.history, mainHandler = shouldPrecompile ? compile() : (ctx) => _compiled ? _compiled(ctx) : (route[index].composed = compile())(ctx);
|
|
oldIndex !== void 0 ? this.router.history[oldIndex] = Object.assign(
|
|
{
|
|
method,
|
|
path,
|
|
composed: mainHandler,
|
|
compile,
|
|
handler: handle,
|
|
hooks
|
|
},
|
|
standaloneValidators.length ? {
|
|
standaloneValidators
|
|
} : void 0,
|
|
localHook.webSocket ? { websocket: localHook.websocket } : void 0
|
|
) : this.router.history.push(
|
|
Object.assign(
|
|
{
|
|
method,
|
|
path,
|
|
composed: mainHandler,
|
|
compile,
|
|
handler: handle,
|
|
hooks
|
|
},
|
|
localHook.webSocket ? { websocket: localHook.websocket } : void 0
|
|
)
|
|
);
|
|
const handler = {
|
|
handler: shouldPrecompile ? route[index].composed : void 0,
|
|
compile() {
|
|
return this.handler = compile();
|
|
}
|
|
}, staticRouter = this.router.static, isStaticPath = path.indexOf(":") === -1 && path.indexOf("*") === -1;
|
|
if (method === "WS") {
|
|
if (isStaticPath) {
|
|
path in staticRouter ? staticRouter[path][method] = index : staticRouter[path] = {
|
|
[method]: index
|
|
};
|
|
return;
|
|
}
|
|
this.router.http.add("WS", path, handler), this.config.strictPath || this.router.http.add("WS", (0, import_utils.getLoosePath)(path), handler);
|
|
const encoded = (0, import_utils.encodePath)(path, { dynamic: !0 });
|
|
path !== encoded && this.router.http.add("WS", encoded, handler);
|
|
return;
|
|
}
|
|
if (isStaticPath)
|
|
path in staticRouter ? staticRouter[path][method] = index : staticRouter[path] = {
|
|
[method]: index
|
|
}, this.config.strictPath || addResponsePath((0, import_utils.getLoosePath)(path));
|
|
else {
|
|
if (this.router.http.add(method, path, handler), !this.config.strictPath) {
|
|
const loosePath = (0, import_utils.getLoosePath)(path);
|
|
addResponsePath(loosePath), this.router.http.add(method, loosePath, handler);
|
|
}
|
|
const encoded = (0, import_utils.encodePath)(path, { dynamic: !0 });
|
|
path !== encoded && (this.router.http.add(method, encoded, handler), addResponsePath(encoded));
|
|
}
|
|
}
|
|
headers(header) {
|
|
return header ? (this.setHeaders || (this.setHeaders = {}), this.setHeaders = (0, import_utils.mergeDeep)(this.setHeaders, header), this) : this;
|
|
}
|
|
/**
|
|
* ### start | Life cycle event
|
|
* Called after server is ready for serving
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .onStart(({ server }) => {
|
|
* console.log("Running at ${server?.url}:${server?.port}")
|
|
* })
|
|
* .listen(3000)
|
|
* ```
|
|
*/
|
|
onStart(handler) {
|
|
return this.on("start", handler), this;
|
|
}
|
|
onRequest(handler) {
|
|
return this.on("request", handler), this;
|
|
}
|
|
onParse(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"parse",
|
|
handler
|
|
) : typeof options == "string" ? this.on("parse", this["~parser"][options]) : this.on("parse", options);
|
|
}
|
|
/**
|
|
* ### parse | Life cycle event
|
|
* Callback function to handle body parsing
|
|
*
|
|
* If truthy value is returned, will be assigned to `context.body`
|
|
* Otherwise will skip the callback and look for the next one.
|
|
*
|
|
* Equivalent to Express's body parser
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .onParse((request, contentType) => {
|
|
* if(contentType === "application/json")
|
|
* return request.json()
|
|
* })
|
|
* ```
|
|
*/
|
|
parser(name, parser) {
|
|
return this["~parser"][name] = parser, this;
|
|
}
|
|
onTransform(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"transform",
|
|
handler
|
|
) : this.on("transform", options);
|
|
}
|
|
resolve(optionsOrResolve, resolve) {
|
|
resolve || (resolve = optionsOrResolve, optionsOrResolve = { as: "local" });
|
|
const hook = {
|
|
subType: "resolve",
|
|
fn: resolve
|
|
};
|
|
return this.onBeforeHandle(optionsOrResolve, hook);
|
|
}
|
|
mapResolve(optionsOrResolve, mapper) {
|
|
mapper || (mapper = optionsOrResolve, optionsOrResolve = { as: "local" });
|
|
const hook = {
|
|
subType: "mapResolve",
|
|
fn: mapper
|
|
};
|
|
return this.onBeforeHandle(optionsOrResolve, hook);
|
|
}
|
|
onBeforeHandle(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"beforeHandle",
|
|
handler
|
|
) : this.on("beforeHandle", options);
|
|
}
|
|
onAfterHandle(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"afterHandle",
|
|
handler
|
|
) : this.on("afterHandle", options);
|
|
}
|
|
mapResponse(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"mapResponse",
|
|
handler
|
|
) : this.on("mapResponse", options);
|
|
}
|
|
onAfterResponse(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"afterResponse",
|
|
handler
|
|
) : this.on("afterResponse", options);
|
|
}
|
|
/**
|
|
* ### After Handle | Life cycle event
|
|
* Intercept request **after** main handler is called.
|
|
*
|
|
* If truthy value is returned, will be assigned as `Response`
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .onAfterHandle((context, response) => {
|
|
* if(typeof response === "object")
|
|
* return JSON.stringify(response)
|
|
* })
|
|
* ```
|
|
*/
|
|
trace(options, handler) {
|
|
handler || (handler = options, options = { as: "local" }), Array.isArray(handler) || (handler = [handler]);
|
|
for (const fn of handler)
|
|
this.on(
|
|
options,
|
|
"trace",
|
|
(0, import_trace.createTracer)(fn)
|
|
);
|
|
return this;
|
|
}
|
|
error(name, error) {
|
|
switch (typeof name) {
|
|
case "string":
|
|
return error.prototype[import_error.ERROR_CODE] = name, this.definitions.error[name] = error, this;
|
|
case "function":
|
|
return this.definitions.error = name(this.definitions.error), this;
|
|
}
|
|
for (const [code, error2] of Object.entries(name))
|
|
error2.prototype[import_error.ERROR_CODE] = code, this.definitions.error[code] = error2;
|
|
return this;
|
|
}
|
|
/**
|
|
* ### Error | Life cycle event
|
|
* Called when error is thrown during processing request
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .onError(({ code }) => {
|
|
* if(code === "NOT_FOUND")
|
|
* return "Path not found :("
|
|
* })
|
|
* ```
|
|
*/
|
|
onError(options, handler) {
|
|
return handler ? this.on(
|
|
options,
|
|
"error",
|
|
handler
|
|
) : this.on("error", options);
|
|
}
|
|
/**
|
|
* ### stop | Life cycle event
|
|
* Called after server stop serving request
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .onStop((app) => {
|
|
* cleanup()
|
|
* })
|
|
* ```
|
|
*/
|
|
onStop(handler) {
|
|
return this.on("stop", handler), this;
|
|
}
|
|
on(optionsOrType, typeOrHandlers, handlers) {
|
|
let type;
|
|
switch (typeof optionsOrType) {
|
|
case "string":
|
|
type = optionsOrType, handlers = typeOrHandlers;
|
|
break;
|
|
case "object":
|
|
type = typeOrHandlers, !Array.isArray(typeOrHandlers) && typeof typeOrHandlers == "object" && (handlers = typeOrHandlers);
|
|
break;
|
|
}
|
|
Array.isArray(handlers) ? handlers = (0, import_utils.fnToContainer)(handlers) : typeof handlers == "function" ? handlers = [
|
|
{
|
|
fn: handlers
|
|
}
|
|
] : handlers = [handlers];
|
|
const handles = handlers;
|
|
for (const handle of handles)
|
|
handle.scope = typeof optionsOrType == "string" ? "local" : optionsOrType?.as ?? "local", (type === "resolve" || type === "derive") && (handle.subType = type);
|
|
type !== "trace" && (this.inference = (0, import_sucrose.sucrose)(
|
|
{
|
|
[type]: handles.map((x) => x.fn)
|
|
},
|
|
this.inference,
|
|
this.config.sucrose
|
|
));
|
|
for (const handle of handles) {
|
|
const fn = (0, import_utils2.asHookType)(handle, "global", { skipIfHasType: !0 });
|
|
switch ((this.config.name || this.config.seed) && (fn.checksum = (0, import_utils2.checksum)(
|
|
this.config.name + JSON.stringify(this.config.seed)
|
|
)), type) {
|
|
case "start":
|
|
this.event.start ??= [], this.event.start.push(fn);
|
|
break;
|
|
case "request":
|
|
this.event.request ??= [], this.event.request.push(fn);
|
|
break;
|
|
case "parse":
|
|
this.event.parse ??= [], this.event.parse.push(fn);
|
|
break;
|
|
case "transform":
|
|
this.event.transform ??= [], this.event.transform.push(fn);
|
|
break;
|
|
// @ts-expect-error
|
|
case "derive":
|
|
this.event.transform ??= [], this.event.transform.push(
|
|
(0, import_utils.fnToContainer)(fn, "derive")
|
|
);
|
|
break;
|
|
case "beforeHandle":
|
|
this.event.beforeHandle ??= [], this.event.beforeHandle.push(fn);
|
|
break;
|
|
// @ts-expect-error
|
|
// eslint-disable-next-line sonarjs/no-duplicated-branches
|
|
case "resolve":
|
|
this.event.beforeHandle ??= [], this.event.beforeHandle.push(
|
|
(0, import_utils.fnToContainer)(fn, "resolve")
|
|
);
|
|
break;
|
|
case "afterHandle":
|
|
this.event.afterHandle ??= [], this.event.afterHandle.push(fn);
|
|
break;
|
|
case "mapResponse":
|
|
this.event.mapResponse ??= [], this.event.mapResponse.push(fn);
|
|
break;
|
|
case "afterResponse":
|
|
this.event.afterResponse ??= [], this.event.afterResponse.push(fn);
|
|
break;
|
|
case "trace":
|
|
this.event.trace ??= [], this.event.trace.push(fn);
|
|
break;
|
|
case "error":
|
|
this.event.error ??= [], this.event.error.push(fn);
|
|
break;
|
|
case "stop":
|
|
this.event.stop ??= [], this.event.stop.push(fn);
|
|
break;
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
as(type) {
|
|
return (0, import_utils.promoteEvent)(this.event.parse, type), (0, import_utils.promoteEvent)(this.event.transform, type), (0, import_utils.promoteEvent)(this.event.beforeHandle, type), (0, import_utils.promoteEvent)(this.event.afterHandle, type), (0, import_utils.promoteEvent)(this.event.mapResponse, type), (0, import_utils.promoteEvent)(this.event.afterResponse, type), (0, import_utils.promoteEvent)(this.event.trace, type), (0, import_utils.promoteEvent)(this.event.error, type), type === "scoped" ? (this.validator.scoped = (0, import_utils.mergeSchemaValidator)(
|
|
this.validator.scoped,
|
|
this.validator.local
|
|
), this.validator.local = null, this.standaloneValidator.local !== null && (this.standaloneValidator.scoped ||= [], this.standaloneValidator.scoped.push(
|
|
...this.standaloneValidator.local
|
|
), this.standaloneValidator.local = null)) : type === "global" && (this.validator.global = (0, import_utils.mergeSchemaValidator)(
|
|
this.validator.global,
|
|
(0, import_utils.mergeSchemaValidator)(
|
|
this.validator.scoped,
|
|
this.validator.local
|
|
)
|
|
), this.validator.scoped = null, this.validator.local = null, this.standaloneValidator.local !== null && (this.standaloneValidator.scoped ||= [], this.standaloneValidator.scoped.push(
|
|
...this.standaloneValidator.local
|
|
), this.standaloneValidator.local = null), this.standaloneValidator.scoped !== null && (this.standaloneValidator.global ||= [], this.standaloneValidator.global.push(
|
|
...this.standaloneValidator.scoped
|
|
), this.standaloneValidator.scoped = null)), this;
|
|
}
|
|
/**
|
|
* ### group
|
|
* Encapsulate and group path with prefix
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .group('/v1', app => app
|
|
* .get('/', () => 'Hi')
|
|
* .get('/name', () => 'Elysia')
|
|
* })
|
|
* ```
|
|
*/
|
|
group(prefix, schemaOrRun, run) {
|
|
const instance = new _Elysia({
|
|
...this.config,
|
|
prefix: ""
|
|
});
|
|
instance.singleton = { ...this.singleton }, instance.definitions = { ...this.definitions }, instance.getServer = () => this.getServer(), instance.inference = (0, import_utils.cloneInference)(this.inference), instance.extender = { ...this.extender }, instance["~parser"] = this["~parser"], instance.standaloneValidator = {
|
|
local: [...this.standaloneValidator.local ?? []],
|
|
scoped: [...this.standaloneValidator.scoped ?? []],
|
|
global: [...this.standaloneValidator.global ?? []]
|
|
};
|
|
const isSchema = typeof schemaOrRun == "object", sandbox = (isSchema ? run : schemaOrRun)(instance);
|
|
return this.singleton = (0, import_utils.mergeDeep)(this.singleton, instance.singleton), this.definitions = (0, import_utils.mergeDeep)(this.definitions, instance.definitions), sandbox.event.request?.length && (this.event.request = [
|
|
...this.event.request || [],
|
|
...sandbox.event.request || []
|
|
]), sandbox.event.mapResponse?.length && (this.event.mapResponse = [
|
|
...this.event.mapResponse || [],
|
|
...sandbox.event.mapResponse || []
|
|
]), this.model(sandbox.definitions.type), Object.values(instance.router.history).forEach(
|
|
({ method, path, handler, hooks }) => {
|
|
if (path = (isSchema ? "" : this.config.prefix ?? "") + prefix + path, isSchema) {
|
|
const {
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response,
|
|
...hook
|
|
} = schemaOrRun, localHook = hooks;
|
|
this.applyMacro(hook);
|
|
const hasStandaloneSchema = body || headers || query || params || cookie || response;
|
|
this.add(
|
|
method,
|
|
path,
|
|
handler,
|
|
(0, import_utils2.mergeHook)(hook, {
|
|
...localHook || {},
|
|
error: localHook.error ? Array.isArray(localHook.error) ? [
|
|
...localHook.error ?? [],
|
|
...sandbox.event.error ?? []
|
|
] : [
|
|
localHook.error,
|
|
...sandbox.event.error ?? []
|
|
] : sandbox.event.error,
|
|
// Merge macro's standaloneValidator with local and group schema
|
|
standaloneValidator: hook.standaloneValidator || localHook.standaloneValidator || hasStandaloneSchema ? [
|
|
...hook.standaloneValidator ?? [],
|
|
...localHook.standaloneValidator ?? [],
|
|
...hasStandaloneSchema ? [
|
|
{
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response
|
|
}
|
|
] : []
|
|
] : void 0
|
|
}),
|
|
void 0
|
|
);
|
|
} else
|
|
this.add(
|
|
method,
|
|
path,
|
|
handler,
|
|
(0, import_utils2.mergeHook)(hooks, {
|
|
error: sandbox.event.error
|
|
}),
|
|
{
|
|
skipPrefix: !0
|
|
}
|
|
);
|
|
}
|
|
), this;
|
|
}
|
|
/**
|
|
* ### guard
|
|
* Encapsulate and pass hook into all child handler
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .guard({
|
|
* body: t.Object({
|
|
* username: t.String(),
|
|
* password: t.String()
|
|
* })
|
|
* }, app => app
|
|
* .get("/", () => 'Hi')
|
|
* .get("/name", () => 'Elysia')
|
|
* })
|
|
* ```
|
|
*/
|
|
guard(hook, run) {
|
|
if (!run) {
|
|
if (typeof hook == "object") {
|
|
this.applyMacro(hook), hook.detail && (this.config.detail ? this.config.detail = (0, import_utils.mergeDeep)(
|
|
Object.assign({}, this.config.detail),
|
|
hook.detail
|
|
) : this.config.detail = hook.detail), hook.tags && (this.config.detail ? this.config.detail.tags = hook.tags : this.config.detail = {
|
|
tags: hook.tags
|
|
});
|
|
const type = hook.as ?? "local";
|
|
if (hook.schema === "standalone") {
|
|
this.standaloneValidator[type] || (this.standaloneValidator[type] = []);
|
|
const response = hook?.response ? typeof hook.response == "string" || import_typebox.Kind in hook.response || "~standard" in hook.response ? {
|
|
200: hook.response
|
|
} : hook?.response : void 0;
|
|
this.standaloneValidator[type].push({
|
|
body: hook.body,
|
|
headers: hook.headers,
|
|
params: hook.params,
|
|
query: hook.query,
|
|
response,
|
|
cookie: hook.cookie
|
|
});
|
|
} else
|
|
this.validator[type] = {
|
|
body: hook.body ?? this.validator[type]?.body,
|
|
headers: hook.headers ?? this.validator[type]?.headers,
|
|
params: hook.params ?? this.validator[type]?.params,
|
|
query: hook.query ?? this.validator[type]?.query,
|
|
response: hook.response ?? this.validator[type]?.response,
|
|
cookie: hook.cookie ?? this.validator[type]?.cookie
|
|
};
|
|
return hook.parse && this.on({ as: type }, "parse", hook.parse), hook.transform && this.on({ as: type }, "transform", hook.transform), hook.derive && this.on({ as: type }, "derive", hook.derive), hook.beforeHandle && this.on({ as: type }, "beforeHandle", hook.beforeHandle), hook.resolve && this.on({ as: type }, "resolve", hook.resolve), hook.afterHandle && this.on({ as: type }, "afterHandle", hook.afterHandle), hook.mapResponse && this.on({ as: type }, "mapResponse", hook.mapResponse), hook.afterResponse && this.on({ as: type }, "afterResponse", hook.afterResponse), hook.error && this.on({ as: type }, "error", hook.error), this;
|
|
}
|
|
return this.guard({}, hook);
|
|
}
|
|
const instance = new _Elysia({
|
|
...this.config,
|
|
prefix: ""
|
|
});
|
|
instance.singleton = { ...this.singleton }, instance.definitions = { ...this.definitions }, instance.inference = (0, import_utils.cloneInference)(this.inference), instance.extender = { ...this.extender }, instance.getServer = () => this.getServer();
|
|
const sandbox = run(instance);
|
|
if (this.singleton = (0, import_utils.mergeDeep)(this.singleton, instance.singleton), this.definitions = (0, import_utils.mergeDeep)(this.definitions, instance.definitions), sandbox.getServer = () => this.server, sandbox.event.request?.length && (this.event.request = [
|
|
...this.event.request || [],
|
|
...sandbox.event.request || []
|
|
]), sandbox.event.mapResponse?.length && (this.event.mapResponse = [
|
|
...this.event.mapResponse || [],
|
|
...sandbox.event.mapResponse || []
|
|
]), this.model(sandbox.definitions.type), Object.values(instance.router.history).forEach(
|
|
({ method, path, handler, hooks: localHook }) => {
|
|
const {
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response,
|
|
...guardHook
|
|
} = hook, hasStandaloneSchema = body || headers || query || params || cookie || response;
|
|
this.add(
|
|
method,
|
|
path,
|
|
handler,
|
|
(0, import_utils2.mergeHook)(guardHook, {
|
|
...localHook || {},
|
|
error: localHook.error ? Array.isArray(localHook.error) ? [
|
|
...localHook.error ?? [],
|
|
...sandbox.event.error ?? []
|
|
] : [
|
|
localHook.error,
|
|
...sandbox.event.error ?? []
|
|
] : sandbox.event.error,
|
|
standaloneValidator: hasStandaloneSchema ? [
|
|
...localHook.standaloneValidator ?? [],
|
|
{
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response
|
|
}
|
|
] : localHook.standaloneValidator
|
|
})
|
|
);
|
|
}
|
|
), instance.promisedModules.size > 0) {
|
|
let processedUntil = instance.router.history.length;
|
|
for (const promise of instance.promisedModules.promises)
|
|
this.promisedModules.add(
|
|
promise.then(() => {
|
|
const {
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response,
|
|
...guardHook
|
|
} = hook, hasStandaloneSchema = body || headers || query || params || cookie || response, startIndex = processedUntil;
|
|
processedUntil = instance.router.history.length;
|
|
for (let i = startIndex; i < instance.router.history.length; i++) {
|
|
const {
|
|
method,
|
|
path,
|
|
handler,
|
|
hooks: localHook
|
|
} = instance.router.history[i];
|
|
this.add(
|
|
method,
|
|
path,
|
|
handler,
|
|
(0, import_utils2.mergeHook)(guardHook, {
|
|
...localHook || {},
|
|
error: localHook.error ? Array.isArray(localHook.error) ? [
|
|
...localHook.error ?? [],
|
|
...sandbox.event.error ?? []
|
|
] : [
|
|
localHook.error,
|
|
...sandbox.event.error ?? []
|
|
] : sandbox.event.error,
|
|
standaloneValidator: hasStandaloneSchema ? [
|
|
...localHook.standaloneValidator ?? [],
|
|
{
|
|
body,
|
|
headers,
|
|
query,
|
|
params,
|
|
cookie,
|
|
response
|
|
}
|
|
] : localHook.standaloneValidator
|
|
})
|
|
);
|
|
}
|
|
})
|
|
);
|
|
}
|
|
return this;
|
|
}
|
|
/**
|
|
* ### use
|
|
* Merge separate logic of Elysia with current
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* const plugin = (app: Elysia) => app
|
|
* .get('/plugin', () => 'hi')
|
|
*
|
|
* new Elysia()
|
|
* .use(plugin)
|
|
* ```
|
|
*/
|
|
use(plugin) {
|
|
if (!plugin) return this;
|
|
if (Array.isArray(plugin)) {
|
|
let app = this;
|
|
for (const p of plugin) app = app.use(p);
|
|
return app;
|
|
}
|
|
return plugin instanceof Promise ? (this.promisedModules.add(
|
|
plugin.then((plugin2) => {
|
|
if (typeof plugin2 == "function") return plugin2(this);
|
|
if (plugin2 instanceof _Elysia)
|
|
return this._use(plugin2).compile();
|
|
if (plugin2.constructor?.name === "Elysia")
|
|
return this._use(
|
|
plugin2
|
|
).compile();
|
|
if (typeof plugin2.default == "function")
|
|
return plugin2.default(this);
|
|
if (plugin2.default instanceof _Elysia)
|
|
return this._use(plugin2.default);
|
|
if (plugin2.constructor?.name === "Elysia")
|
|
return this._use(plugin2.default);
|
|
if (plugin2.constructor?.name === "_Elysia")
|
|
return this._use(plugin2.default);
|
|
try {
|
|
return this._use(plugin2.default);
|
|
} catch (error) {
|
|
throw console.error(
|
|
'Invalid plugin type. Expected Elysia instance, function, or module with "default" as Elysia instance or function that returns Elysia instance.'
|
|
), error;
|
|
}
|
|
}).then((v) => (v && typeof v.compile == "function" && v.compile(), v))
|
|
), this) : this._use(plugin);
|
|
}
|
|
propagatePromiseModules(plugin) {
|
|
if (plugin.promisedModules.size <= 0) return this;
|
|
for (const promise of plugin.promisedModules.promises)
|
|
this.promisedModules.add(
|
|
promise.then((v) => {
|
|
if (!v) return;
|
|
const t3 = this._use(v);
|
|
return t3 instanceof Promise ? t3.then((v2) => {
|
|
v2 ? v2.compile() : v.compile();
|
|
}) : v.compile();
|
|
})
|
|
);
|
|
return this;
|
|
}
|
|
_use(plugin) {
|
|
if (typeof plugin == "function") {
|
|
const instance = plugin(this);
|
|
return instance instanceof Promise ? (this.promisedModules.add(
|
|
instance.then((plugin2) => {
|
|
if (plugin2 instanceof _Elysia) {
|
|
plugin2.getServer = () => this.getServer(), plugin2.getGlobalRoutes = () => this.getGlobalRoutes(), plugin2.getGlobalDefinitions = () => this.getGlobalDefinitions(), plugin2.model(this.definitions.type), plugin2.error(this.definitions.error);
|
|
for (const {
|
|
method,
|
|
path,
|
|
handler,
|
|
hooks
|
|
} of Object.values(plugin2.router.history))
|
|
this.add(
|
|
method,
|
|
path,
|
|
handler,
|
|
hooks,
|
|
void 0
|
|
);
|
|
return plugin2 === this ? void 0 : (this.propagatePromiseModules(plugin2), plugin2);
|
|
}
|
|
return typeof plugin2 == "function" ? plugin2(
|
|
this
|
|
) : typeof plugin2.default == "function" ? plugin2.default(
|
|
this
|
|
) : this._use(plugin2);
|
|
}).then((v) => (v && typeof v.compile == "function" && v.compile(), v))
|
|
), this) : instance;
|
|
}
|
|
this.propagatePromiseModules(plugin);
|
|
const name = plugin.config.name, seed = plugin.config.seed;
|
|
if (plugin.getParent = () => this, plugin.getServer = () => this.getServer(), plugin.getGlobalRoutes = () => this.getGlobalRoutes(), plugin.getGlobalDefinitions = () => this.getGlobalDefinitions(), plugin.standaloneValidator?.scoped && (this.standaloneValidator.local ? this.standaloneValidator.local = this.standaloneValidator.local.concat(
|
|
plugin.standaloneValidator.scoped
|
|
) : this.standaloneValidator.local = plugin.standaloneValidator.scoped), plugin.standaloneValidator?.global && (this.standaloneValidator.global ? this.standaloneValidator.global = this.standaloneValidator.global.concat(
|
|
plugin.standaloneValidator.global
|
|
) : this.standaloneValidator.global = plugin.standaloneValidator.global), (0, import_utils.isNotEmpty)(plugin["~parser"]) && (this["~parser"] = {
|
|
...plugin["~parser"],
|
|
...this["~parser"]
|
|
}), plugin.setHeaders && this.headers(plugin.setHeaders), name) {
|
|
name in this.dependencies || (this.dependencies[name] = []);
|
|
const current = seed !== void 0 ? (0, import_utils2.checksum)(name + JSON.stringify(seed)) : 0;
|
|
this.dependencies[name].some(
|
|
({ checksum: checksum3 }) => current === checksum3
|
|
) || (this.extender.macro = {
|
|
...this.extender.macro,
|
|
...plugin.extender.macro
|
|
}, this.extender.higherOrderFunctions = this.extender.higherOrderFunctions.concat(
|
|
plugin.extender.higherOrderFunctions
|
|
));
|
|
} else
|
|
(0, import_utils.isNotEmpty)(plugin.extender.macro) && (this.extender.macro = {
|
|
...this.extender.macro,
|
|
...plugin.extender.macro
|
|
}), plugin.extender.higherOrderFunctions.length && (this.extender.higherOrderFunctions = this.extender.higherOrderFunctions.concat(
|
|
plugin.extender.higherOrderFunctions
|
|
));
|
|
if (plugin.extender.higherOrderFunctions.length) {
|
|
(0, import_utils.deduplicateChecksum)(this.extender.higherOrderFunctions);
|
|
const hofHashes = [];
|
|
for (let i = 0; i < this.extender.higherOrderFunctions.length; i++) {
|
|
const hof = this.extender.higherOrderFunctions[i];
|
|
hof.checksum && (hofHashes.includes(hof.checksum) && (this.extender.higherOrderFunctions.splice(i, 1), i--), hofHashes.push(hof.checksum));
|
|
}
|
|
hofHashes.length = 0;
|
|
}
|
|
this.inference = (0, import_sucrose.mergeInference)(this.inference, plugin.inference), (0, import_utils.isNotEmpty)(plugin.singleton.decorator) && this.decorate(plugin.singleton.decorator), (0, import_utils.isNotEmpty)(plugin.singleton.store) && this.state(plugin.singleton.store), (0, import_utils.isNotEmpty)(plugin.definitions.type) && this.model(plugin.definitions.type), (0, import_utils.isNotEmpty)(plugin.definitions.error) && this.error(plugin.definitions.error), (0, import_utils.isNotEmpty)(plugin.extender.macro) && (this.extender.macro = {
|
|
...this.extender.macro,
|
|
...plugin.extender.macro
|
|
});
|
|
for (const { method, path, handler, hooks } of Object.values(
|
|
plugin.router.history
|
|
))
|
|
this.add(method, path, handler, hooks);
|
|
if (name) {
|
|
name in this.dependencies || (this.dependencies[name] = []);
|
|
const current = seed !== void 0 ? (0, import_utils2.checksum)(name + JSON.stringify(seed)) : 0;
|
|
if (this.dependencies[name].some(
|
|
({ checksum: checksum3 }) => current === checksum3
|
|
))
|
|
return this;
|
|
this.dependencies[name].push(
|
|
this.config?.analytic ? {
|
|
name: plugin.config.name,
|
|
seed: plugin.config.seed,
|
|
checksum: current,
|
|
dependencies: plugin.dependencies,
|
|
stack: plugin.telemetry?.stack,
|
|
routes: plugin.router.history,
|
|
decorators: plugin.singleton,
|
|
store: plugin.singleton.store,
|
|
error: plugin.definitions.error,
|
|
derive: plugin.event.transform?.filter((x) => x?.subType === "derive").map((x) => ({
|
|
fn: x.toString(),
|
|
stack: new Error().stack ?? ""
|
|
})),
|
|
resolve: plugin.event.transform?.filter((x) => x?.subType === "resolve").map((x) => ({
|
|
fn: x.toString(),
|
|
stack: new Error().stack ?? ""
|
|
}))
|
|
} : {
|
|
name: plugin.config.name,
|
|
seed: plugin.config.seed,
|
|
checksum: current,
|
|
dependencies: plugin.dependencies
|
|
}
|
|
), (0, import_utils.isNotEmpty)(plugin.event) && (this.event = (0, import_utils2.mergeLifeCycle)(
|
|
this.event,
|
|
(0, import_utils2.filterGlobalHook)(plugin.event),
|
|
current
|
|
));
|
|
} else
|
|
(0, import_utils.isNotEmpty)(plugin.event) && (this.event = (0, import_utils2.mergeLifeCycle)(
|
|
this.event,
|
|
(0, import_utils2.filterGlobalHook)(plugin.event)
|
|
));
|
|
return plugin.validator.global && (this.validator.global = (0, import_utils2.mergeHook)(this.validator.global, {
|
|
...plugin.validator.global
|
|
})), plugin.validator.scoped && (this.validator.local = (0, import_utils2.mergeHook)(this.validator.local, {
|
|
...plugin.validator.scoped
|
|
})), this;
|
|
}
|
|
macro(macroOrName, macro) {
|
|
if (typeof macroOrName == "string" && !macro)
|
|
throw new Error("Macro function is required");
|
|
return typeof macroOrName == "string" ? this.extender.macro[macroOrName] = macro : this.extender.macro = {
|
|
...this.extender.macro,
|
|
...macroOrName
|
|
}, this;
|
|
}
|
|
applyMacro(localHook, appliable = localHook, {
|
|
iteration = 0,
|
|
applied = {}
|
|
} = {}) {
|
|
if (iteration >= 16) return;
|
|
const macro = this.extender.macro;
|
|
for (let [key, value] of Object.entries(appliable)) {
|
|
if (!(key in macro)) continue;
|
|
const macroHook = typeof macro[key] == "function" ? macro[key](value) : macro[key];
|
|
if (!macroHook || typeof macro[key] == "object" && value === !1)
|
|
return;
|
|
const seed = (0, import_utils2.checksum)(key + JSON.stringify(macroHook.seed ?? value));
|
|
if (!(seed in applied)) {
|
|
applied[seed] = !0;
|
|
for (let [k, value2] of Object.entries(macroHook))
|
|
if (k !== "seed") {
|
|
if (k in import_utils.emptySchema) {
|
|
(0, import_utils.insertStandaloneValidator)(
|
|
localHook,
|
|
k,
|
|
value2
|
|
), delete localHook[key];
|
|
continue;
|
|
}
|
|
if (k === "introspect") {
|
|
value2?.(localHook), delete localHook[key];
|
|
continue;
|
|
}
|
|
if (k === "detail") {
|
|
localHook.detail || (localHook.detail = {}), localHook.detail = (0, import_utils.mergeDeep)(localHook.detail, value2, {
|
|
mergeArray: !0
|
|
}), delete localHook[key];
|
|
continue;
|
|
}
|
|
if (k in macro) {
|
|
this.applyMacro(
|
|
localHook,
|
|
{ [k]: value2 },
|
|
{ applied, iteration: iteration + 1 }
|
|
), delete localHook[key];
|
|
continue;
|
|
}
|
|
switch ((k === "derive" || k === "resolve") && typeof value2 == "function" && (value2 = {
|
|
fn: value2,
|
|
subType: k
|
|
}), typeof localHook[k]) {
|
|
case "function":
|
|
localHook[k] = [localHook[k], value2];
|
|
break;
|
|
case "object":
|
|
Array.isArray(localHook[k]) ? localHook[k].push(value2) : localHook[k] = [localHook[k], value2];
|
|
break;
|
|
case "undefined":
|
|
localHook[k] = value2;
|
|
break;
|
|
}
|
|
delete localHook[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
mount(path, handleOrConfig, config) {
|
|
if (path instanceof _Elysia || typeof path == "function" || path.length === 0 || path === "/") {
|
|
const run = typeof path == "function" ? path : path instanceof _Elysia ? path.compile().fetch : handleOrConfig instanceof _Elysia ? handleOrConfig.compile().fetch : typeof handleOrConfig == "function" ? handleOrConfig : (() => {
|
|
throw new Error("Invalid handler");
|
|
})(), handler2 = ({ request, path: path2 }) => run(new Request((0, import_utils2.replaceUrlPath)(request.url, path2), request));
|
|
return this.route("ALL", "/*", handler2, {
|
|
parse: "none",
|
|
...config,
|
|
detail: {
|
|
...config?.detail,
|
|
hide: !0
|
|
},
|
|
config: {
|
|
mount: run
|
|
}
|
|
}), this;
|
|
}
|
|
const handle = handleOrConfig instanceof _Elysia ? handleOrConfig.compile().fetch : typeof handleOrConfig == "function" ? handleOrConfig : (() => {
|
|
throw new Error("Invalid handler");
|
|
})(), length = (typeof path == "string" && this.config.prefix ? this.config.prefix + path : path).length - (path.endsWith("*") ? 1 : 0), handler = ({ request, path: path2 }) => handle(
|
|
new Request(
|
|
(0, import_utils2.replaceUrlPath)(request.url, path2.slice(length) || "/"),
|
|
request
|
|
)
|
|
);
|
|
return this.route("ALL", path, handler, {
|
|
parse: "none",
|
|
...config,
|
|
detail: {
|
|
...config?.detail,
|
|
hide: !0
|
|
},
|
|
config: {
|
|
mount: handle
|
|
}
|
|
}), this.route(
|
|
"ALL",
|
|
path + (path.endsWith("/") ? "*" : "/*"),
|
|
handler,
|
|
{
|
|
parse: "none",
|
|
...config,
|
|
detail: {
|
|
...config?.detail,
|
|
hide: !0
|
|
},
|
|
config: {
|
|
mount: handle
|
|
}
|
|
}
|
|
), this;
|
|
}
|
|
/**
|
|
* ### get
|
|
* Register handler for path with method [GET]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .get('/', () => 'hi')
|
|
* .get('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
get(path, handler, hook) {
|
|
return this.add("GET", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### post
|
|
* Register handler for path with method [POST]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .post('/', () => 'hi')
|
|
* .post('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
post(path, handler, hook) {
|
|
return this.add("POST", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### put
|
|
* Register handler for path with method [PUT]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .put('/', () => 'hi')
|
|
* .put('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
put(path, handler, hook) {
|
|
return this.add("PUT", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### patch
|
|
* Register handler for path with method [PATCH]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .patch('/', () => 'hi')
|
|
* .patch('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
patch(path, handler, hook) {
|
|
return this.add("PATCH", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### delete
|
|
* Register handler for path with method [DELETE]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .delete('/', () => 'hi')
|
|
* .delete('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
delete(path, handler, hook) {
|
|
return this.add("DELETE", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### options
|
|
* Register handler for path with method [POST]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .options('/', () => 'hi')
|
|
* .options('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
options(path, handler, hook) {
|
|
return this.add("OPTIONS", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### all
|
|
* Register handler for path with method [ALL]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .all('/', () => 'hi')
|
|
* .all('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
all(path, handler, hook) {
|
|
return this.add("ALL", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### head
|
|
* Register handler for path with method [HEAD]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .head('/', () => 'hi')
|
|
* .head('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
head(path, handler, hook) {
|
|
return this.add("HEAD", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### connect
|
|
* Register handler for path with method [CONNECT]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .connect('/', () => 'hi')
|
|
* .connect('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
connect(path, handler, hook) {
|
|
return this.add("CONNECT", path, handler, hook), this;
|
|
}
|
|
/**
|
|
* ### route
|
|
* Register handler for path with method [ROUTE]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .route('/', () => 'hi')
|
|
* .route('/with-hook', () => 'hi', {
|
|
* response: t.String()
|
|
* })
|
|
* ```
|
|
*/
|
|
route(method, path, handler, hook) {
|
|
return this.add(method.toUpperCase(), path, handler, hook, hook?.config), this;
|
|
}
|
|
/**
|
|
* ### ws
|
|
* Register handler for path with method [ws]
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* import { Elysia, t } from 'elysia'
|
|
*
|
|
* new Elysia()
|
|
* .ws('/', {
|
|
* message(ws, message) {
|
|
* ws.send(message)
|
|
* }
|
|
* })
|
|
* ```
|
|
*/
|
|
ws(path, options) {
|
|
return this["~adapter"].ws ? this["~adapter"].ws(this, path, options) : console.warn("Current adapter doesn't support WebSocket"), this;
|
|
}
|
|
/**
|
|
* ### state
|
|
* Assign global mutatable state accessible for all handler
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .state('counter', 0)
|
|
* .get('/', (({ counter }) => ++counter)
|
|
* ```
|
|
*/
|
|
state(options, name, value) {
|
|
name === void 0 ? (value = options, options = { as: "append" }, name = "") : value === void 0 && (typeof options == "string" ? (value = name, name = options, options = { as: "append" }) : typeof options == "object" && (value = name, name = ""));
|
|
const { as } = options;
|
|
if (typeof name != "string") return this;
|
|
switch (typeof value) {
|
|
case "object":
|
|
return !value || !(0, import_utils.isNotEmpty)(value) ? this : name ? (name in this.singleton.store ? this.singleton.store[name] = (0, import_utils.mergeDeep)(
|
|
this.singleton.store[name],
|
|
value,
|
|
{
|
|
override: as === "override"
|
|
}
|
|
) : this.singleton.store[name] = value, this) : value === null ? this : (this.singleton.store = (0, import_utils.mergeDeep)(this.singleton.store, value, {
|
|
override: as === "override"
|
|
}), this);
|
|
case "function":
|
|
return name ? (as === "override" || !(name in this.singleton.store)) && (this.singleton.store[name] = value) : this.singleton.store = value(this.singleton.store), this;
|
|
default:
|
|
return (as === "override" || !(name in this.singleton.store)) && (this.singleton.store[name] = value), this;
|
|
}
|
|
}
|
|
/**
|
|
* ### decorate
|
|
* Define custom method to `Context` accessible for all handler
|
|
*
|
|
* ---
|
|
* @example
|
|
* ```typescript
|
|
* new Elysia()
|
|
* .decorate('getDate', () => Date.now())
|
|
* .get('/', (({ getDate }) => getDate())
|
|
* ```
|
|
*/
|
|
decorate(options, name, value) {
|
|
name === void 0 ? (value = options, options = { as: "append" }, name = "") : value === void 0 && (typeof options == "string" ? (value = name, name = options, options = { as: "append" }) : typeof options == "object" && (value = name, name = ""));
|
|
const { as } = options;
|
|
if (typeof name != "string") return this;
|
|
switch (typeof value) {
|
|
case "object":
|
|
return name ? (name in this.singleton.decorator ? this.singleton.decorator[name] = (0, import_utils.mergeDeep)(
|
|
this.singleton.decorator[name],
|
|
value,
|
|
{
|
|
override: as === "override"
|
|
}
|
|
) : this.singleton.decorator[name] = value, this) : value === null ? this : (this.singleton.decorator = (0, import_utils.mergeDeep)(
|
|
this.singleton.decorator,
|
|
value,
|
|
{
|
|
override: as === "override"
|
|
}
|
|
), this);
|
|
case "function":
|
|
return name ? (as === "override" || !(name in this.singleton.decorator)) && (this.singleton.decorator[name] = value) : this.singleton.decorator = value(this.singleton.decorator), this;
|
|
default:
|
|
return (as === "override" || !(name in this.singleton.decorator)) && (this.singleton.decorator[name] = value), this;
|
|
}
|
|
}
|
|
derive(optionsOrTransform, transform) {
|
|
transform || (transform = optionsOrTransform, optionsOrTransform = { as: "local" });
|
|
const hook = {
|
|
subType: "derive",
|
|
fn: transform
|
|
};
|
|
return this.onTransform(optionsOrTransform, hook);
|
|
}
|
|
model(name, model) {
|
|
const onlyTypebox = (a) => {
|
|
const res = {};
|
|
for (const key in a) "~standard" in a[key] || (res[key] = a[key]);
|
|
return res;
|
|
};
|
|
switch (typeof name) {
|
|
case "object":
|
|
const parsedTypebox = {}, kvs = Object.entries(name);
|
|
if (!kvs.length) return this;
|
|
for (const [key, value] of kvs)
|
|
key in this.definitions.type || ("~standard" in value ? this.definitions.type[key] = value : (parsedTypebox[key] = this.definitions.type[key] = value, parsedTypebox[key].$id ??= `#/components/schemas/${key}`));
|
|
return this.definitions.typebox = import_type_system.t.Module({
|
|
...this.definitions.typebox.$defs,
|
|
...parsedTypebox
|
|
}), this;
|
|
case "function":
|
|
const result = name(this.definitions.type);
|
|
return this.definitions.type = result, this.definitions.typebox = import_type_system.t.Module(onlyTypebox(result)), this;
|
|
case "string":
|
|
if (!model) break;
|
|
if (this.definitions.type[name] = model, "~standard" in model) return this;
|
|
const newModel = {
|
|
...model,
|
|
id: model.$id ?? `#/components/schemas/${name}`
|
|
};
|
|
return this.definitions.typebox = import_type_system.t.Module({
|
|
...this.definitions.typebox.$defs,
|
|
...newModel
|
|
}), this;
|
|
}
|
|
return model ? (this.definitions.type[name] = model, "~standard" in model ? this : (this.definitions.typebox = import_type_system.t.Module({
|
|
...this.definitions.typebox.$defs,
|
|
[name]: model
|
|
}), this)) : this;
|
|
}
|
|
Ref(key) {
|
|
return import_type_system.t.Ref(key);
|
|
}
|
|
mapDerive(optionsOrDerive, mapper) {
|
|
mapper || (mapper = optionsOrDerive, optionsOrDerive = { as: "local" });
|
|
const hook = {
|
|
subType: "mapDerive",
|
|
fn: mapper
|
|
};
|
|
return this.onTransform(optionsOrDerive, hook);
|
|
}
|
|
affix(base, type, word) {
|
|
if (word === "") return this;
|
|
const delimieter = ["_", "-", " "], capitalize = (word2) => word2[0].toUpperCase() + word2.slice(1), joinKey = base === "prefix" ? (prefix, word2) => delimieter.includes(prefix.at(-1) ?? "") ? prefix + word2 : prefix + capitalize(word2) : delimieter.includes(word.at(-1) ?? "") ? (suffix, word2) => word2 + suffix : (suffix, word2) => word2 + capitalize(suffix), remap = (type2) => {
|
|
const store = {};
|
|
switch (type2) {
|
|
case "decorator":
|
|
for (const key in this.singleton.decorator)
|
|
store[joinKey(word, key)] = this.singleton.decorator[key];
|
|
this.singleton.decorator = store;
|
|
break;
|
|
case "state":
|
|
for (const key in this.singleton.store)
|
|
store[joinKey(word, key)] = this.singleton.store[key];
|
|
this.singleton.store = store;
|
|
break;
|
|
case "model":
|
|
for (const key in this.definitions.type)
|
|
store[joinKey(word, key)] = this.definitions.type[key];
|
|
this.definitions.type = store;
|
|
break;
|
|
case "error":
|
|
for (const key in this.definitions.error)
|
|
store[joinKey(word, key)] = this.definitions.error[key];
|
|
this.definitions.error = store;
|
|
break;
|
|
}
|
|
}, types = Array.isArray(type) ? type : [type];
|
|
for (const type2 of types.some((x) => x === "all") ? ["decorator", "state", "model", "error"] : types)
|
|
remap(type2);
|
|
return this;
|
|
}
|
|
prefix(type, word) {
|
|
return this.affix("prefix", type, word);
|
|
}
|
|
suffix(type, word) {
|
|
return this.affix("suffix", type, word);
|
|
}
|
|
compile() {
|
|
return this["~adapter"].beforeCompile?.(this), this["~adapter"].isWebStandard ? (this._handle = this.config.aot ? (0, import_compose.composeGeneralHandler)(this) : (0, import_dynamic_handle.createDynamicHandler)(this), Object.defineProperty(this, "fetch", {
|
|
value: this._handle,
|
|
configurable: !0,
|
|
writable: !0
|
|
}), typeof this.server?.reload == "function" && this.server.reload({
|
|
...this.server || {},
|
|
fetch: this.fetch
|
|
}), this) : (typeof this.server?.reload == "function" && this.server.reload(this.server || {}), this._handle = (0, import_compose.composeGeneralHandler)(this), this);
|
|
}
|
|
/**
|
|
* Use handle can be either sync or async to save performance.
|
|
*
|
|
* Beside benchmark purpose, please use 'handle' instead.
|
|
*/
|
|
get fetch() {
|
|
const fetch = this.config.aot ? (0, import_compose.composeGeneralHandler)(this) : (0, import_dynamic_handle.createDynamicHandler)(this);
|
|
return Object.defineProperty(this, "fetch", {
|
|
value: fetch,
|
|
configurable: !0,
|
|
writable: !0
|
|
}), fetch;
|
|
}
|
|
/**
|
|
* Wait until all lazy loaded modules all load is fully
|
|
*/
|
|
get modules() {
|
|
return this.promisedModules;
|
|
}
|
|
};
|
|
let Elysia = _Elysia;
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
Cookie,
|
|
ELYSIA_FORM_DATA,
|
|
ELYSIA_REQUEST_ID,
|
|
ELYSIA_TRACE,
|
|
ERROR_CODE,
|
|
Elysia,
|
|
ElysiaCustomStatusResponse,
|
|
ElysiaFile,
|
|
ElysiaStatus,
|
|
InternalServerError,
|
|
InvalidCookieSignature,
|
|
InvalidFileType,
|
|
InvertedStatusMap,
|
|
NotFoundError,
|
|
ParseError,
|
|
StatusMap,
|
|
TypeSystemPolicy,
|
|
ValidationError,
|
|
checksum,
|
|
cloneInference,
|
|
deduplicateChecksum,
|
|
env,
|
|
file,
|
|
fileType,
|
|
form,
|
|
getResponseSchemaValidator,
|
|
getSchemaValidator,
|
|
mapValueError,
|
|
mergeHook,
|
|
mergeObjectArray,
|
|
redirect,
|
|
replaceSchemaType,
|
|
replaceUrlPath,
|
|
serializeCookie,
|
|
sse,
|
|
status,
|
|
t,
|
|
validationDetail
|
|
});
|