{"version":3,"sources":["../../../src/validations/index.ts","../../../src/validations/valleyed.ts","../../../src/instance/index.ts","../../../src/errors/equippedError.ts","../../../src/errors/requestError.ts","../../../src/server/types.ts","../../../src/errors/types/validationError.ts","../../../src/instance/hooks.ts","../../../src/instance/settings.ts"],"sourcesContent":["export * from 'valleyed'\nexport * as ve from './valleyed'\nimport { type Pipe, PipeError, type PipeOutput, v } from 'valleyed'\n\nimport { ValidationError } from '../errors'\n\nexport function pipeErrorToValidationError(error: PipeError) {\n\tconst errorsObject = error.messages.reduce<Record<string, { field: string; messages: string[] }>>((acc, { path = '', message }) => {\n\t\tif (acc[path]) acc[path].messages.push(message)\n\t\telse acc[path] = { field: path, messages: [message] }\n\t\treturn acc\n\t}, {})\n\n\treturn new ValidationError(Object.values(errorsObject))\n}\n\nexport function validate<T extends Pipe<unknown, unknown>>(pipe: T, value: unknown): PipeOutput<T> {\n\tconst validity = v.validate(pipe, value)\n\tif (validity.valid) return validity.value\n\tthrow pipeErrorToValidationError(validity.error)\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { type Pipe, PipeError, type PipeInput, type PipeOutput, v } from 'valleyed'\n\nimport { Instance } from '../instance'\nimport type { IncomingFile, Request, Response, RouteDef, RouteDefToReqRes } from '../server'\n\nconst filePipe = (err?: string) =>\n\tv.array(\n\t\tv.file<IncomingFile>(err).pipe((input) => {\n\t\t\tconst err = `is larger than allowed limit of ${Instance.get().settings.utils.maxFileUploadSizeInMb}mb`\n\t\t\tconst valid = input ? !input.isTruncated : true\n\t\t\tif (valid) return input\n\t\t\tthrow PipeError.root(err, input)\n\t\t}),\n\t)\n\nexport const incomingFile = (err?: string) =>\n\tv.define<unknown, IncomingFile>(\n\t\tv.compile(\n\t\t\tfilePipe(err)\n\t\t\t\t.pipe(v.min(1, 'no file provided'))\n\t\t\t\t.pipe((files) => files[0]),\n\t\t),\n\t\t{ schema: () => ({ type: 'string', format: 'binary' }) },\n\t)\n\nexport const incomingFiles = (err?: string) =>\n\tv.define<unknown, IncomingFile[]>(v.compile(filePipe(err)), {\n\t\tschema: () => ({ type: 'string', format: 'binary' }),\n\t})\n\nexport const requestLocalStorage = new AsyncLocalStorage<Request<RouteDefToReqRes<RouteDef>>>()\nexport const responseLocalStorage = new AsyncLocalStorage<Response<RouteDefToReqRes<RouteDef>>>()\n\nexport const withRequest = <T extends Pipe<any, any>>(fn: (req: Request<RouteDefToReqRes<RouteDef>>) => T) =>\n\tv.define<PipeInput<T>, PipeOutput<T>>((input) => {\n\t\tconst req = requestLocalStorage.getStore()\n\t\tif (!req) throw new Error('Request not found in context')\n\t\tconst validated = v.validate(fn(req), input)\n\t\treturn validated.valid ? validated.value : validated.error\n\t})\n\nexport const withResponse = <T extends Pipe<any, any>>(fn: (req: Response<RouteDefToReqRes<RouteDef>>) => T) =>\n\tv.define<PipeInput<T>, PipeOutput<T>>((input) => {\n\t\tconst res = responseLocalStorage.getStore()\n\t\tif (!res) throw new Error('Response not found in context')\n\t\tconst validated = v.validate(fn(res), input)\n\t\treturn validated.valid ? validated.value : validated.error\n\t})\n","import pino, { type Logger } from 'pino'\nimport { ulid } from 'ulid'\nimport { type Pipe, v } from 'valleyed'\n\nimport { EquippedError } from '../errors'\nimport { type ClassRef, type HookCb, type HookEvent, type HookOptions, type HookRecord, registerHook, runHooks } from './hooks'\nimport { instanceSettingsPipe, type Settings, type SettingsInput } from './settings'\n\nexport type { ClassRef, HookCb, HookEvent, HookOptions }\n\nexport class Instance {\n\tstatic #id: string | undefined\n\tstatic #instance: Instance | undefined\n\tstatic #hooks: Partial<Record<HookEvent, HookRecord[]>> = {}\n\treadonly settings: Readonly<Settings>\n\treadonly log: Logger<never>\n\n\tprivate constructor(settings: Settings) {\n\t\tInstance.#instance = this\n\t\tthis.settings = Object.freeze(settings)\n\t\tthis.log = pino<never>({\n\t\t\tlevel: this.settings.log.level,\n\t\t\tserializers: {\n\t\t\t\terr: pino.stdSerializers.err,\n\t\t\t\terror: pino.stdSerializers.err,\n\t\t\t\treq: pino.stdSerializers.req,\n\t\t\t\tres: pino.stdSerializers.res,\n\t\t\t},\n\t\t\tmixin: () => ({\n\t\t\t\tinstanceId: Instance.#id,\n\t\t\t}),\n\t\t})\n\t\tInstance.#registerOnExitHandler()\n\t}\n\n\talias(id: string) {\n\t\tif (Instance.#id !== undefined) return Instance.crash(new EquippedError('Instance already has an alias', {}))\n\t\tInstance.#id = id\n\t}\n\n\tget id() {\n\t\tif (Instance.#id === undefined) return Instance.crash(new EquippedError('Instance doesnt have an alias yet', {}))\n\t\treturn Instance.#id\n\t}\n\n\tgetScopedName(name: string, key = '.') {\n\t\treturn [this.settings.app.name, name].join(key)\n\t}\n\n\tasync start() {\n\t\ttry {\n\t\t\tawait runHooks(Instance.#hooks['setup'] ?? [])\n\t\t\tawait runHooks(Instance.#hooks['start'] ?? [])\n\t\t} catch (error) {\n\t\t\tInstance.crash(new EquippedError(`Error starting instance`, {}, error))\n\t\t}\n\t}\n\n\tstatic envs<E extends object>(envsPipe: Pipe<unknown, E>): E {\n\t\tconst envValidity = v.validate(envsPipe, process.env)\n\t\tif (!envValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Environment variables are not valid\\n${envValidity.error.toString()}`, {\n\t\t\t\t\tmessages: envValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn envValidity.value\n\t}\n\n\tstatic create(settings: SettingsInput) {\n\t\tif (Instance.#instance) return Instance.crash(new EquippedError('Instance has been initialized already', {}))\n\t\tconst settingsValidity = v.validate(instanceSettingsPipe(), settings)\n\t\tif (!settingsValidity.valid) {\n\t\t\tInstance.crash(\n\t\t\t\tnew EquippedError(`Settings are not valid\\n${settingsValidity.error.toString()}`, {\n\t\t\t\t\tmessages: settingsValidity.error.messages,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\treturn new Instance(settingsValidity.value)\n\t}\n\n\tstatic get() {\n\t\tif (!Instance.#instance)\n\t\t\treturn Instance.crash(\n\t\t\t\tnew EquippedError('Has not been initialized. Make sure an instance has been created before you get an instance', {}),\n\t\t\t)\n\t\treturn Instance.#instance\n\t}\n\n\tstatic maybeGet() {\n\t\treturn Instance.#instance\n\t}\n\n\tstatic on(event: HookEvent, cb: HookCb, options?: HookOptions) {\n\t\tInstance.#hooks[event] ??= []\n\t\tconst record: HookRecord = { cb, class: options?.class, after: options?.after ?? [] }\n\t\tregisterHook(Instance.#hooks[event], record)\n\t}\n\n\tstatic #registerOnExitHandler() {\n\t\tconst signals = {\n\t\t\tSIGHUP: 1,\n\t\t\tSIGINT: 2,\n\t\t\tSIGTERM: 15,\n\t\t}\n\n\t\tObject.entries(signals).forEach(([signal, code]) => {\n\t\t\tprocess.on(signal, async () => {\n\t\t\t\tawait runHooks(Instance.#hooks['close'] ?? [], () => {}, true)\n\t\t\t\tprocess.exit(128 + code)\n\t\t\t})\n\t\t})\n\t}\n\n\tstatic resolveBeforeCrash<T>(cb: () => Promise<T>) {\n\t\tconst value = cb()\n\t\tInstance.on('close', async () => await value)\n\t\treturn value\n\t}\n\n\tstatic crash(error: EquippedError): never {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.error(error)\n\t\tprocess.exit(1)\n\t}\n\n\tstatic createId(opts?: { prefix?: string; time?: Date }) {\n\t\treturn `${opts?.prefix ?? ''}${ulid(opts?.time?.getTime())}`\n\t}\n}\n","export class EquippedError extends Error {\n\tconstructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly context: Record<string, unknown>,\n\t\tpublic readonly cause?: unknown,\n\t) {\n\t\tsuper(message, { cause })\n\t}\n}\n","import type { StatusCodesEnum } from '../server'\nimport { EquippedError } from './equippedError'\n\nexport abstract class RequestError extends EquippedError {\n\tabstract readonly statusCode: StatusCodesEnum\n\n\tprotected constructor(\n\t\tpublic readonly message: string,\n\t\tpublic readonly serializedErrors: { message: string; field?: string }[],\n\t\tcause?: unknown,\n\t) {\n\t\tsuper(message, { serializedErrors }, cause)\n\t}\n}\n","import type { IsInTypeList, Pipe, PipeInput, PipeOutput, Prettify } from 'valleyed'\n\nimport type { RequestError } from '../errors'\nimport type { Enum } from '../types'\nimport type { Request, Response } from './requests'\n\nexport const Methods = {\n\thead: 'head',\n\tget: 'get',\n\tpost: 'post',\n\tput: 'put',\n\tpatch: 'patch',\n\tdelete: 'delete',\n\toptions: 'options',\n} as const\n\nexport const StatusCodes = {\n\tOk: 200,\n\tFound: 302,\n\tBadRequest: 400,\n\tNotAuthenticated: 401,\n\tNotAuthorized: 403,\n\tNotFound: 404,\n\tValidationError: 422,\n\tPreconditionRequired: 428,\n\tTooManyRequests: 429,\n\tTokenExpired: 461,\n} as const\n\nexport type MethodsEnum = Enum<typeof Methods>\nexport type StatusCodesEnum = Enum<typeof StatusCodes>\n\nexport type DefaultHeaders = Record<string, ArrayOrValue<string>>\nexport type DefaultCookies = Record<string, string | undefined>\n\ntype ArrayOrValue<T> = T | T[] | undefined\n\nexport type IncomingFile = {\n\tname: string\n\ttype: string\n\tsize: number\n\tisTruncated: boolean\n\tdata: Buffer\n\tduration: number\n}\n\nexport type RouteDef = {\n\tparams?: Pipe<Record<string, ArrayOrValue<string>>, Record<string, ArrayOrValue<string>>>\n\tquery?: Pipe<Record<string, ArrayOrValue<unknown>>, Record<string, ArrayOrValue<unknown>>>\n\theaders?: Pipe<DefaultHeaders, DefaultHeaders>\n\tcookies?: Pipe<DefaultCookies, DefaultCookies>\n\tbody?: Pipe<Record<string, unknown>, Record<string, unknown>>\n\tresponse?: Pipe<unknown, unknown>\n\tresponseHeaders?: Pipe<DefaultHeaders, DefaultHeaders>\n\tresponseCookies?: Pipe<DefaultCookies, DefaultCookies>\n\tdefaultStatusCode?: StatusCodesEnum\n\tdefaultContentType?: string\n}\n\ntype RouteGroup = { name: string; description?: string }\ntype HandlerSetup<T extends RouteDef> = (route: Route<T>) => void\n\nexport type RouteConfig<T extends RouteDef> = {\n\tmiddlewares?: ReturnType<typeof makeMiddleware<RouteDef>>[]\n\tresponseMiddlewares?: ReturnType<typeof makeResponseMiddleware<RouteDef>>[]\n\tonError?: ReturnType<typeof makeErrorMiddleware<RouteDef>>\n\tgroups?: (RouteGroup | RouteGroup['name'])[]\n\ttitle?: string\n\tdescriptions?: string[]\n\tsecurity?: Record<string, string[]>[]\n\tschema?: T\n\thide?: boolean\n}\n\nexport type RouterConfig<T extends RouteDef> = RouteConfig<T> & { path: string }\nexport type Route<T extends RouteDef> = RouteConfig<T> & {\n\tpath: string\n\tmethod: MethodsEnum\n\thandler: RouteDefHandler<T>\n}\n\ntype GetApiPart<T extends RouteDef, K extends keyof RouteDef> = NonNullable<IsInTypeList<T[K], [unknown]> extends true ? RouteDef[K] : T[K]>\n\ntype ArePipes<A, B> = A extends Pipe<any, any> ? (B extends Pipe<any, any> ? true : false) : false\ntype Compare<K extends keyof RouteDef, A, B> =\n\tIsInTypeList<B, [unknown]> extends true\n\t\t? A\n\t\t: IsInTypeList<A, [unknown]> extends true\n\t\t\t? B\n\t\t\t: K extends `default${string}` | 'context'\n\t\t\t\t? B\n\t\t\t\t: ArePipes<A, B> extends true\n\t\t\t\t\t? Pipe<PipeInput<A> & PipeInput<B>, PipeOutput<A> & PipeOutput<B>>\n\t\t\t\t\t: B\n\nexport type MergeRouteDefs<A extends RouteDef, B extends RouteDef> = {\n\t[K in keyof RouteDef]: Compare<K, A[K], B[K]>\n}\n\nexport type RouteDefToReqRes<T extends RouteDef> = Prettify<{\n\tbody: PipeOutput<GetApiPart<T, 'body'>>\n\tparams: PipeOutput<GetApiPart<T, 'params'>>\n\trequestHeaders: PipeOutput<GetApiPart<T, 'headers'>>\n\trequestCookies: PipeOutput<GetApiPart<T, 'cookies'>>\n\tquery: PipeOutput<GetApiPart<T, 'query'>>\n\tresponse: PipeOutput<GetApiPart<T, 'response'>>\n\tresponseHeaders: PipeOutput<GetApiPart<T, 'responseHeaders'>>\n\tresponseCookies: PipeOutput<GetApiPart<T, 'responseCookies'>>\n\tstatusCode: GetApiPart<T, 'defaultStatusCode'>\n\tcontentType: GetApiPart<T, 'defaultContentType'>\n}>\n\ntype Awaitable<T> = Promise<T> | T\ntype Res<T extends RouteDefToReqRes<any>> = Awaitable<\n\tIsInTypeList<T['statusCode'], [StatusCodesEnum, 200]> extends true\n\t\t? IsInTypeList<T['responseHeaders'], [DefaultHeaders]> extends true\n\t\t\t? IsInTypeList<T['responseCookies'], [DefaultCookies]> extends true\n\t\t\t\t? Response<T> | T['response']\n\t\t\t\t: Response<T>\n\t\t\t: Response<T>\n\t\t: Response<T>\n>\nexport type RouteDefHandler<Def extends RouteDef> = (req: Request<RouteDefToReqRes<Def>>) => Res<RouteDefToReqRes<Def>>\ntype RouteMiddlewareHandler<_Def extends RouteDef> = (req: Request<RouteDefToReqRes<RouteDef>>) => Awaitable<void>\ntype RouteResponseMiddlewareHandler<_Def extends RouteDef> = (\n\treq: Request<RouteDefToReqRes<RouteDef>>,\n\tres: Response<RouteDefToReqRes<RouteDef>>,\n) => Awaitable<void>\ntype ErrorHandler<Def extends RouteDef> = (\n\treq: Request<RouteDefToReqRes<Def>>,\n\terr: Error,\n) => Res<\n\tOmit<RouteDefToReqRes<Def>, 'response' | 'statusCode' | 'responseHeaders' | 'responseCookies'> & {\n\t\tresponse: RequestError['serializedErrors']\n\t\tstatusCode: RequestError['statusCode']\n\t\tresponseHeaders: DefaultHeaders\n\t\tresponseCookies: DefaultCookies\n\t}\n>\n\nfunction makeMiddlewareHandler<Cb extends Function, T extends RouteDef>(cb: Cb, onSetup?: HandlerSetup<T>) {\n\treturn { cb, onSetup }\n}\n\nexport const makeMiddleware = <Def extends RouteDef>(...args: Parameters<typeof makeMiddlewareHandler<RouteMiddlewareHandler<Def>, Def>>) =>\n\tmakeMiddlewareHandler(...args)\nexport const makeResponseMiddleware = <Def extends RouteDef>(\n\t...args: Parameters<typeof makeMiddlewareHandler<RouteResponseMiddlewareHandler<Def>, Def>>\n) => makeMiddlewareHandler(...args)\nexport const makeErrorMiddleware = <Def extends RouteDef>(...args: Parameters<typeof makeMiddlewareHandler<ErrorHandler<Def>, Def>>) =>\n\tmakeMiddlewareHandler(...args)\n","import { StatusCodes } from '../../server'\nimport { RequestError } from '../requestError'\n\ntype ValidError = {\n\tmessages: string[]\n\tfield: string\n}\n\nexport class ValidationError extends RequestError {\n\tstatusCode = StatusCodes.ValidationError\n\n\tconstructor(errors: ValidError[], cause?: unknown) {\n\t\tsuper(\n\t\t\t'Unprocessable Entity',\n\t\t\terrors.flatMap(({ field, messages }) => messages.map((message) => ({ message, field }))),\n\t\t\tcause,\n\t\t)\n\t}\n}\n","export type HookEvent = 'setup' | 'start' | 'close'\nexport type HookCb = Promise<unknown | void> | (() => void | unknown | Promise<void | unknown>)\n\nexport type ClassRef = Function & { prototype: unknown; name: string }\nexport type HookOptions = {\n\tclass?: ClassRef\n\tafter?: ClassRef[]\n}\nexport type HookRecord = { cb: HookCb; class?: ClassRef; after: ClassRef[] }\n\nexport function registerHook(hooks: HookRecord[], record: HookRecord): void {\n\tfor (const dep of record.after) {\n\t\tif (!hooks.some((h) => h.class === dep)) {\n\t\t\tconst depName = dep.name || 'unknown'\n\t\t\tconst ownerName = record.class?.name || 'anonymous'\n\t\t\tthrow new Error(`Missing dependency: ${ownerName} declares after: [${depName}], but ${depName} is not registered`)\n\t\t}\n\t}\n\n\tif (record.class) {\n\t\tconst tentative = [...hooks, record]\n\t\tdetectCycle(tentative)\n\t}\n\n\thooks.push(record)\n}\n\nfunction detectCycle(hooks: HookRecord[]): void {\n\tconst classToAfter = new Map<ClassRef, ClassRef[]>()\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tconst existing = classToAfter.get(h.class)\n\t\tif (existing) {\n\t\t\tfor (const dep of h.after) {\n\t\t\t\tif (!existing.includes(dep)) existing.push(dep)\n\t\t\t}\n\t\t} else {\n\t\t\tclassToAfter.set(h.class, [...h.after])\n\t\t}\n\t}\n\n\tconst visited = new Set<ClassRef>()\n\tconst stack = new Set<ClassRef>()\n\n\tfunction visit(cls: ClassRef, path: ClassRef[]): void {\n\t\tif (stack.has(cls)) {\n\t\t\tconst cycleStart = path.indexOf(cls)\n\t\t\tconst cycle = [...path.slice(cycleStart), cls]\n\t\t\tconst names = cycle.map((c) => c.name || 'unknown')\n\t\t\tthrow new Error(`Cycle detected: ${names.join(' → ')}`)\n\t\t}\n\t\tif (visited.has(cls)) return\n\t\tstack.add(cls)\n\t\tpath.push(cls)\n\t\tfor (const dep of classToAfter.get(cls) ?? []) {\n\t\t\tvisit(dep, path)\n\t\t}\n\t\tpath.pop()\n\t\tstack.delete(cls)\n\t\tvisited.add(cls)\n\t}\n\n\tfor (const cls of classToAfter.keys()) {\n\t\tvisit(cls, [])\n\t}\n}\n\nexport type HookLayer = HookRecord[]\n\nexport function resolveHookDAG(hooks: HookRecord[], invert: boolean = false): HookLayer[] {\n\tif (hooks.length === 0) return []\n\n\tconst classToHooks = new Map<ClassRef, HookRecord[]>()\n\tconst anonymous: HookRecord[] = []\n\n\tfor (const h of hooks) {\n\t\tif (h.class) {\n\t\t\tconst list = classToHooks.get(h.class)\n\t\t\tif (list) list.push(h)\n\t\t\telse classToHooks.set(h.class, [h])\n\t\t} else {\n\t\t\tanonymous.push(h)\n\t\t}\n\t}\n\n\tconst classes = [...classToHooks.keys()]\n\n\tconst inDegree = new Map<ClassRef, number>()\n\tconst graph = new Map<ClassRef, ClassRef[]>()\n\n\tfor (const cls of classes) {\n\t\tinDegree.set(cls, 0)\n\t\tgraph.set(cls, [])\n\t}\n\n\tfor (const h of hooks) {\n\t\tif (!h.class) continue\n\t\tfor (const dep of h.after) {\n\t\t\tconst [from, to] = invert ? [h.class, dep] : [dep, h.class]\n\t\t\tconst edges = graph.get(from)!\n\t\t\tif (!edges.includes(to)) {\n\t\t\t\tedges.push(to)\n\t\t\t\tinDegree.set(to, inDegree.get(to)! + 1)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst layers: HookLayer[] = []\n\tlet queue = classes.filter((c) => inDegree.get(c) === 0)\n\n\twhile (queue.length > 0) {\n\t\tconst layer: HookRecord[] = []\n\t\tconst next: ClassRef[] = []\n\n\t\tfor (const cls of queue) {\n\t\t\tlayer.push(...(classToHooks.get(cls) ?? []))\n\t\t}\n\t\tlayers.push(layer)\n\n\t\tfor (const cls of queue) {\n\t\t\tfor (const neighbor of graph.get(cls) ?? []) {\n\t\t\t\tconst d = inDegree.get(neighbor)! - 1\n\t\t\t\tinDegree.set(neighbor, d)\n\t\t\t\tif (d === 0) next.push(neighbor)\n\t\t\t}\n\t\t}\n\n\t\tqueue = next\n\t}\n\n\tif (anonymous.length > 0) {\n\t\tconst anonWithDeps = anonymous.filter((h) => h.after.length > 0)\n\t\tconst anonWithoutDeps = anonymous.filter((h) => h.after.length === 0)\n\n\t\tif (anonWithDeps.length > 0) {\n\t\t\tlet maxLayer = -1\n\t\t\tfor (const h of anonWithDeps) {\n\t\t\t\tfor (const dep of h.after) {\n\t\t\t\t\tconst depLayer = layers.findIndex((l) => l.some((r) => r.class === dep))\n\t\t\t\t\tif (depLayer > maxLayer) maxLayer = depLayer\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst insertAt = maxLayer + 1\n\t\t\tif (insertAt < layers.length) {\n\t\t\t\tlayers[insertAt].push(...anonWithDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithDeps)\n\t\t\t}\n\t\t}\n\n\t\tif (anonWithoutDeps.length > 0) {\n\t\t\tif (layers.length > 0) {\n\t\t\t\tlayers[layers.length - 1].push(...anonWithoutDeps)\n\t\t\t} else {\n\t\t\t\tlayers.push(anonWithoutDeps)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn layers\n}\n\nexport async function runHooks(\n\thooks: HookRecord[],\n\tonError: (error: Error) => void = (error) => {\n\t\tthrow error\n\t},\n\tinvert: boolean = false,\n) {\n\tconst layers = resolveHookDAG(hooks, invert)\n\tfor (const layer of layers)\n\t\tawait Promise.all(\n\t\t\tlayer.map(async (h) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (typeof h.cb === 'function') return await h.cb()\n\t\t\t\t\treturn await h.cb\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn onError(error instanceof Error ? error : new Error(`${error}`))\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n}\n\nif (import.meta.vitest) {\n\tconst { describe, test, expect } = import.meta.vitest\n\n\tclass A {}\n\tclass B {}\n\tclass C {}\n\tclass D {}\n\n\tconst noop = () => {}\n\n\tdescribe('registerHook', () => {\n\t\ttest('registers a hook with no dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\texpect(hooks).toHaveLength(1)\n\t\t})\n\n\t\ttest('throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: B, after: [A] })).toThrow(/Missing dependency.*B.*A/)\n\t\t})\n\n\t\ttest('throws on cycle: A→B→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [B] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('throws on transitive cycle: A→B→C→A', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, class: B, after: [A] })\n\t\t\tregisterHook(hooks, { cb: noop, class: C, after: [B] })\n\t\t\texpect(() => registerHook(hooks, { cb: noop, class: A, after: [C] })).toThrow(/Cycle detected/)\n\t\t})\n\n\t\ttest('allows anonymous hooks with dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\tregisterHook(hooks, { cb: noop, class: A, after: [] })\n\t\t\tregisterHook(hooks, { cb: noop, after: [A] })\n\t\t\texpect(hooks).toHaveLength(2)\n\t\t})\n\n\t\ttest('anonymous hook throws on missing dependency', () => {\n\t\t\tconst hooks: HookRecord[] = []\n\t\t\texpect(() => registerHook(hooks, { cb: noop, after: [A] })).toThrow(/Missing dependency.*anonymous.*A/)\n\t\t})\n\t})\n\n\tdescribe('resolveHookDAG', () => {\n\t\ttest('linear chain: A → B → C', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === C)).toBe(true)\n\t\t})\n\n\t\ttest('fan-out: A → B, A → C (B and C are parallel)', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t\tconst secondClasses = layers[1].map((h) => h.class)\n\t\t\texpect(secondClasses).toContain(B)\n\t\t\texpect(secondClasses).toContain(C)\n\t\t})\n\n\t\ttest('fan-in: B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: B, after: [] },\n\t\t\t\t{ cb: noop, class: C, after: [] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === D)).toBe(true)\n\t\t})\n\n\t\ttest('diamond: A → B, A → C, B → D, C → D', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t\t{ cb: noop, class: D, after: [B, C] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0][0].class).toBe(A)\n\t\t\tconst midClasses = layers[1].map((h) => h.class)\n\t\t\texpect(midClasses).toContain(B)\n\t\t\texpect(midClasses).toContain(C)\n\t\t\texpect(layers[2][0].class).toBe(D)\n\t\t})\n\n\t\ttest('close-event inversion reverses the graph', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(3)\n\t\t\texpect(layers[0].every((h) => h.class === C)).toBe(true)\n\t\t\texpect(layers[1].every((h) => h.class === B)).toBe(true)\n\t\t\texpect(layers[2].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('close inversion: fan-out becomes fan-in', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks, true)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst firstClasses = layers[0].map((h) => h.class)\n\t\t\texpect(firstClasses).toContain(B)\n\t\t\texpect(firstClasses).toContain(C)\n\t\t\texpect(layers[1].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('multiple hooks per class are all in the same layer', () => {\n\t\t\tconst cb1 = () => {}\n\t\t\tconst cb2 = () => {}\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: cb1, class: A, after: [] },\n\t\t\t\t{ cb: cb2, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\texpect(layers[0]).toHaveLength(2)\n\t\t\texpect(layers[0].every((h) => h.class === A)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks without deps run at deepest level', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, after: [] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\texpect(layers).toHaveLength(2)\n\t\t\tconst lastLayer = layers[layers.length - 1]\n\t\t\texpect(lastLayer.some((h) => h.class === undefined)).toBe(true)\n\t\t})\n\n\t\ttest('anonymous hooks with deps run after their dependencies', () => {\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: noop, class: A, after: [] },\n\t\t\t\t{ cb: noop, class: B, after: [A] },\n\t\t\t\t{ cb: noop, class: C, after: [B] },\n\t\t\t\t{ cb: noop, after: [A] },\n\t\t\t]\n\t\t\tconst layers = resolveHookDAG(hooks)\n\t\t\tconst anonLayer = layers.findIndex((l) => l.some((h) => h.class === undefined))\n\t\t\tconst aLayer = layers.findIndex((l) => l.some((h) => h.class === A))\n\t\t\texpect(anonLayer).toBeGreaterThan(aLayer)\n\t\t})\n\n\t\ttest('empty hooks returns empty layers', () => {\n\t\t\texpect(resolveHookDAG([])).toEqual([])\n\t\t})\n\t})\n\n\tdescribe('runHooks', () => {\n\t\ttest('same-depth siblings observably overlap', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('B-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('C-start')\n\t\t\t\t\t\tawait new Promise((r) => setTimeout(r, 20))\n\t\t\t\t\t\tlog.push('C-end')\n\t\t\t\t\t},\n\t\t\t\t\tclass: C,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log[0]).toBe('B-start')\n\t\t\texpect(log[1]).toBe('C-start')\n\t\t})\n\n\t\ttest('different depths run sequentially', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('A')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tcb: async () => {\n\t\t\t\t\t\tlog.push('B')\n\t\t\t\t\t},\n\t\t\t\t\tclass: B,\n\t\t\t\t\tafter: [A],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toEqual(['A', 'B'])\n\t\t})\n\n\t\ttest('close inversion runs hooks in reverse dependency order', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{ cb: async () => log.push('A'), class: A, after: [] },\n\t\t\t\t{ cb: async () => log.push('B'), class: B, after: [A] },\n\t\t\t\t{ cb: async () => log.push('C'), class: C, after: [B] },\n\t\t\t]\n\t\t\tawait runHooks(hooks, undefined, true)\n\t\t\texpect(log).toEqual(['C', 'B', 'A'])\n\t\t})\n\n\t\ttest('errors are routed to onError handler', async () => {\n\t\t\tconst errors: Error[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: () => {\n\t\t\t\t\t\tthrow new Error('boom')\n\t\t\t\t\t},\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks, (e) => {\n\t\t\t\terrors.push(e)\n\t\t\t})\n\t\t\texpect(errors).toHaveLength(1)\n\t\t\texpect(errors[0].message).toBe('boom')\n\t\t})\n\n\t\ttest('raw promise callbacks are awaited', async () => {\n\t\t\tconst log: string[] = []\n\t\t\tconst hooks: HookRecord[] = [\n\t\t\t\t{\n\t\t\t\t\tcb: Promise.resolve().then(() => log.push('resolved')),\n\t\t\t\t\tclass: A,\n\t\t\t\t\tafter: [],\n\t\t\t\t},\n\t\t\t]\n\t\t\tawait runHooks(hooks)\n\t\t\texpect(log).toContain('resolved')\n\t\t})\n\t})\n}\n","import { type ConditionalObjectKeys, type PipeInput, type PipeOutput, v } from 'valleyed'\n\nexport const instanceSettingsPipe = () =>\n\tv.object({\n\t\tapp: v.object({\n\t\t\tname: v.string(),\n\t\t}),\n\t\tlog: v.defaults(\n\t\t\tv.object({\n\t\t\t\tlevel: v.defaults(v.in(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent'] as const), 'info'),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t\tutils: v.defaults(\n\t\t\tv.object({\n\t\t\t\thashSaltRounds: v.defaults(v.number(), 10),\n\t\t\t\tpaginationDefaultLimit: v.defaults(v.number(), 100),\n\t\t\t\tmaxFileUploadSizeInMb: v.defaults(v.number(), 500),\n\t\t\t}),\n\t\t\t{},\n\t\t),\n\t})\n\nexport type Settings = PipeOutput<ReturnType<typeof instanceSettingsPipe>>\nexport type SettingsInput = ConditionalObjectKeys<PipeInput<ReturnType<typeof instanceSettingsPipe>>>\n"],"mappings":"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","names":["validations_exports","__export","pipeErrorToValidationError","validate","valleyed_exports","__toCommonJS","__reExport","valleyed_exports","__export","incomingFile","incomingFiles","requestLocalStorage","responseLocalStorage","withRequest","withResponse","import_node_async_hooks","import_valleyed","import_pino","import_ulid","import_valleyed","EquippedError","message","context","cause","RequestError","EquippedError","message","serializedErrors","cause","StatusCodes","ValidationError","RequestError","StatusCodes","errors","cause","field","messages","message","registerHook","hooks","record","dep","h","depName","ownerName","tentative","detectCycle","classToAfter","existing","visited","stack","visit","cls","path","cycleStart","names","c","resolveHookDAG","invert","classToHooks","anonymous","list","classes","inDegree","graph","from","to","edges","layers","queue","layer","next","neighbor","d","anonWithDeps","anonWithoutDeps","maxLayer","depLayer","l","r","insertAt","runHooks","onError","error","import_valleyed","instanceSettingsPipe","Instance","_Instance","#id","#instance","#hooks","settings","pino","#registerOnExitHandler","id","EquippedError","name","key","runHooks","error","envsPipe","envValidity","settingsValidity","instanceSettingsPipe","event","cb","options","record","registerHook","signal","code","value","opts","filePipe","err","input","Instance","incomingFile","files","incomingFiles","requestLocalStorage","responseLocalStorage","withRequest","fn","req","validated","withResponse","res","import_valleyed","pipeErrorToValidationError","error","errorsObject","acc","path","message","ValidationError","validate","pipe","value","validity"]}