@kosmojs/api 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@kosmojs/api",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.10",
|
|
5
5
|
"author": "Slee Woo",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"publishConfig": {
|
|
@@ -29,22 +29,21 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@koa/router": "^
|
|
32
|
+
"@koa/router": "^15.0.0",
|
|
33
33
|
"formidable": "^3.5.4",
|
|
34
34
|
"koa": "^3.1.1",
|
|
35
35
|
"picomatch": "^4.0.3",
|
|
36
36
|
"qs": "^6.14.0",
|
|
37
|
-
"raw-body": "^3.0.
|
|
37
|
+
"raw-body": "^3.0.2",
|
|
38
38
|
"string-width": "^8.1.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/formidable": "^3.4.6",
|
|
42
42
|
"@types/koa": "^3.0.1",
|
|
43
|
-
"@types/koa__router": "^12.0.5",
|
|
44
43
|
"@types/picomatch": "^4.0.2",
|
|
45
44
|
"@types/qs": "^6.14.0",
|
|
46
|
-
"@kosmojs/config": "^0.0.
|
|
47
|
-
"@kosmojs/devlib": "^0.0.
|
|
45
|
+
"@kosmojs/config": "^0.0.10",
|
|
46
|
+
"@kosmojs/devlib": "^0.0.10"
|
|
48
47
|
},
|
|
49
48
|
"scripts": {
|
|
50
49
|
"build": "esbuilder src/index.ts src/bodyparser/index.ts src/queryparser/index.ts src/debug.ts",
|
package/pkg/index.js
CHANGED
|
@@ -128,23 +128,14 @@ var routerRoutesFactory = (routeSources, {
|
|
|
128
128
|
// Response validation
|
|
129
129
|
];
|
|
130
130
|
const stack = [];
|
|
131
|
-
for (const
|
|
132
|
-
const
|
|
133
|
-
name,
|
|
134
|
-
path,
|
|
135
|
-
file,
|
|
136
|
-
definitionItems,
|
|
137
|
-
// Includes both middleware and HTTP method handlers
|
|
138
|
-
params,
|
|
139
|
-
numericParams,
|
|
140
|
-
validationSchemas
|
|
141
|
-
} = route;
|
|
131
|
+
for (const { name, path, file, ...rest } of routeSources) {
|
|
132
|
+
const definitionItems = [...rest.useWrappers, ...rest.definitionItems];
|
|
142
133
|
const routeMiddleware = definitionItems.filter(
|
|
143
134
|
(e) => e.kind === "middleware"
|
|
144
135
|
);
|
|
145
136
|
const middlewareStack = [
|
|
146
|
-
...paramsMiddlewareFactory(params, numericParams),
|
|
147
|
-
...validationMiddlewareFactory(validationSchemas),
|
|
137
|
+
...paramsMiddlewareFactory(rest.params, rest.numericParams),
|
|
138
|
+
...validationMiddlewareFactory(rest.validationSchemas),
|
|
148
139
|
// core middleware overrides builtin middleware (of same slot)
|
|
149
140
|
...coreMiddleware,
|
|
150
141
|
// route middleware overrides core middleware (of same slot)
|
package/pkg/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/app.ts", "../src/errors.ts", "../src/router.ts", "../src/types.ts", "../src/use.ts"],
|
|
4
|
-
"sourcesContent": ["import Koa from \"koa\";\n\nimport withQueryparser from \"@kosmojs/api/queryparser\";\n\nimport type { CreateApp } from \"./types\";\n\nexport const createApp: CreateApp = (options) => {\n return withQueryparser(new Koa(options));\n};\n", "import type {\n ValidationErrorData,\n ValidationErrorEntry,\n ValidationErrorScope,\n} from \"./types\";\n\n/**\n * Standardized error wrapper used by validation generators.\n *\n * Instances of this class are thrown whenever validation fails,\n * carrying both the error scope (e.g. `\"params\"`, `\"payload\"`)\n * and the list of validation error details.\n */\nexport class ValidationError extends Error {\n public scope: ValidationErrorScope;\n public errors: Array<ValidationErrorEntry> = [];\n public errorMessage: string;\n public errorSummary: string;\n\n constructor([scope, { errors, errorMessage, errorSummary }]: [\n ValidationErrorScope,\n ValidationErrorData,\n ]) {\n super(JSON.stringify(errors, null, 2));\n this.name = `${scope}ValidationError`;\n this.scope = scope;\n this.errors = errors;\n this.errorMessage = errorMessage;\n this.errorSummary = errorSummary;\n }\n}\n", "import Router from \"@koa/router\";\n\nimport {\n type CreateRouter,\n type DefineRoute,\n type HandlerDefinition,\n HTTPMethods,\n type MiddlewareDefinition,\n type RouterRoute,\n type RouterRouteSource,\n type UseSlots,\n type ValidationSchemas,\n} from \"./types\";\nimport { use } from \"./use\";\n\nexport const createRouter: CreateRouter = (options) => {\n return new Router(options);\n};\n\nexport const defineRoute: DefineRoute = (factory) => {\n return factory({\n use(middleware, options) {\n return {\n kind: \"middleware\",\n middleware: [middleware as never].flat(),\n options,\n };\n },\n HEAD(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"HEAD\",\n };\n },\n OPTIONS(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"OPTIONS\",\n };\n },\n GET(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"GET\",\n };\n },\n POST(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"POST\",\n };\n },\n PUT(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"PUT\",\n };\n },\n PATCH(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"PATCH\",\n };\n },\n DELETE(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"DELETE\",\n };\n },\n });\n};\n\nexport const routerRoutesFactory = (\n routeSources: Array<RouterRouteSource>,\n {\n // Global middleware applied to every route (e.g., logging)\n coreMiddleware,\n }: {\n coreMiddleware: Array<MiddlewareDefinition>;\n },\n) => {\n // WARN:: prioritized middleware must run in this exact order!\n const prioritizedSlots: Array<keyof UseSlots> = [\n \"params\", // Path params processing\n \"validateParams\", // Path params validation\n \"bodyparser\", // Raw request body parsing\n \"payload\", // Set ctx.payload\n \"validatePayload\", // Payload validation\n \"validateResponse\", // Response validation\n ];\n\n const stack: Array<RouterRoute> = [];\n\n // Iterate over each route definition\n for (const route of routeSources) {\n const {\n name,\n path,\n file,\n definitionItems, // Includes both middleware and HTTP method handlers\n params,\n numericParams,\n validationSchemas,\n } = route;\n\n const routeMiddleware: Array<MiddlewareDefinition> = definitionItems.filter(\n (e) => e.kind === \"middleware\",\n );\n\n // WARN: the order is critical!\n // the last defined middleware will take precedence.\n const middlewareStack: Array<MiddlewareDefinition> = [\n ...paramsMiddlewareFactory(params, numericParams),\n ...validationMiddlewareFactory(validationSchemas),\n // core middleware overrides builtin middleware (of same slot)\n ...coreMiddleware,\n // route middleware overrides core middleware (of same slot)\n ...routeMiddleware,\n ];\n\n const routeStack: Array<MiddlewareDefinition | HandlerDefinition> = [\n ...prioritizedSlots.flatMap((slot) => {\n const middleware = middlewareStack.findLast(\n // Using findLast to pick the latest entry,\n // ensuring later entries override earlier ones.\n (e) => e.options?.slot === slot,\n );\n return middleware //\n ? [middleware]\n : [];\n }),\n\n ...coreMiddleware.flatMap((entry) => {\n if (!entry.options?.slot) {\n // no slot, including regardless\n return [entry];\n }\n if (prioritizedSlots.includes(entry.options?.slot)) {\n // already picked when inserted prioritized middleware, excluding\n return [];\n }\n const override = routeMiddleware.findLast(\n // Using findLast to pick the latest entry,\n // ensuring later entries override earlier ones.\n (e) => e.options?.slot === entry.options?.slot,\n );\n return [override || entry];\n }),\n\n ...definitionItems.flatMap((entry) => {\n const slot =\n entry.kind === \"middleware\" //\n ? entry.options?.slot\n : undefined;\n\n if (slot) {\n if (prioritizedSlots.includes(slot)) {\n // already picked when inserted prioritized middleware, excluding\n return [];\n }\n if (coreMiddleware.some((e) => e.options?.slot === slot)) {\n // already picked when inserted core middleware, excluding\n return [];\n }\n }\n\n return [entry];\n }),\n ];\n\n for (const entry of routeStack) {\n if (entry.kind === \"middleware\") {\n stack.push({\n name,\n path,\n file,\n methods: entry.options?.on || Object.keys(HTTPMethods),\n middleware: entry.middleware,\n kind: entry.kind,\n slot: entry.options?.slot,\n debug: entry.options?.debug,\n });\n } else if (entry.kind === \"handler\") {\n stack.push({\n name,\n path,\n file,\n methods: [entry.method],\n middleware: entry.middleware,\n kind: entry.kind,\n });\n }\n }\n }\n\n return stack;\n};\n\nconst paramsMiddlewareFactory = (\n params: RouterRouteSource[\"params\"],\n numericParams: RouterRouteSource[\"numericParams\"],\n) => [\n use(\n (ctx, next) => {\n ctx.typedParams = params.reduce(\n (map: Record<string, unknown>, [name, isRest]) => {\n const value = ctx.params[name];\n if (value) {\n if (isRest) {\n map[name] = numericParams.includes(name)\n ? value.split(\"/\").map(Number)\n : value.split(\"/\");\n } else {\n map[name] = numericParams.includes(name) ? Number(value) : value;\n }\n } else {\n map[name] = value;\n }\n return map;\n },\n {},\n ) as never;\n return next();\n },\n { slot: \"params\" },\n ),\n];\n\nconst validationMiddlewareFactory = (validationSchemas: ValidationSchemas) => [\n use(\n (ctx, next) => {\n validationSchemas.params?.validate(ctx.typedParams);\n return next();\n },\n { slot: \"validateParams\" },\n ),\n\n use(\n (ctx, next) => {\n validationSchemas.payload?.[ctx.method]?.validate(ctx.payload);\n return next();\n },\n {\n slot: \"validatePayload\",\n on: Object.keys(validationSchemas.payload || {}) as never,\n },\n ),\n\n use(\n async (ctx, next) => {\n if (validationSchemas.response?.[ctx.method]) {\n await next();\n validationSchemas.response?.[ctx.method]?.validate(ctx.body);\n } else {\n return next();\n }\n },\n {\n slot: \"validateResponse\",\n on: Object.keys(validationSchemas.response || {}) as never,\n },\n ),\n];\n", "import type {\n Middleware,\n RouterOptions,\n RouterParamContext,\n} from \"@koa/router\";\nimport type { Next } from \"koa\";\n\ndeclare module \"koa\" {\n interface Request {\n body?: unknown;\n rawBody: string;\n }\n}\n\nexport interface DefaultState {}\nexport interface DefaultContext {}\n\nexport enum HTTPMethods {\n HEAD = \"HEAD\",\n OPTIONS = \"OPTIONS\",\n GET = \"GET\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n POST = \"POST\",\n DELETE = \"DELETE\",\n}\n\nexport type { Middleware };\n\nexport type HTTPMethod = keyof typeof HTTPMethods;\n\nexport type ParameterizedContext<\n ParamsT,\n StateT,\n ContextT,\n PayloadT = unknown,\n ResponseT = unknown,\n> = import(\"koa\").ParameterizedContext<\n DefaultState & StateT,\n RouterParamContext<StateT, ContextT> &\n DefaultContext &\n ContextT & {\n typedParams: ParamsT;\n payload: PayloadT;\n },\n ResponseT\n>;\n\ntype RouteMiddleware<ParamsT, StateT, ContextT> = (\n ctx: ParameterizedContext<ParamsT, StateT, ContextT>,\n next: Next,\n) => Promise<void> | void;\n\nexport type RouteHandler<\n ParamsT,\n StateT,\n ContextT,\n PayloadT = unknown,\n ResponseT = unknown,\n> = (\n ctx: ParameterizedContext<ParamsT, StateT, ContextT, PayloadT, ResponseT>,\n next: Next,\n) => Promise<void> | void;\n\nexport type MiddlewareDefinition = {\n kind: \"middleware\";\n middleware: Array<Middleware>;\n options?: UseOptions | undefined;\n};\n\nexport type HandlerDefinition = {\n kind: \"handler\";\n middleware: Array<Middleware>;\n method: HTTPMethod;\n};\n\nexport type RouteDefinitionItem = MiddlewareDefinition | HandlerDefinition;\n\nexport type DefineRouteHelpers<\n ParamsT,\n StateT,\n ContextT,\n OptionalHandlers = undefined,\n> = {\n // INFO: The `use` helper intentionally does not accept type parameters.\n // PayloadT and ResponseT are only relevant to route handlers,\n // as different request methods receive different payloads and return different responses.\n // Allowing these type parameters on `use` would be misleading,\n // since middleware operates across multiple request methods with varying types.\n use: (\n middleware:\n | RouteMiddleware<ParamsT, StateT, ContextT>\n | Array<RouteMiddleware<ParamsT, StateT, ContextT>>,\n options?: UseOptions,\n ) => RouteDefinitionItem;\n} & {\n [M in HTTPMethod]: M extends OptionalHandlers\n ? <PayloadT = unknown, ResponseT = unknown>(\n handler?:\n | RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>\n | Array<RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>>,\n ) => RouteDefinitionItem\n : <PayloadT = unknown, ResponseT = unknown>(\n handler:\n | RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>\n | Array<RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>>,\n ) => RouteDefinitionItem;\n};\n\nexport type DefineRoute = <\n ParamsT = Record<string, string>,\n StateT = object,\n ContextT = object,\n>(\n factory: (\n helpers: DefineRouteHelpers<ParamsT, StateT, ContextT>,\n ) => Array<RouteDefinitionItem>,\n) => Array<RouteDefinitionItem>;\n\nexport interface UseSlots {\n params: string;\n validateParams: string;\n bodyparser: string;\n payload: string;\n validatePayload: string;\n validateResponse: string;\n}\n\nexport type UseOptions = {\n on?: Array<HTTPMethod>;\n slot?: keyof UseSlots;\n debug?: string | undefined;\n};\n\nexport type Use = <StateT = DefaultState, ContextT = DefaultContext>(\n middleware:\n | RouteMiddleware<Record<string, string>, StateT, ContextT>\n | Array<RouteMiddleware<Record<string, string>, StateT, ContextT>>,\n options?: UseOptions,\n) => MiddlewareDefinition;\n\nexport type RouterRouteSource = {\n name: string;\n path: string;\n file: string;\n definitionItems: Array<RouteDefinitionItem>;\n params: Array<[name: string, isRest?: boolean]>;\n numericParams: Array<string>;\n validationSchemas: ValidationSchemas;\n meta?: Record<string, unknown>;\n};\n\nexport type RouterRoute = {\n name: string;\n path: string;\n file: string;\n methods: Array<string>;\n middleware: Array<Middleware>;\n kind: \"middleware\" | \"handler\";\n slot?: keyof UseSlots | undefined;\n debug?: string | undefined;\n};\n\nimport type Koa from \"koa\";\nexport type App = Koa<DefaultState, DefaultContext>;\nexport type AppOptions = ConstructorParameters<typeof import(\"koa\")>[0];\nexport type CreateApp = (options?: AppOptions) => App;\n\nimport type KoaRouter from \"@koa/router\";\nexport type Router = KoaRouter<DefaultState, DefaultContext>;\nexport type { RouterOptions };\nexport type CreateRouter = (options?: RouterOptions) => Router;\n\nexport type DevMiddlewareFactory = (\n app: App,\n) => (\n req: import(\"node:http\").IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n next: () => Promise<void>,\n) => Promise<void>;\nexport type TeardownHandler = (app: App) => void | Promise<void>;\n\nexport type ValidationSchema = {\n check: (data: unknown) => boolean;\n errors: (data: unknown) => Array<ValidationErrorEntry>;\n errorMessage: (data: unknown) => string;\n errorSummary: (data: unknown) => string;\n validate: (data: unknown) => void;\n};\n\nexport type ValidationSchemas<Extend = object> = {\n params?: ValidationSchema & Extend;\n payload?: Record<string, ValidationSchema & Extend>;\n response?: Record<string, ValidationSchema & Extend>;\n};\n\nexport type ValidationErrorScope = \"params\" | \"payload\" | \"response\";\n\n/**\n * Shape of individual validation errors emitted by generators.\n */\nexport type ValidationErrorEntry = {\n /** JSON Schema keyword that triggered the error (e.g. `format`, `maxItems`, `maxLength`). */\n keyword: string;\n /** JSON Pointer\u2013style path to the invalid field (matches JSON Schema `instancePath`). */\n path: string;\n /** Human-readable error message. */\n message: string;\n /** Constraint parameters (e.g. `{ limit: 5 }`, `{ format: \"email\" }`). */\n params?: Record<string, unknown>;\n /** Optional error code for i18n/l10n or custom handling. */\n code?: string;\n};\n\nexport type ValidationErrorData = {\n errors: Array<ValidationErrorEntry>;\n /**\n * Formats errors into a single human-readable message.\n * @example: Validation failed: user: missing required properties: \"email\", \"name\"; password: must be at least 8 characters long\n */\n errorMessage: string;\n /**\n * Gets a simple error summary for quick feedback.\n * @example: 2 validation errors found across 2 fields\n */\n errorSummary: string;\n};\n", "import type { Use } from \"./types\";\n\nexport const use: Use = (middleware, options) => {\n return {\n kind: \"middleware\",\n middleware: [middleware].flat() as never,\n options,\n };\n};\n"],
|
|
5
|
-
"mappings": ";AAAA,OAAO,SAAS;AAEhB,OAAO,qBAAqB;AAIrB,IAAM,YAAuB,CAAC,YAAY;AAC/C,SAAO,gBAAgB,IAAI,IAAI,OAAO,CAAC;AACzC;;;ACKO,IAAM,kBAAN,cAA8B,MAAM;AAAA,EAClC;AAAA,EACA,SAAsC,CAAC;AAAA,EACvC;AAAA,EACA;AAAA,EAEP,YAAY,CAAC,OAAO,EAAE,QAAQ,cAAc,aAAa,CAAC,GAGvD;AACD,UAAM,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AACrC,SAAK,OAAO,GAAG,KAAK;AACpB,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,eAAe;AACpB,SAAK,eAAe;AAAA,EACtB;AACF;;;AC9BA,OAAO,YAAY;;;ACiBZ,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,SAAM;AACN,EAAAA,aAAA,SAAM;AACN,EAAAA,aAAA,WAAQ;AACR,EAAAA,aAAA,UAAO;AACP,EAAAA,aAAA,YAAS;AAPC,SAAAA;AAAA,GAAA;;;ACfL,IAAM,MAAW,CAAC,YAAY,YAAY;AAC/C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY,CAAC,UAAU,EAAE,KAAK;AAAA,IAC9B;AAAA,EACF;AACF;;;AFOO,IAAM,eAA6B,CAAC,YAAY;AACrD,SAAO,IAAI,OAAO,OAAO;AAC3B;AAEO,IAAM,cAA2B,CAAC,YAAY;AACnD,SAAO,QAAQ;AAAA,IACb,IAAI,YAAY,SAAS;AACvB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,QAAQ,YAAY;AAClB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,IAAI,YAAY;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,IAAI,YAAY;AACd,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,MAAM,YAAY;AAChB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,OAAO,YAAY;AACjB,aAAO;AAAA,QACL,MAAM;AAAA,QACN,YAAY,CAAC,UAAmB,EAAE,KAAK;AAAA,QACvC,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,IAAM,sBAAsB,CACjC,cACA;AAAA;AAAA,EAEE;AACF,MAGG;AAEH,QAAM,mBAA0C;AAAA,IAC9C;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,QAAM,QAA4B,CAAC;AAGnC,aAAW,
|
|
4
|
+
"sourcesContent": ["import Koa from \"koa\";\n\nimport withQueryparser from \"@kosmojs/api/queryparser\";\n\nimport type { CreateApp } from \"./types\";\n\nexport const createApp: CreateApp = (options) => {\n return withQueryparser(new Koa(options));\n};\n", "import type {\n ValidationErrorData,\n ValidationErrorEntry,\n ValidationErrorScope,\n} from \"./types\";\n\n/**\n * Standardized error wrapper used by validation generators.\n *\n * Instances of this class are thrown whenever validation fails,\n * carrying both the error scope (e.g. `\"params\"`, `\"payload\"`)\n * and the list of validation error details.\n */\nexport class ValidationError extends Error {\n public scope: ValidationErrorScope;\n public errors: Array<ValidationErrorEntry> = [];\n public errorMessage: string;\n public errorSummary: string;\n\n constructor([scope, { errors, errorMessage, errorSummary }]: [\n ValidationErrorScope,\n ValidationErrorData,\n ]) {\n super(JSON.stringify(errors, null, 2));\n this.name = `${scope}ValidationError`;\n this.scope = scope;\n this.errors = errors;\n this.errorMessage = errorMessage;\n this.errorSummary = errorSummary;\n }\n}\n", "import Router from \"@koa/router\";\n\nimport {\n type CreateRouter,\n type DefineRoute,\n type HandlerDefinition,\n HTTPMethods,\n type MiddlewareDefinition,\n type RouterRoute,\n type RouterRouteSource,\n type UseSlots,\n type ValidationSchemas,\n} from \"./types\";\nimport { use } from \"./use\";\n\nexport const createRouter: CreateRouter = (options) => {\n return new Router(options);\n};\n\nexport const defineRoute: DefineRoute = (factory) => {\n return factory({\n use(middleware, options) {\n return {\n kind: \"middleware\",\n middleware: [middleware as never].flat(),\n options,\n };\n },\n HEAD(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"HEAD\",\n };\n },\n OPTIONS(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"OPTIONS\",\n };\n },\n GET(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"GET\",\n };\n },\n POST(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"POST\",\n };\n },\n PUT(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"PUT\",\n };\n },\n PATCH(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"PATCH\",\n };\n },\n DELETE(middleware) {\n return {\n kind: \"handler\",\n middleware: [middleware as never].flat(),\n method: \"DELETE\",\n };\n },\n });\n};\n\nexport const routerRoutesFactory = (\n routeSources: Array<RouterRouteSource>,\n {\n // Global middleware applied to every route (e.g., logging)\n coreMiddleware,\n }: {\n coreMiddleware: Array<MiddlewareDefinition>;\n },\n) => {\n // WARN:: prioritized middleware must run in this exact order!\n const prioritizedSlots: Array<keyof UseSlots> = [\n \"params\", // Path params processing\n \"validateParams\", // Path params validation\n \"bodyparser\", // Raw request body parsing\n \"payload\", // Set ctx.payload\n \"validatePayload\", // Payload validation\n \"validateResponse\", // Response validation\n ];\n\n const stack: Array<RouterRoute> = [];\n\n // Iterate over each route definition\n for (const { name, path, file, ...rest } of routeSources) {\n // Include both middleware and HTTP method handlers\n const definitionItems = [...rest.useWrappers, ...rest.definitionItems];\n\n const routeMiddleware: Array<MiddlewareDefinition> = definitionItems.filter(\n (e) => e.kind === \"middleware\",\n );\n\n // WARN: the order is critical!\n // the last defined middleware will take precedence.\n const middlewareStack: Array<MiddlewareDefinition> = [\n ...paramsMiddlewareFactory(rest.params, rest.numericParams),\n ...validationMiddlewareFactory(rest.validationSchemas),\n // core middleware overrides builtin middleware (of same slot)\n ...coreMiddleware,\n // route middleware overrides core middleware (of same slot)\n ...routeMiddleware,\n ];\n\n const routeStack: Array<MiddlewareDefinition | HandlerDefinition> = [\n ...prioritizedSlots.flatMap((slot) => {\n const middleware = middlewareStack.findLast(\n // Using findLast to pick the latest entry,\n // ensuring later entries override earlier ones.\n (e) => e.options?.slot === slot,\n );\n return middleware //\n ? [middleware]\n : [];\n }),\n\n ...coreMiddleware.flatMap((entry) => {\n if (!entry.options?.slot) {\n // no slot, including regardless\n return [entry];\n }\n if (prioritizedSlots.includes(entry.options?.slot)) {\n // already picked when inserted prioritized middleware, excluding\n return [];\n }\n const override = routeMiddleware.findLast(\n // Using findLast to pick the latest entry,\n // ensuring later entries override earlier ones.\n (e) => e.options?.slot === entry.options?.slot,\n );\n return [override || entry];\n }),\n\n ...definitionItems.flatMap((entry) => {\n const slot =\n entry.kind === \"middleware\" //\n ? entry.options?.slot\n : undefined;\n\n if (slot) {\n if (prioritizedSlots.includes(slot)) {\n // already picked when inserted prioritized middleware, excluding\n return [];\n }\n if (coreMiddleware.some((e) => e.options?.slot === slot)) {\n // already picked when inserted core middleware, excluding\n return [];\n }\n }\n\n return [entry];\n }),\n ];\n\n for (const entry of routeStack) {\n if (entry.kind === \"middleware\") {\n stack.push({\n name,\n path,\n file,\n methods: entry.options?.on || Object.keys(HTTPMethods),\n middleware: entry.middleware,\n kind: entry.kind,\n slot: entry.options?.slot,\n debug: entry.options?.debug,\n });\n } else if (entry.kind === \"handler\") {\n stack.push({\n name,\n path,\n file,\n methods: [entry.method],\n middleware: entry.middleware,\n kind: entry.kind,\n });\n }\n }\n }\n\n return stack;\n};\n\nconst paramsMiddlewareFactory = (\n params: RouterRouteSource[\"params\"],\n numericParams: RouterRouteSource[\"numericParams\"],\n) => [\n use(\n (ctx, next) => {\n ctx.typedParams = params.reduce(\n (map: Record<string, unknown>, [name, isRest]) => {\n const value = ctx.params[name];\n if (value) {\n if (isRest) {\n map[name] = numericParams.includes(name)\n ? value.split(\"/\").map(Number)\n : value.split(\"/\");\n } else {\n map[name] = numericParams.includes(name) ? Number(value) : value;\n }\n } else {\n map[name] = value;\n }\n return map;\n },\n {},\n ) as never;\n return next();\n },\n { slot: \"params\" },\n ),\n];\n\nconst validationMiddlewareFactory = (validationSchemas: ValidationSchemas) => [\n use(\n (ctx, next) => {\n validationSchemas.params?.validate(ctx.typedParams);\n return next();\n },\n { slot: \"validateParams\" },\n ),\n\n use(\n (ctx, next) => {\n validationSchemas.payload?.[ctx.method]?.validate(ctx.payload);\n return next();\n },\n {\n slot: \"validatePayload\",\n on: Object.keys(validationSchemas.payload || {}) as never,\n },\n ),\n\n use(\n async (ctx, next) => {\n if (validationSchemas.response?.[ctx.method]) {\n await next();\n validationSchemas.response?.[ctx.method]?.validate(ctx.body);\n } else {\n return next();\n }\n },\n {\n slot: \"validateResponse\",\n on: Object.keys(validationSchemas.response || {}) as never,\n },\n ),\n];\n", "import type {\n RouterContext,\n RouterMiddleware,\n RouterOptions,\n} from \"@koa/router\";\nimport type { Next } from \"koa\";\n\ndeclare module \"koa\" {\n interface Request {\n body?: unknown;\n rawBody: string;\n }\n}\n\nexport interface DefaultState {}\nexport interface DefaultContext {}\n\nexport enum HTTPMethods {\n HEAD = \"HEAD\",\n OPTIONS = \"OPTIONS\",\n GET = \"GET\",\n PUT = \"PUT\",\n PATCH = \"PATCH\",\n POST = \"POST\",\n DELETE = \"DELETE\",\n}\n\nexport type { RouterMiddleware as Middleware };\n\nexport type HTTPMethod = keyof typeof HTTPMethods;\n\nexport type ParameterizedContext<\n ParamsT,\n StateT,\n ContextT,\n PayloadT = unknown,\n ResponseT = unknown,\n> = RouterContext<\n DefaultState & StateT,\n DefaultContext &\n ContextT & {\n typedParams: ParamsT;\n payload: PayloadT;\n },\n ResponseT\n>;\n\ntype RouteMiddleware<ParamsT, StateT, ContextT> = (\n ctx: ParameterizedContext<ParamsT, StateT, ContextT>,\n next: Next,\n) => Promise<void> | void;\n\nexport type RouteHandler<\n ParamsT,\n StateT,\n ContextT,\n PayloadT = unknown,\n ResponseT = unknown,\n> = (\n ctx: ParameterizedContext<ParamsT, StateT, ContextT, PayloadT, ResponseT>,\n next: Next,\n) => Promise<void> | void;\n\nexport type MiddlewareDefinition = {\n kind: \"middleware\";\n middleware: Array<RouterMiddleware>;\n options?: UseOptions | undefined;\n};\n\nexport type HandlerDefinition = {\n kind: \"handler\";\n middleware: Array<RouterMiddleware>;\n method: HTTPMethod;\n};\n\nexport type RouteDefinitionItem = MiddlewareDefinition | HandlerDefinition;\n\nexport type DefineRouteHelpers<\n ParamsT,\n StateT,\n ContextT,\n OptionalHandlers = undefined,\n> = {\n // INFO: The `use` helper intentionally does not accept type parameters.\n // PayloadT and ResponseT are only relevant to route handlers,\n // as different request methods receive different payloads and return different responses.\n // Allowing these type parameters on `use` would be misleading,\n // since middleware operates across multiple request methods with varying types.\n use: (\n middleware:\n | RouteMiddleware<ParamsT, StateT, ContextT>\n | Array<RouteMiddleware<ParamsT, StateT, ContextT>>,\n options?: UseOptions,\n ) => RouteDefinitionItem;\n} & {\n [M in HTTPMethod]: M extends OptionalHandlers\n ? <PayloadT = unknown, ResponseT = unknown>(\n handler?:\n | RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>\n | Array<RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>>,\n ) => RouteDefinitionItem\n : <PayloadT = unknown, ResponseT = unknown>(\n handler:\n | RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>\n | Array<RouteHandler<ParamsT, StateT, ContextT, PayloadT, ResponseT>>,\n ) => RouteDefinitionItem;\n};\n\nexport type DefineRoute = <\n ParamsT = Record<string, string>,\n StateT = object,\n ContextT = object,\n>(\n factory: (\n helpers: DefineRouteHelpers<ParamsT, StateT, ContextT>,\n ) => Array<RouteDefinitionItem>,\n) => Array<RouteDefinitionItem>;\n\nexport interface UseSlots {\n params: string;\n validateParams: string;\n bodyparser: string;\n payload: string;\n validatePayload: string;\n validateResponse: string;\n}\n\nexport type UseOptions = {\n on?: Array<HTTPMethod>;\n slot?: keyof UseSlots;\n debug?: string | undefined;\n};\n\nexport type Use = <StateT = DefaultState, ContextT = DefaultContext>(\n middleware:\n | RouteMiddleware<Record<string, string>, StateT, ContextT>\n | Array<RouteMiddleware<Record<string, string>, StateT, ContextT>>,\n options?: UseOptions,\n) => MiddlewareDefinition;\n\nexport type RouterRouteSource = {\n name: string;\n path: string;\n file: string;\n // useWrappers is same as defining middleware inside route definition,\n // just automatically imported from use.ts files\n useWrappers: Array<MiddlewareDefinition>;\n definitionItems: Array<RouteDefinitionItem>;\n params: Array<[name: string, isRest?: boolean]>;\n numericParams: Array<string>;\n validationSchemas: ValidationSchemas;\n meta?: Record<string, unknown>;\n};\n\nexport type RouterRoute = {\n name: string;\n path: string;\n file: string;\n methods: Array<string>;\n middleware: Array<RouterMiddleware>;\n kind: \"middleware\" | \"handler\";\n slot?: keyof UseSlots | undefined;\n debug?: string | undefined;\n};\n\nimport type Koa from \"koa\";\nexport type App = Koa<DefaultState, DefaultContext>;\nexport type AppOptions = ConstructorParameters<typeof import(\"koa\")>[0];\nexport type CreateApp = (options?: AppOptions) => App;\n\nimport type KoaRouter from \"@koa/router\";\nexport type Router = KoaRouter<DefaultState, DefaultContext>;\nexport type { RouterOptions };\nexport type CreateRouter = (options?: RouterOptions) => Router;\n\nexport type DevMiddlewareFactory = (\n app: App,\n) => (\n req: import(\"node:http\").IncomingMessage,\n res: import(\"node:http\").ServerResponse,\n next: () => Promise<void>,\n) => Promise<void>;\nexport type TeardownHandler = (app: App) => void | Promise<void>;\n\nexport type ValidationSchema = {\n check: (data: unknown) => boolean;\n errors: (data: unknown) => Array<ValidationErrorEntry>;\n errorMessage: (data: unknown) => string;\n errorSummary: (data: unknown) => string;\n validate: (data: unknown) => void;\n};\n\nexport type ValidationSchemas<Extend = object> = {\n params?: ValidationSchema & Extend;\n payload?: Record<string, ValidationSchema & Extend>;\n response?: Record<string, ValidationSchema & Extend>;\n};\n\nexport type ValidationErrorScope = \"params\" | \"payload\" | \"response\";\n\n/**\n * Shape of individual validation errors emitted by generators.\n */\nexport type ValidationErrorEntry = {\n /** JSON Schema keyword that triggered the error (e.g. `format`, `maxItems`, `maxLength`). */\n keyword: string;\n /** JSON Pointer\u2013style path to the invalid field (matches JSON Schema `instancePath`). */\n path: string;\n /** Human-readable error message. */\n message: string;\n /** Constraint parameters (e.g. `{ limit: 5 }`, `{ format: \"email\" }`). */\n params?: Record<string, unknown>;\n /** Optional error code for i18n/l10n or custom handling. */\n code?: string;\n};\n\nexport type ValidationErrorData = {\n errors: Array<ValidationErrorEntry>;\n /**\n * Formats errors into a single human-readable message.\n * @example: Validation failed: user: missing required properties: \"email\", \"name\"; password: must be at least 8 characters long\n */\n errorMessage: string;\n /**\n * Gets a simple error summary for quick feedback.\n * @example: 2 validation errors found across 2 fields\n */\n errorSummary: string;\n};\n", "import type { Use } from \"./types\";\n\nexport const use: Use = (middleware, options) => {\n return {\n kind: \"middleware\",\n middleware: [middleware].flat() as never,\n options,\n };\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["HTTPMethods"]
|
|
7
7
|
}
|
package/pkg/src/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouterContext, RouterMiddleware, RouterOptions } from "@koa/router";
|
|
2
2
|
import type { Next } from "koa";
|
|
3
3
|
declare module "koa" {
|
|
4
4
|
interface Request {
|
|
@@ -19,9 +19,9 @@ export declare enum HTTPMethods {
|
|
|
19
19
|
POST = "POST",
|
|
20
20
|
DELETE = "DELETE"
|
|
21
21
|
}
|
|
22
|
-
export type { Middleware };
|
|
22
|
+
export type { RouterMiddleware as Middleware };
|
|
23
23
|
export type HTTPMethod = keyof typeof HTTPMethods;
|
|
24
|
-
export type ParameterizedContext<ParamsT, StateT, ContextT, PayloadT = unknown, ResponseT = unknown> =
|
|
24
|
+
export type ParameterizedContext<ParamsT, StateT, ContextT, PayloadT = unknown, ResponseT = unknown> = RouterContext<DefaultState & StateT, DefaultContext & ContextT & {
|
|
25
25
|
typedParams: ParamsT;
|
|
26
26
|
payload: PayloadT;
|
|
27
27
|
}, ResponseT>;
|
|
@@ -29,12 +29,12 @@ type RouteMiddleware<ParamsT, StateT, ContextT> = (ctx: ParameterizedContext<Par
|
|
|
29
29
|
export type RouteHandler<ParamsT, StateT, ContextT, PayloadT = unknown, ResponseT = unknown> = (ctx: ParameterizedContext<ParamsT, StateT, ContextT, PayloadT, ResponseT>, next: Next) => Promise<void> | void;
|
|
30
30
|
export type MiddlewareDefinition = {
|
|
31
31
|
kind: "middleware";
|
|
32
|
-
middleware: Array<
|
|
32
|
+
middleware: Array<RouterMiddleware>;
|
|
33
33
|
options?: UseOptions | undefined;
|
|
34
34
|
};
|
|
35
35
|
export type HandlerDefinition = {
|
|
36
36
|
kind: "handler";
|
|
37
|
-
middleware: Array<
|
|
37
|
+
middleware: Array<RouterMiddleware>;
|
|
38
38
|
method: HTTPMethod;
|
|
39
39
|
};
|
|
40
40
|
export type RouteDefinitionItem = MiddlewareDefinition | HandlerDefinition;
|
|
@@ -62,6 +62,7 @@ export type RouterRouteSource = {
|
|
|
62
62
|
name: string;
|
|
63
63
|
path: string;
|
|
64
64
|
file: string;
|
|
65
|
+
useWrappers: Array<MiddlewareDefinition>;
|
|
65
66
|
definitionItems: Array<RouteDefinitionItem>;
|
|
66
67
|
params: Array<[name: string, isRest?: boolean]>;
|
|
67
68
|
numericParams: Array<string>;
|
|
@@ -73,7 +74,7 @@ export type RouterRoute = {
|
|
|
73
74
|
path: string;
|
|
74
75
|
file: string;
|
|
75
76
|
methods: Array<string>;
|
|
76
|
-
middleware: Array<
|
|
77
|
+
middleware: Array<RouterMiddleware>;
|
|
77
78
|
kind: "middleware" | "handler";
|
|
78
79
|
slot?: keyof UseSlots | undefined;
|
|
79
80
|
debug?: string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|