UNPKG

jetpath

Version:

A performance-first cross-runtime API framework without the boilerplate

334 lines (333 loc) 10.5 kB
import { IncomingMessage, Server, ServerResponse } from 'node:http'; import type { _JetPath_paths, v } from './functions.js'; import { type CookieOptions, SchemaBuilder } from './classes.js'; import type { BunFile } from 'bun'; import type Stream from 'node:stream'; export type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never; export interface JetContext<JetData extends { body?: Record<string, any>; params?: Record<string, any>; query?: Record<string, any>; } = { body: {}; params: {}; query: {}; }, JetPluginTypes extends Record<string, unknown>[] = []> { /** * an object you can set values to per request */ state: Record<string, any>; /** * an object you can set values to per request */ plugins: UnionToIntersection<JetPluginTypes[number]> & Record<string, any>; /** * get body params after /? */ /** * get query params after /? */ /** * get route params in /:thing */ params: JetData['params']; /** * websocket socket event class */ connection: jet_socket; /** * reply the request */ request: Request; /** * API status */ code: number; /** * send a stream * @param stream - The stream or file path to send * @param folder - The folder to save the stream to * @param ContentType - The content type of the stream * * PLEASE PROVIDE A VALID FOLDER PATH FOR SECURITY REASONS */ sendStream(stream: Stream | string | BunFile, config?: { folder?: string; ContentType?: string; }): void | never; /** * send a file for download * @param stream - The file path to send * @param folder - The folder to save the stream to * @param ContentType - The content type of the stream * * PLEASE PROVIDE A VALID FOLDER PATH FOR SECURITY REASONS */ download(stream: string | BunFile, config?: { folder?: string; ContentType?: string; }): void; /** * send a direct response * *Only for deno and bun */ sendResponse(response?: Response): void; /** * reply the request */ send(data: unknown, statusCode?: number, ContentType?: string): void; /** * redirect the request */ redirect(url: string): void; /** * get request header values */ get(field: string): string | undefined; /** * set request header values */ set(field: string, value: string): void; /** * Parses the request body */ getCookie(name: string): string | undefined; getCookies(): Record<string, string>; setCookie(name: string, value: string, options: CookieOptions): void; clearCookie(name: string, options: CookieOptions): void; parse(options?: { maxBodySize?: number; contentType?: string; }): Promise<JetData['body']>; parseQuery(): JetData['query']; /** * Upgrade the request to a WebSocket connection */ upgrade(): void | never; /** * get original request */ path: string; payload?: string; _2?: Record<string, string>; _3?: any; _4?: boolean | undefined; _5?: JetRoute | undefined; _6?: Response | false; } export type JetPluginExecutorInitParams = { runtime: { node: boolean; bun: boolean; deno: boolean; }; server: Server<typeof IncomingMessage, typeof ServerResponse>; routesObject: typeof _JetPath_paths; JetPath_app: (req: Request) => Response; }; export type contentType = 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'application/json'; export type methods = 'GET' | 'POST' | 'OPTIONS' | 'DELETE' | 'HEAD' | 'PUT' | 'CONNECT' | 'TRACE' | 'PATCH'; export type allowedMethods = methods[]; export type jetOptions = { /** * edge grabber helps capture defined API functions in an edge environment * and avoids fs system scanning. * @example * ```ts * edgeGrabber: [ * GET_api_users, * POST_api_users, * Middleware_api_users, * ] * ``` */ edgeGrabber?: JetRoute[] & JetMiddleware[]; /** * upgrade the request to a WebSocket connection */ upgrade?: boolean; /** * source of the app */ source?: string; /** * global headers */ globalHeaders?: Record<string, string>; /** * strict mode */ strictMode?: 'ON' | 'OFF' | 'WARN'; /** * generated routes file path * putting the file on the frontend folder will make it accessible * during build time * @default generates nothing */ generatedRoutesFilePath?: string; /** * keep alive timeout */ keepAliveTimeout?: number; /** * api documentation options */ apiDoc?: { display?: 'UI' | 'HTTP' | false; environments?: Record<string, string>; name?: string; info?: string; color?: string; logo?: string; path?: string; password?: string; username?: string; }; /** * credentials options */ credentials?: { cert: string; key: string; }; /** * port */ port?: number; /** * cors options */ cors?: { allowMethods?: allowedMethods; secureContext?: { 'Cross-Origin-Opener-Policy': 'same-origin' | 'unsafe-none' | 'same-origin-allow-popups'; 'Cross-Origin-Embedder-Policy': 'require-corp' | 'unsafe-none'; }; allowHeaders?: string[]; exposeHeaders?: string[]; keepHeadersOnError?: boolean; maxAge?: string; credentials?: boolean; privateNetworkAccess?: any; origin?: string[]; } | boolean; }; export type HTTPBody<Obj extends Record<string, any>> = { [x in keyof Obj]: { err?: string; type?: 'string' | 'number' | 'file' | 'object' | 'boolean' | 'array' | 'date'; arrayType?: 'string' | 'number' | 'file' | 'object' | 'boolean' | 'array' | 'date'; RegExp?: RegExp; inputAccept?: string; inputType?: 'date' | 'email' | 'file' | 'password' | 'number' | 'time' | 'tel' | 'datetime' | 'url'; inputDefaultValue?: string | number | boolean; required?: boolean; validator?: (value: any) => boolean | string; objectSchema?: HTTPBody<Record<string, any>>; }; }; export type Middleware<JetData extends { body?: Record<string, any>; params?: Record<string, any>; query?: Record<string, any>; } = { body: {}; params: {}; query: {}; }, JetPluginTypes extends Record<string, unknown>[] = []> = (ctx: JetContext<JetData, JetPluginTypes>) => void | Promise<void> | ((ctx: JetContext<JetData, JetPluginTypes>, error: unknown) => void | Promise<void>) | Promise<((ctx: JetContext<JetData, JetPluginTypes>, error: unknown) => void | Promise<void>) | undefined> | undefined; export type JetMiddleware<JetData extends { body?: Record<string, any>; params?: Record<string, any>; query?: Record<string, any>; } = { body: {}; params: {}; query: {}; }, JetPluginTypes extends Record<string, unknown>[] = []> = Middleware<JetData, JetPluginTypes> | Middleware<JetData, JetPluginTypes>[]; export type JetRoute<JetData extends { body?: Record<string, any>; params?: Record<string, any>; query?: Record<string, any>; response?: Record<string, any>; } = { body: {}; params: {}; query: {}; response: {}; title: ''; description: ''; method: ''; path: ''; jet_middleware: []; }, JetPluginTypes extends Record<string, unknown>[] = []> = { (ctx: JetContext<JetData, JetPluginTypes>): Promise<void> | void; body?: HTTPBody<JetData['body'] & Record<string, any>>; headers?: Record<string, string>; title?: string; description?: string; method?: string; path?: string; jet_middleware?: Middleware[]; params?: HTTPBody<JetData['params'] & Record<string, any>>; query?: HTTPBody<JetData['query'] & Record<string, any>>; response?: HTTPBody<JetData['response'] & Record<string, any>>; }; interface jet_socket { addEventListener(event: 'message' | 'close' | 'drain' | 'open', listener: (socket: WebSocket, ...params: any[]) => void): void; } export type JetFile = { fileName: string; content: Uint8Array; mimeType: string; }; export type SchemaType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'file'; export interface ValidationOptions { err?: string; RegExp?: RegExp; validator?: (value: any) => boolean | string; inputDefaultValue?: any; required?: boolean; } export interface FileOptions { inputAccept?: string; inputMultiple?: boolean; err?: string; } export interface ArrayOptions extends ValidationOptions { arrayType?: SchemaType | 'object'; objectSchema?: HTTPBody<any>; } export interface ObjectOptions extends ValidationOptions { objectSchema?: HTTPBody<any>; } export type SchemaDefinition = { type: SchemaType; } & ValidationOptions & ArrayOptions & ObjectOptions; export type compilerType<JetData extends { body?: Record<string, any>; params?: Record<string, any>; query?: Record<string, any>; response?: Record<string, any>; }, JetPluginTypes extends Record<string, unknown>[] = []> = { /** * Sets the API body validation and documentation body for the endpoint */ body: (schemaFn: (t: typeof v) => Partial<Record<keyof HTTPBody<NonNullable<JetData['body']>>, SchemaBuilder>>) => compilerType<JetData, JetPluginTypes>; /** * Sets the API body validation and documentation body for the endpoint */ response: (schemaFn: (t: typeof v) => Partial<Record<keyof HTTPBody<NonNullable<JetData['response']>>, SchemaBuilder>>) => compilerType<JetData, JetPluginTypes>; /** * Sets the API documentation query for the endpoint */ query: (schemaFn: (t: typeof v) => Partial<Record<keyof HTTPBody<NonNullable<JetData['query']>>, SchemaBuilder>>) => compilerType<JetData, JetPluginTypes>; /** * Sets the API documentation title for the endpoint */ title: (title: string) => compilerType<JetData, JetPluginTypes>; /** * Sets the API documentation description for the endpoint */ description: (description: string) => compilerType<JetData, JetPluginTypes>; }; export {};