Comparing version 0.2.0-beta.2 to 0.2.0-rc.0
/// <reference types="bun-types" /> | ||
import { Elysia } from '.'; | ||
import type { TypedRoute } from './types'; | ||
type UnwrapFn<T> = T extends (...params: any) => any ? ReturnType<T> : T; | ||
export interface Context<Route extends TypedRoute = TypedRoute, Store extends Elysia['store'] = Elysia['store']> { | ||
request: Request; | ||
query: Route['query'] extends undefined ? Record<string, unknown> : Route['query']; | ||
params: Route['params']; | ||
body: Route['body']; | ||
query: UnwrapFn<Route['query']> extends undefined ? Record<string, unknown> : UnwrapFn<Route['query']>; | ||
params: UnwrapFn<Route['params']>; | ||
body: UnwrapFn<Route['body']>; | ||
store: Store; | ||
@@ -17,1 +18,2 @@ set: { | ||
export type PreContext<Route extends TypedRoute = TypedRoute, Store extends Elysia['store'] = Elysia['store']> = Omit<Context<Route, Store>, 'query' | 'params' | 'body'>; | ||
export {}; |
/// <reference types="bun-types" /> | ||
import type { Serve, Server } from 'bun'; | ||
import { Router } from './router'; | ||
import { SCHEMA } from './utils'; | ||
import { SCHEMA, DEFS } from './utils'; | ||
import type { Context } from './context'; | ||
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, MaybePromise, IsNever } from './types'; | ||
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, MaybePromise, IsNever, InferSchema } from './types'; | ||
import { type TSchema } from '@sinclair/typebox'; | ||
export default class Elysia<Instance extends ElysiaInstance = ElysiaInstance> { | ||
@@ -50,13 +51,13 @@ config: ElysiaConfig; | ||
}>): IsNever<LazyLoadElysia> extends false ? Elysia<LazyLoadElysia & Instance> : NewElysia extends Elysia<infer NewInstance> ? IsNever<NewInstance> extends true ? Elysia<Instance> : Elysia<NewInstance & Instance> : NewElysia extends Promise<Elysia<infer NewInstance>> ? Elysia<NewInstance & Instance> : this; | ||
get<Schema extends TypedSchema = TypedSchema, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'GET', Schema, Instance, Path, Response>; | ||
post<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'POST', Schema, Instance, Path, Response>; | ||
put<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PUT', Schema, Instance, Path, Response>; | ||
patch<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PATCH', Schema, Instance, Path, Response>; | ||
delete<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'DELETE', Schema, Instance, Path, Response>; | ||
options<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'OPTIONS', Schema, Instance, Path, Response>; | ||
all<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'ALL', Schema, Instance, Path, Response>; | ||
head<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'HEAD', Schema, Instance, Path, Response>; | ||
trace<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'TRACE', Schema, Instance, Path, Response>; | ||
connect<Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'CONNECT', Schema, Instance, Path, Response>; | ||
route<Method extends HTTPMethod = HTTPMethod, Schema extends TypedSchema = {}, Path extends string = string, Response = unknown>(method: Method, path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<Method, Schema, Instance, Path, Response>; | ||
get<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'GET', Schema, Instance, Path, Response>; | ||
post<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'POST', Schema, Instance, Path, Response>; | ||
put<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PUT', Schema, Instance, Path, Response>; | ||
patch<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PATCH', Schema, Instance, Path, Response>; | ||
delete<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'DELETE', Schema, Instance, Path, Response>; | ||
options<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'OPTIONS', Schema, Instance, Path, Response>; | ||
all<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'ALL', Schema, Instance, Path, Response>; | ||
head<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'HEAD', Schema, Instance, Path, Response>; | ||
trace<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'TRACE', Schema, Instance, Path, Response>; | ||
connect<Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'CONNECT', Schema, Instance, Path, Response>; | ||
route<Method extends HTTPMethod = HTTPMethod, Schema extends InferSchema<Instance> = InferSchema<Instance>, Path extends string = string, Response = unknown>(method: Method, path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<Method, Schema, Instance, Path, Response>; | ||
state<Key extends string | number | symbol = keyof Instance['store'], Value = Instance['store'][keyof Instance['store']], ReturnValue = Value extends () => infer Returned ? Returned extends Promise<infer AsyncReturned> ? AsyncReturned : Returned : Value, NewInstance = Elysia<{ | ||
@@ -88,3 +89,3 @@ store: Instance['store'] & { | ||
}>; | ||
schema<Schema extends TypedSchema = TypedSchema, NewInstance = Elysia<{ | ||
schema<Schema extends InferSchema<Instance> = InferSchema<Instance>, NewInstance = Elysia<{ | ||
request: Instance['request']; | ||
@@ -99,11 +100,18 @@ store: Instance['store']; | ||
get modules(): Promise<Elysia<ElysiaInstance<{ | ||
store: Record<typeof SCHEMA, {}>; | ||
store: Record<typeof SCHEMA | typeof DEFS, {}>; | ||
request: {}; | ||
schema: {}; | ||
}>>[]>; | ||
setModel<Recorder extends Record<string, TSchema>>(record: Recorder): Elysia<{ | ||
store: Instance['store'] & { | ||
[Defs in typeof DEFS]: Recorder; | ||
}; | ||
request: Instance['request']; | ||
schema: Instance['schema']; | ||
}>; | ||
} | ||
export { Elysia, Router }; | ||
export { Type as t } from '@sinclair/typebox'; | ||
export { SCHEMA, getPath, createValidationError, getSchemaValidator } from './utils'; | ||
export { SCHEMA, DEFS, getPath, createValidationError, getSchemaValidator } from './utils'; | ||
export type { Context, PreContext } from './context'; | ||
export type { Handler, RegisteredHook, BeforeRequestHandler, TypedRoute, OverwritableTypeRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, ComposedHandler, InternalRoute, BodyParser, ErrorHandler, ErrorCode, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, AfterRequestHandler, HookHandler, TypedSchemaToRoute, UnwrapSchema, LifeCycleStore, VoidLifeCycle, SchemaValidator, ElysiaRoute, ExtractPath, IsPathParameter, IsAny, IsNever, UnknownFallback, WithArray, ObjectValues, PickInOrder, MaybePromise, MergeIfNotNull } from './types'; |
import { Router } from './router'; | ||
import { mapResponse, mapEarlyResponse } from './handler'; | ||
import { mapQuery, clone, mergeHook, mergeDeep, createValidationError, SCHEMA, getSchemaValidator } from './utils'; | ||
import { mapQuery, clone, mergeHook, mergeDeep, createValidationError, getSchemaValidator, SCHEMA, DEFS, getResponseSchemaValidator } from './utils'; | ||
import { registerSchemaPath } from './schema'; | ||
@@ -9,3 +9,4 @@ import { mapErrorCode, mapErrorStatus } from './error'; | ||
this.store = { | ||
[SCHEMA]: {} | ||
[SCHEMA]: {}, | ||
[DEFS]: {} | ||
}; | ||
@@ -49,7 +50,8 @@ this.decorators = null; | ||
}); | ||
const body = getSchemaValidator(hook?.schema?.body ?? this.$schema?.body); | ||
const header = getSchemaValidator(hook?.schema?.headers ?? this.$schema?.headers, true); | ||
const params = getSchemaValidator(hook?.schema?.params ?? this.$schema?.params); | ||
const query = getSchemaValidator(hook?.schema?.query ?? this.$schema?.query); | ||
const response = getSchemaValidator(hook?.schema?.response ?? this.$schema?.response); | ||
const defs = this.store[DEFS]; | ||
const body = getSchemaValidator(hook?.schema?.body ?? this.$schema?.body, defs); | ||
const header = getSchemaValidator(hook?.schema?.headers ?? this.$schema?.headers, defs, true); | ||
const params = getSchemaValidator(hook?.schema?.params ?? this.$schema?.params, defs); | ||
const query = getSchemaValidator(hook?.schema?.query ?? this.$schema?.query, defs); | ||
const response = getResponseSchemaValidator(hook?.schema?.response ?? this.$schema?.response, defs); | ||
registerSchemaPath({ | ||
@@ -59,3 +61,4 @@ schema: this.store[SCHEMA], | ||
method, | ||
path | ||
path, | ||
models: this.store[DEFS] | ||
}); | ||
@@ -259,8 +262,9 @@ const validator = body || header || params || query || response | ||
schema(schema) { | ||
const defs = this.store[DEFS]; | ||
this.$schema = { | ||
body: getSchemaValidator(schema?.body), | ||
headers: getSchemaValidator(schema?.headers), | ||
params: getSchemaValidator(schema?.params), | ||
query: getSchemaValidator(schema?.query), | ||
response: getSchemaValidator(schema?.response?.['200'] ?? schema.response) | ||
body: getSchemaValidator(schema.body, defs), | ||
headers: getSchemaValidator(schema?.headers, defs, true), | ||
params: getSchemaValidator(schema?.params, defs), | ||
query: getSchemaValidator(schema?.query, defs), | ||
response: getSchemaValidator(schema?.response, defs) | ||
}; | ||
@@ -459,5 +463,9 @@ return this; | ||
} | ||
setModel(record) { | ||
Object.assign(this.store[DEFS], record); | ||
return this; | ||
} | ||
} | ||
export { Elysia, Router }; | ||
export { Type as t } from '@sinclair/typebox'; | ||
export { SCHEMA, getPath, createValidationError, getSchemaValidator } from './utils'; | ||
export { SCHEMA, DEFS, getPath, createValidationError, getSchemaValidator } from './utils'; |
@@ -1,6 +0,6 @@ | ||
import type { TSchema } from '@sinclair/typebox'; | ||
import { TSchema } from '@sinclair/typebox'; | ||
import type { OpenAPIV2 } from 'openapi-types'; | ||
import type { HTTPMethod, LocalHook } from './types'; | ||
export declare const toOpenAPIPath: (path: string) => string; | ||
export declare const mapProperties: (name: string, schema: TSchema | undefined) => { | ||
export declare const mapProperties: (name: string, schema: TSchema | string | undefined, models: Record<string, TSchema>) => { | ||
in: string; | ||
@@ -11,11 +11,12 @@ name: string; | ||
}[]; | ||
export declare const registerSchemaPath: ({ schema, path, method, hook }: { | ||
export declare const registerSchemaPath: ({ schema, path, method, hook, models }: { | ||
schema: OpenAPIV2.PathsObject; | ||
path: string; | ||
method: HTTPMethod; | ||
hook?: LocalHook<import("./types").TypedSchema, import("./types").ElysiaInstance<{ | ||
store: Record<typeof import("./utils").SCHEMA, {}>; | ||
hook?: LocalHook<import("./types").TypedSchema<string>, import("./types").ElysiaInstance<{ | ||
store: Record<typeof import("./utils").SCHEMA | typeof import("./utils").DEFS, {}>; | ||
request: {}; | ||
schema: {}; | ||
}>, string, import("./types").MergeSchema<import("./types").TypedSchema, {}>> | undefined; | ||
}>, string, import("./types").MergeSchema<import("./types").TypedSchema<string>, {}>> | undefined; | ||
models: Record<string, TSchema>; | ||
}) => void; |
@@ -0,1 +1,2 @@ | ||
import { Kind } from '@sinclair/typebox'; | ||
export const toOpenAPIPath = (path) => path | ||
@@ -5,9 +6,18 @@ .split('/') | ||
.join('/'); | ||
export const mapProperties = (name, schema) => Object.entries(schema?.properties ?? []).map(([key, value]) => ({ | ||
in: name, | ||
name: key, | ||
type: value?.type, | ||
required: schema.required?.includes(key) ?? false | ||
})); | ||
export const registerSchemaPath = ({ schema, path, method, hook }) => { | ||
export const mapProperties = (name, schema, models) => { | ||
if (schema === undefined) | ||
return []; | ||
if (typeof schema === 'string') | ||
if (schema in models) | ||
schema = models[schema]; | ||
else | ||
throw new Error(`Can't find model ${schema}`); | ||
return Object.entries(schema?.properties ?? []).map(([key, value]) => ({ | ||
in: name, | ||
name: key, | ||
type: value?.type, | ||
required: schema.required?.includes(key) ?? false | ||
})); | ||
}; | ||
export const registerSchemaPath = ({ schema, path, method, hook, models }) => { | ||
path = toOpenAPIPath(path); | ||
@@ -18,8 +28,34 @@ const bodySchema = hook?.schema?.body; | ||
const querySchema = hook?.schema?.query; | ||
const responseSchema = hook?.schema?.response; | ||
const detail = hook?.schema?.detail; | ||
let responseSchema = hook?.schema?.response; | ||
if (typeof responseSchema === 'object') { | ||
if (Kind in responseSchema) { | ||
responseSchema = { | ||
'200': { | ||
schema: responseSchema | ||
} | ||
}; | ||
} | ||
else { | ||
Object.entries(responseSchema).forEach(([key, value]) => { | ||
if (typeof value === 'string') | ||
responseSchema[key] = { | ||
schema: { | ||
$ref: `#/definitions/${value}` | ||
} | ||
}; | ||
}); | ||
} | ||
} | ||
else if (typeof responseSchema === 'string') | ||
responseSchema = { | ||
'200': { | ||
schema: { | ||
$ref: `#/definitions/${responseSchema}` | ||
} | ||
} | ||
}; | ||
const parameters = [ | ||
...mapProperties('header', headerSchema), | ||
...mapProperties('path', paramsSchema), | ||
...mapProperties('query', querySchema) | ||
...mapProperties('header', headerSchema, models), | ||
...mapProperties('path', paramsSchema, models), | ||
...mapProperties('query', querySchema, models) | ||
]; | ||
@@ -31,3 +67,7 @@ if (bodySchema) | ||
required: true, | ||
schema: bodySchema | ||
schema: typeof bodySchema === 'string' | ||
? { | ||
$ref: `#/definitions/${bodySchema}` | ||
} | ||
: bodySchema | ||
}); | ||
@@ -42,13 +82,8 @@ schema[path] = { | ||
? { | ||
responses: { | ||
'200': { | ||
description: 'Default response', | ||
schema: responseSchema | ||
} | ||
} | ||
responses: responseSchema | ||
} | ||
: {}), | ||
...detail | ||
...hook?.schema?.detail | ||
} | ||
}; | ||
}; |
@@ -7,3 +7,3 @@ /// <reference types="bun-types" /> | ||
import type { TypeCheck } from '@sinclair/typebox/compiler'; | ||
import type { SCHEMA } from './utils'; | ||
import type { SCHEMA, DEFS } from './utils'; | ||
import type { OpenAPIV2 } from 'openapi-types'; | ||
@@ -13,7 +13,9 @@ export type WithArray<T> = T | T[]; | ||
export interface ElysiaInstance<Instance extends { | ||
store?: Record<any, any> & Record<typeof SCHEMA, Partial<OpenAPIV2.PathsObject>>; | ||
store?: Record<any, any> & Record<typeof SCHEMA, Partial<OpenAPIV2.PathsObject>> & Record<typeof DEFS, { | ||
[x in string]: TSchema; | ||
}>; | ||
request?: Record<any, any>; | ||
schema?: TypedSchema; | ||
} = { | ||
store: Record<typeof SCHEMA, {}>; | ||
store: Record<typeof SCHEMA | typeof DEFS, {}>; | ||
request: {}; | ||
@@ -26,3 +28,3 @@ schema: {}; | ||
} | ||
export type Handler<Route extends TypedRoute = TypedRoute, Instance extends ElysiaInstance = ElysiaInstance, CatchResponse = Route['response']> = (context: Context<Route, Instance['store']> & Instance['request']) => Route['response'] extends CatchResponse ? MaybePromise<CatchResponse> | Response : MaybePromise<Route['response']> | Response; | ||
export type Handler<Route extends TypedRoute = TypedRoute, Instance extends ElysiaInstance = ElysiaInstance, CatchResponse = Route['response']> = (context: Context<Route, Instance['store']> & Instance['request']) => Route['response'] extends (models: Record<string, TSchema>) => TSchema ? ReturnType<Route['response']> extends CatchResponse ? MaybePromise<CatchResponse> | Response : MaybePromise<ReturnType<Route['response']>> | Response : Route['response'] extends CatchResponse ? MaybePromise<CatchResponse> | Response : MaybePromise<Route['response']> | Response; | ||
export type NoReturnHandler<Route extends TypedRoute = TypedRoute, Instance extends ElysiaInstance = ElysiaInstance> = (context: Context<Route, Instance['store']> & Instance['request']) => void | Promise<void>; | ||
@@ -62,18 +64,21 @@ export type LifeCycleEvent = 'start' | 'request' | 'parse' | 'transform' | 'beforeHandle' | 'afterHandle' | 'error' | 'stop'; | ||
} | ||
export interface TypedSchema { | ||
body?: TSchema; | ||
headers?: TObject; | ||
query?: TObject; | ||
params?: TObject; | ||
response?: TSchema | Record<string | '200', TSchema>; | ||
export interface TypedSchema<ModelName extends string = string> { | ||
body?: TSchema | ModelName; | ||
headers?: TObject | ModelName; | ||
query?: TObject | ModelName; | ||
params?: TObject | ModelName; | ||
response?: TSchema | Record<string | '200', TSchema> | ModelName | Record<string, ModelName | TSchema>; | ||
} | ||
export type UnwrapSchema<Schema extends TSchema | undefined, Fallback = unknown> = Schema extends NonNullable<Schema> ? Static<NonNullable<Schema>> : Fallback; | ||
export type TypedSchemaToRoute<Schema extends TypedSchema> = { | ||
body: UnwrapSchema<Schema['body']>; | ||
headers: UnwrapSchema<Schema['headers']> extends infer Result extends Record<string, any> ? Result : undefined; | ||
query: UnwrapSchema<Schema['query']> extends infer Result extends Record<string, any> ? Result : undefined; | ||
params: UnwrapSchema<Schema['params']> extends infer Result extends Record<string, any> ? Result : undefined; | ||
response: Schema['response'] extends TSchema ? UnwrapSchema<Schema['response']> : Schema['response'] extends { | ||
[k in string]: TSchema; | ||
} ? UnwrapSchema<ObjectValues<Schema['response']>> : unknown; | ||
export type InferSchema<Instance extends ElysiaInstance> = TypedSchema<Exclude<keyof Instance['store'][typeof DEFS], number | symbol>>; | ||
export type UnwrapSchema<Schema extends TSchema | undefined | string, Instance extends ElysiaInstance = ElysiaInstance, Fallback = unknown> = Schema extends string ? Instance['store'][typeof DEFS] extends { | ||
[name in Schema]: infer NamedSchema extends TSchema; | ||
} ? UnwrapSchema<NamedSchema> : keyof Instance['store'][typeof DEFS] : NonNullable<Schema> extends TSchema ? Static<NonNullable<Schema>> : Fallback; | ||
export type TypedSchemaToRoute<Schema extends TypedSchema, Instance extends ElysiaInstance> = { | ||
body: UnwrapSchema<Schema['body'], Instance>; | ||
headers: UnwrapSchema<Schema['headers'], Instance> extends infer Result extends Record<string, any> ? Result : undefined; | ||
query: UnwrapSchema<Schema['query'], Instance> extends infer Result extends Record<string, any> ? Result : undefined; | ||
params: UnwrapSchema<Schema['params'], Instance> extends infer Result extends Record<string, any> ? Result : undefined; | ||
response: Schema['response'] extends TSchema | string ? UnwrapSchema<Schema['response'], Instance> : Schema['response'] extends { | ||
[k in string]: TSchema | string; | ||
} ? UnwrapSchema<ObjectValues<Schema['response']>, Instance> : unknown; | ||
}; | ||
@@ -87,3 +92,3 @@ export type SchemaValidator = { | ||
}; | ||
export type HookHandler<Schema extends TypedSchema = TypedSchema, Instance extends ElysiaInstance = ElysiaInstance, Path extends string = string, Typed extends TypedSchemaToRoute<Schema> = TypedSchemaToRoute<Schema>> = Handler<Typed['params'] extends {} ? Omit<Typed, 'response'> & { | ||
export type HookHandler<Schema extends TypedSchema = TypedSchema, Instance extends ElysiaInstance = ElysiaInstance, Path extends string = string, Typed extends TypedSchemaToRoute<Schema, Instance> = TypedSchemaToRoute<Schema, Instance>> = Handler<Typed['params'] extends {} ? Omit<Typed, 'response'> & { | ||
response: void | Typed['response']; | ||
@@ -114,3 +119,3 @@ } : Omit<Omit<Typed, 'response'> & { | ||
} | ||
export type RouteToSchema<Schema extends TypedSchema = TypedSchema, Instance extends ElysiaInstance<any> = ElysiaInstance, Path extends string = string, FinalSchema extends MergeSchema<Schema, Instance['schema']> = MergeSchema<Schema, Instance['schema']>> = FinalSchema['params'] extends NonNullable<Schema['params']> ? TypedSchemaToRoute<FinalSchema> : Omit<TypedSchemaToRoute<FinalSchema>, 'params'> & { | ||
export type RouteToSchema<Schema extends TypedSchema = TypedSchema, Instance extends ElysiaInstance<any> = ElysiaInstance, Path extends string = string, FinalSchema extends MergeSchema<Schema, Instance['schema']> = MergeSchema<Schema, Instance['schema']>> = FinalSchema['params'] extends NonNullable<Schema['params']> ? TypedSchemaToRoute<FinalSchema, Instance> : Omit<TypedSchemaToRoute<FinalSchema, Instance>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string>; | ||
@@ -117,0 +122,0 @@ }; |
@@ -0,5 +1,6 @@ | ||
import { TSchema } from '@sinclair/typebox'; | ||
import { TypeCheck } from '@sinclair/typebox/compiler'; | ||
import type { TSchema } from '@sinclair/typebox'; | ||
import type { DeepMergeTwoTypes, LifeCycleStore, LocalHook, RegisteredHook } from './types'; | ||
import type { DeepMergeTwoTypes, LifeCycleStore, LocalHook, TypedSchema, RegisteredHook } from './types'; | ||
export declare const SCHEMA: unique symbol; | ||
export declare const DEFS: unique symbol; | ||
export declare const mergeObjectArray: <T>(a: T | T[], b: T | T[]) => T[]; | ||
@@ -12,2 +13,3 @@ export declare const mergeHook: (a: LocalHook<any> | LifeCycleStore<any>, b: LocalHook<any>) => RegisteredHook<any>; | ||
export declare const createValidationError: (type: string, validator: TypeCheck<any>, value: any) => Error; | ||
export declare const getSchemaValidator: <Schema extends TSchema | undefined = undefined>(schema: Schema, additionalProperties?: boolean) => TypeCheck<NonNullable<Schema>> | undefined; | ||
export declare const getSchemaValidator: (s: TSchema | string | undefined, models: Record<string, TSchema>, additionalProperties?: boolean) => TypeCheck<TSchema> | undefined; | ||
export declare const getResponseSchemaValidator: (s: TypedSchema['response'] | undefined, models: Record<string, TSchema>, additionalProperties?: boolean) => TypeCheck<TSchema> | undefined; |
@@ -0,3 +1,5 @@ | ||
import { Kind, Type } from '@sinclair/typebox'; | ||
import { TypeCompiler } from '@sinclair/typebox/compiler'; | ||
export const SCHEMA = Symbol('schema'); | ||
export const DEFS = Symbol('definitions'); | ||
export const mergeObjectArray = (a, b) => [ | ||
@@ -92,5 +94,8 @@ ...(Array.isArray(a) ? a : [a]), | ||
}; | ||
export const getSchemaValidator = (schema, additionalProperties = false) => { | ||
if (!schema) | ||
export const getSchemaValidator = (s, models, additionalProperties = false) => { | ||
if (!s) | ||
return; | ||
if (typeof s === 'string' && !(s in models)) | ||
return; | ||
const schema = typeof s === 'string' ? models[s] : s; | ||
if (schema.type === 'object' && 'additionalProperties' in schema === false) | ||
@@ -100,1 +105,26 @@ schema.additionalProperties = additionalProperties; | ||
}; | ||
export const getResponseSchemaValidator = (s, models, additionalProperties = false) => { | ||
if (!s) | ||
return; | ||
if (typeof s === 'string' && !(s in models)) | ||
return; | ||
const maybeSchemaOrRecord = typeof s === 'string' ? models[s] : s; | ||
const schema = Kind in maybeSchemaOrRecord | ||
? maybeSchemaOrRecord | ||
: Type.Union(Object.keys(maybeSchemaOrRecord) | ||
.map((key) => { | ||
const maybeNameOrSchema = maybeSchemaOrRecord[key]; | ||
if (typeof maybeNameOrSchema === 'string') { | ||
if (maybeNameOrSchema in models) { | ||
const schema = models[maybeNameOrSchema]; | ||
return schema; | ||
} | ||
return undefined; | ||
} | ||
return maybeNameOrSchema; | ||
}) | ||
.filter((a) => a)); | ||
if (schema.type === 'object' && 'additionalProperties' in schema === false) | ||
schema.additionalProperties = additionalProperties; | ||
return TypeCompiler.Compile(schema); | ||
}; |
{ | ||
"name": "elysia", | ||
"description": "Fast, and friendly Bun web framework", | ||
"version": "0.2.0-beta.2", | ||
"version": "0.2.0-rc.0", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "saltyAom", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
69125
1471