elysia
Advanced tools
Comparing version 0.1.0-rc.7 to 0.1.0-rc.8
/// <reference types="bun-types" /> | ||
import type { Serve, Server } from 'bun'; | ||
import { SCHEMA } from './utils'; | ||
import type { Context } from './context'; | ||
@@ -192,3 +193,15 @@ import type { Handler, BeforeRequestHandler, TypedRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, InternalRoute, BodyParser, ErrorHandler, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, LifeCycleStore, VoidLifeCycle, AfterRequestHandler, MergeIfNotNull, IsAny, OverwritableTypeRoute, MergeSchema, ListenCallback, NoReturnHandler, ElysiaRoute } from './types'; | ||
*/ | ||
group(prefix: string, run: (group: Elysia<Instance>) => void): this; | ||
group<NewElysia extends Elysia<any> = Elysia<any>, Prefix extends string = string>(prefix: Prefix, run: (group: Elysia<{ | ||
request: Instance['request']; | ||
store: Omit<Instance['store'], typeof SCHEMA> & ElysiaInstance['store']; | ||
schema: Instance['schema']; | ||
}>) => NewElysia): NewElysia extends Elysia<infer NewInstance> ? Elysia<{ | ||
request: Instance['request'] & NewInstance['request']; | ||
schema: Instance['schema'] & NewInstance['schema']; | ||
store: Instance['store'] & (Omit<NewInstance['store'], typeof SCHEMA> & { | ||
[key in typeof SCHEMA]: { | ||
[key in keyof NewInstance['store'][typeof SCHEMA] as key extends `${infer Rest}` ? `${Prefix}${Rest}` : key]: NewInstance['store'][typeof SCHEMA][key]; | ||
}; | ||
}); | ||
}> : this; | ||
/** | ||
@@ -217,7 +230,7 @@ * ### guard | ||
*/ | ||
guard<Schema extends TypedSchema = {}>(hook: LocalHook<Schema, Instance>, run: (group: Elysia<{ | ||
guard<Schema extends TypedSchema = {}, NewElysia extends Elysia<any> = Elysia<any>>(hook: LocalHook<Schema, Instance>, run: (group: Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: MergeIfNotNull<Schema, Instance['schema']>; | ||
}>) => void): this; | ||
schema: Omit<MergeIfNotNull<Schema, Instance['schema']>, typeof SCHEMA>; | ||
}>) => NewElysia): NewElysia extends Elysia<infer NewInstance> ? Elysia<NewInstance & Instance> : this; | ||
/** | ||
@@ -224,0 +237,0 @@ * ### use |
@@ -746,3 +746,3 @@ "use strict"; | ||
} | ||
const index = request.url.indexOf('?'); | ||
const index = request.url.indexOf('?', 12); | ||
const route = this.router.find((0, utils_1.getPath)(request.url, index)); | ||
@@ -760,4 +760,5 @@ if (!route) | ||
if (contentType) { | ||
for (let i = 0; i < this.event.parse.length; i++) { | ||
let temp = this.event.parse[i](request, contentType); | ||
const parse = this.event.parse; | ||
for (let i = 0; i < parse.length; i++) { | ||
let temp = parse[i](request, contentType); | ||
if (temp instanceof Promise) | ||
@@ -781,2 +782,3 @@ temp = await temp; | ||
} | ||
const hooks = handler.hooks; | ||
const context = (this.decorators | ||
@@ -800,4 +802,4 @@ ? (0, utils_1.clone)(this.decorators) | ||
} | ||
for (let i = 0; i < handler.hooks.transform.length; i++) { | ||
const operation = handler.hooks.transform[i](context); | ||
for (let i = 0; i < hooks.transform.length; i++) { | ||
const operation = hooks.transform[i](context); | ||
if (operation instanceof Promise) | ||
@@ -807,19 +809,19 @@ await operation; | ||
if (handler.validator) { | ||
if (handler.validator.headers) { | ||
const validator = handler.validator; | ||
if (validator.headers) { | ||
const _header = {}; | ||
for (const key in request.headers) | ||
_header[key] = request.headers.get(key); | ||
if (handler.validator.headers.Check(_header) === false) | ||
throw (0, utils_1.createValidationError)('header', handler.validator.headers, _header); | ||
if (validator.headers.Check(_header) === false) | ||
throw (0, utils_1.createValidationError)('header', validator.headers, _header); | ||
} | ||
if (handler.validator.params?.Check(context.params) === false) | ||
throw (0, utils_1.createValidationError)('params', handler.validator.params, context.params); | ||
if (handler.validator.query?.Check(context.query) === false) { | ||
throw (0, utils_1.createValidationError)('query', handler.validator.query, context.query); | ||
} | ||
if (handler.validator.body?.Check(body) === false) | ||
throw (0, utils_1.createValidationError)('body', handler.validator.body, body); | ||
if (validator.params?.Check(context.params) === false) | ||
throw (0, utils_1.createValidationError)('params', validator.params, context.params); | ||
if (validator.query?.Check(context.query) === false) | ||
throw (0, utils_1.createValidationError)('query', validator.query, context.query); | ||
if (validator.body?.Check(body) === false) | ||
throw (0, utils_1.createValidationError)('body', validator.body, body); | ||
} | ||
for (let i = 0; i < handler.hooks.beforeHandle.length; i++) { | ||
let response = handler.hooks.beforeHandle[i](context); | ||
for (let i = 0; i < hooks.beforeHandle.length; i++) { | ||
let response = hooks.beforeHandle[i](context); | ||
if (response instanceof Promise) | ||
@@ -829,4 +831,4 @@ response = await response; | ||
if (response !== null && response !== undefined) { | ||
for (let i = 0; i < handler.hooks.afterHandle.length; i++) { | ||
let newResponse = handler.hooks.afterHandle[i](context, response); | ||
for (let i = 0; i < hooks.afterHandle.length; i++) { | ||
let newResponse = hooks.afterHandle[i](context, response); | ||
if (newResponse instanceof Promise) | ||
@@ -847,4 +849,4 @@ newResponse = await newResponse; | ||
throw (0, utils_1.createValidationError)('response', handler.validator.response, response); | ||
for (let i = 0; i < handler.hooks.afterHandle.length; i++) { | ||
let newResponse = handler.hooks.afterHandle[i](context, response); | ||
for (let i = 0; i < hooks.afterHandle.length; i++) { | ||
let newResponse = hooks.afterHandle[i](context, response); | ||
if (newResponse instanceof Promise) | ||
@@ -851,0 +853,0 @@ newResponse = await newResponse; |
@@ -167,16 +167,17 @@ "use strict"; | ||
function matchRoute(url, urlLength, node, startIndex) { | ||
const pathPartEndIndex = startIndex + node.pathPart.length; | ||
const pathPart = node.pathPart; | ||
const pathPartEndIndex = startIndex + pathPart.length; | ||
// Only check the pathPart if its length is > 1 since the parent has | ||
// already checked that the url matches the first character | ||
if (node.pathPart.length > 1) { | ||
if (pathPart.length > 1) { | ||
if (pathPartEndIndex > urlLength) | ||
return null; | ||
if (node.pathPart.length < 15) | ||
if (pathPart.length < 15) | ||
// Using a loop is faster for short strings | ||
for (let i = 1, j = startIndex + 1; i < node.pathPart.length; ++i, ++j) { | ||
if (node.pathPart[i] !== url[j]) { | ||
for (let i = 1, j = startIndex + 1; i < pathPart.length; ++i, ++j) { | ||
if (pathPart[i] !== url[j]) { | ||
return null; | ||
} | ||
} | ||
else if (url.slice(startIndex, pathPartEndIndex) !== node.pathPart) | ||
else if (url.slice(startIndex, pathPartEndIndex) !== pathPart) | ||
return null; | ||
@@ -183,0 +184,0 @@ } |
@@ -15,3 +15,3 @@ import type { TSchema } from '@sinclair/typebox'; | ||
hook?: LocalHook<any, import("./types").ElysiaInstance<{ | ||
store: {}; | ||
store: Record<typeof import("./utils").SCHEMA, {}>; | ||
request: {}; | ||
@@ -18,0 +18,0 @@ schema: {}; |
@@ -10,7 +10,7 @@ /// <reference types="bun-types" /> | ||
export interface ElysiaInstance<Instance extends { | ||
store?: Record<any | typeof SCHEMA, any>; | ||
store?: Record<any, any> & Record<typeof SCHEMA, Record<string, Partial<Record<HTTPMethod, TypedSchema>>>>; | ||
request?: Record<any, any>; | ||
schema?: TypedSchema; | ||
} = { | ||
store: {}; | ||
store: Record<typeof SCHEMA, {}>; | ||
request: {}; | ||
@@ -50,3 +50,3 @@ schema: {}; | ||
} | ||
export type BeforeRequestHandler<Store extends Record<string, any> = {}> = (context: PreContext<Store>) => void | Promise<void> | Response | Promise<Response>; | ||
export type BeforeRequestHandler<Store extends ElysiaInstance['store'] = ElysiaInstance['store']> = (context: PreContext<Store>) => void | Promise<void> | Response | Promise<Response>; | ||
export interface RegisteredHook<Instance extends ElysiaInstance = ElysiaInstance> { | ||
@@ -53,0 +53,0 @@ schema?: TypedSchema; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const compiler_1 = require("@sinclair/typebox/compiler"); | ||
// ? Internal property | ||
exports.SCHEMA = Symbol('schema'); | ||
@@ -35,3 +36,3 @@ const mergeObjectArray = (a, b) => [ | ||
exports.clone = clone; | ||
const getPath = (url, queryIndex) => url.substring(url.charCodeAt(0) === 47 ? 0 : url.indexOf('/', 11), queryIndex === -1 ? url.length : queryIndex); | ||
const getPath = (url, queryIndex) => url.substring(url.indexOf('/', 11), queryIndex === -1 ? url.length : queryIndex); | ||
exports.getPath = getPath; | ||
@@ -38,0 +39,0 @@ const mapQuery = (url, queryIndex) => { |
/// <reference types="bun-types" /> | ||
import type { Serve, Server } from 'bun'; | ||
import { SCHEMA } from './utils'; | ||
import type { Context } from './context'; | ||
@@ -192,3 +193,15 @@ import type { Handler, BeforeRequestHandler, TypedRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, InternalRoute, BodyParser, ErrorHandler, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, LifeCycleStore, VoidLifeCycle, AfterRequestHandler, MergeIfNotNull, IsAny, OverwritableTypeRoute, MergeSchema, ListenCallback, NoReturnHandler, ElysiaRoute } from './types'; | ||
*/ | ||
group(prefix: string, run: (group: Elysia<Instance>) => void): this; | ||
group<NewElysia extends Elysia<any> = Elysia<any>, Prefix extends string = string>(prefix: Prefix, run: (group: Elysia<{ | ||
request: Instance['request']; | ||
store: Omit<Instance['store'], typeof SCHEMA> & ElysiaInstance['store']; | ||
schema: Instance['schema']; | ||
}>) => NewElysia): NewElysia extends Elysia<infer NewInstance> ? Elysia<{ | ||
request: Instance['request'] & NewInstance['request']; | ||
schema: Instance['schema'] & NewInstance['schema']; | ||
store: Instance['store'] & (Omit<NewInstance['store'], typeof SCHEMA> & { | ||
[key in typeof SCHEMA]: { | ||
[key in keyof NewInstance['store'][typeof SCHEMA] as key extends `${infer Rest}` ? `${Prefix}${Rest}` : key]: NewInstance['store'][typeof SCHEMA][key]; | ||
}; | ||
}); | ||
}> : this; | ||
/** | ||
@@ -217,7 +230,7 @@ * ### guard | ||
*/ | ||
guard<Schema extends TypedSchema = {}>(hook: LocalHook<Schema, Instance>, run: (group: Elysia<{ | ||
guard<Schema extends TypedSchema = {}, NewElysia extends Elysia<any> = Elysia<any>>(hook: LocalHook<Schema, Instance>, run: (group: Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: MergeIfNotNull<Schema, Instance['schema']>; | ||
}>) => void): this; | ||
schema: Omit<MergeIfNotNull<Schema, Instance['schema']>, typeof SCHEMA>; | ||
}>) => NewElysia): NewElysia extends Elysia<infer NewInstance> ? Elysia<NewInstance & Instance> : this; | ||
/** | ||
@@ -224,0 +237,0 @@ * ### use |
@@ -743,3 +743,3 @@ import { Router } from './router'; | ||
} | ||
const index = request.url.indexOf('?'); | ||
const index = request.url.indexOf('?', 12); | ||
const route = this.router.find(getPath(request.url, index)); | ||
@@ -757,4 +757,5 @@ if (!route) | ||
if (contentType) { | ||
for (let i = 0; i < this.event.parse.length; i++) { | ||
let temp = this.event.parse[i](request, contentType); | ||
const parse = this.event.parse; | ||
for (let i = 0; i < parse.length; i++) { | ||
let temp = parse[i](request, contentType); | ||
if (temp instanceof Promise) | ||
@@ -778,2 +779,3 @@ temp = await temp; | ||
} | ||
const hooks = handler.hooks; | ||
const context = (this.decorators | ||
@@ -797,4 +799,4 @@ ? clone(this.decorators) | ||
} | ||
for (let i = 0; i < handler.hooks.transform.length; i++) { | ||
const operation = handler.hooks.transform[i](context); | ||
for (let i = 0; i < hooks.transform.length; i++) { | ||
const operation = hooks.transform[i](context); | ||
if (operation instanceof Promise) | ||
@@ -804,19 +806,19 @@ await operation; | ||
if (handler.validator) { | ||
if (handler.validator.headers) { | ||
const validator = handler.validator; | ||
if (validator.headers) { | ||
const _header = {}; | ||
for (const key in request.headers) | ||
_header[key] = request.headers.get(key); | ||
if (handler.validator.headers.Check(_header) === false) | ||
throw createValidationError('header', handler.validator.headers, _header); | ||
if (validator.headers.Check(_header) === false) | ||
throw createValidationError('header', validator.headers, _header); | ||
} | ||
if (handler.validator.params?.Check(context.params) === false) | ||
throw createValidationError('params', handler.validator.params, context.params); | ||
if (handler.validator.query?.Check(context.query) === false) { | ||
throw createValidationError('query', handler.validator.query, context.query); | ||
} | ||
if (handler.validator.body?.Check(body) === false) | ||
throw createValidationError('body', handler.validator.body, body); | ||
if (validator.params?.Check(context.params) === false) | ||
throw createValidationError('params', validator.params, context.params); | ||
if (validator.query?.Check(context.query) === false) | ||
throw createValidationError('query', validator.query, context.query); | ||
if (validator.body?.Check(body) === false) | ||
throw createValidationError('body', validator.body, body); | ||
} | ||
for (let i = 0; i < handler.hooks.beforeHandle.length; i++) { | ||
let response = handler.hooks.beforeHandle[i](context); | ||
for (let i = 0; i < hooks.beforeHandle.length; i++) { | ||
let response = hooks.beforeHandle[i](context); | ||
if (response instanceof Promise) | ||
@@ -826,4 +828,4 @@ response = await response; | ||
if (response !== null && response !== undefined) { | ||
for (let i = 0; i < handler.hooks.afterHandle.length; i++) { | ||
let newResponse = handler.hooks.afterHandle[i](context, response); | ||
for (let i = 0; i < hooks.afterHandle.length; i++) { | ||
let newResponse = hooks.afterHandle[i](context, response); | ||
if (newResponse instanceof Promise) | ||
@@ -844,4 +846,4 @@ newResponse = await newResponse; | ||
throw createValidationError('response', handler.validator.response, response); | ||
for (let i = 0; i < handler.hooks.afterHandle.length; i++) { | ||
let newResponse = handler.hooks.afterHandle[i](context, response); | ||
for (let i = 0; i < hooks.afterHandle.length; i++) { | ||
let newResponse = hooks.afterHandle[i](context, response); | ||
if (newResponse instanceof Promise) | ||
@@ -848,0 +850,0 @@ newResponse = await newResponse; |
@@ -163,16 +163,17 @@ /** | ||
function matchRoute(url, urlLength, node, startIndex) { | ||
const pathPartEndIndex = startIndex + node.pathPart.length; | ||
const pathPart = node.pathPart; | ||
const pathPartEndIndex = startIndex + pathPart.length; | ||
// Only check the pathPart if its length is > 1 since the parent has | ||
// already checked that the url matches the first character | ||
if (node.pathPart.length > 1) { | ||
if (pathPart.length > 1) { | ||
if (pathPartEndIndex > urlLength) | ||
return null; | ||
if (node.pathPart.length < 15) | ||
if (pathPart.length < 15) | ||
// Using a loop is faster for short strings | ||
for (let i = 1, j = startIndex + 1; i < node.pathPart.length; ++i, ++j) { | ||
if (node.pathPart[i] !== url[j]) { | ||
for (let i = 1, j = startIndex + 1; i < pathPart.length; ++i, ++j) { | ||
if (pathPart[i] !== url[j]) { | ||
return null; | ||
} | ||
} | ||
else if (url.slice(startIndex, pathPartEndIndex) !== node.pathPart) | ||
else if (url.slice(startIndex, pathPartEndIndex) !== pathPart) | ||
return null; | ||
@@ -179,0 +180,0 @@ } |
@@ -15,3 +15,3 @@ import type { TSchema } from '@sinclair/typebox'; | ||
hook?: LocalHook<any, import("./types").ElysiaInstance<{ | ||
store: {}; | ||
store: Record<typeof import("./utils").SCHEMA, {}>; | ||
request: {}; | ||
@@ -18,0 +18,0 @@ schema: {}; |
@@ -10,7 +10,7 @@ /// <reference types="bun-types" /> | ||
export interface ElysiaInstance<Instance extends { | ||
store?: Record<any | typeof SCHEMA, any>; | ||
store?: Record<any, any> & Record<typeof SCHEMA, Record<string, Partial<Record<HTTPMethod, TypedSchema>>>>; | ||
request?: Record<any, any>; | ||
schema?: TypedSchema; | ||
} = { | ||
store: {}; | ||
store: Record<typeof SCHEMA, {}>; | ||
request: {}; | ||
@@ -50,3 +50,3 @@ schema: {}; | ||
} | ||
export type BeforeRequestHandler<Store extends Record<string, any> = {}> = (context: PreContext<Store>) => void | Promise<void> | Response | Promise<Response>; | ||
export type BeforeRequestHandler<Store extends ElysiaInstance['store'] = ElysiaInstance['store']> = (context: PreContext<Store>) => void | Promise<void> | Response | Promise<Response>; | ||
export interface RegisteredHook<Instance extends ElysiaInstance = ElysiaInstance> { | ||
@@ -53,0 +53,0 @@ schema?: TypedSchema; |
import { TypeCompiler } from '@sinclair/typebox/compiler'; | ||
// ? Internal property | ||
export const SCHEMA = Symbol('schema'); | ||
@@ -28,3 +29,3 @@ export const mergeObjectArray = (a, b) => [ | ||
export const clone = (value) => [value][0]; | ||
export const getPath = (url, queryIndex) => url.substring(url.charCodeAt(0) === 47 ? 0 : url.indexOf('/', 11), queryIndex === -1 ? url.length : queryIndex); | ||
export const getPath = (url, queryIndex) => url.substring(url.indexOf('/', 11), queryIndex === -1 ? url.length : queryIndex); | ||
export const mapQuery = (url, queryIndex) => { | ||
@@ -31,0 +32,0 @@ if (queryIndex === -1) |
{ | ||
"name": "elysia", | ||
"description": "Fast, and friendly Bun web framework", | ||
"version": "0.1.0-rc.7", | ||
"version": "0.1.0-rc.8", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "saltyAom", |
172806
4784