@kontract/adonis 0.1.0
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/README.md +507 -0
- package/dist/adapters/controller-registrar.d.ts +313 -0
- package/dist/adapters/controller-registrar.d.ts.map +1 -0
- package/dist/adapters/controller-registrar.js +324 -0
- package/dist/adapters/controller-registrar.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/route-registrar.d.ts +53 -0
- package/dist/adapters/route-registrar.d.ts.map +1 -0
- package/dist/adapters/route-registrar.js +139 -0
- package/dist/adapters/route-registrar.js.map +1 -0
- package/dist/adapters/router.d.ts +37 -0
- package/dist/adapters/router.d.ts.map +1 -0
- package/dist/adapters/router.js +129 -0
- package/dist/adapters/router.js.map +1 -0
- package/dist/builder/index.d.ts +2 -0
- package/dist/builder/index.d.ts.map +1 -0
- package/dist/builder/index.js +3 -0
- package/dist/builder/index.js.map +1 -0
- package/dist/builder/openapi-builder.d.ts +100 -0
- package/dist/builder/openapi-builder.d.ts.map +1 -0
- package/dist/builder/openapi-builder.js +388 -0
- package/dist/builder/openapi-builder.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/serializers/index.d.ts +2 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/index.js +2 -0
- package/dist/serializers/index.js.map +1 -0
- package/dist/serializers/lucid.d.ts +100 -0
- package/dist/serializers/lucid.d.ts.map +1 -0
- package/dist/serializers/lucid.js +114 -0
- package/dist/serializers/lucid.js.map +1 -0
- package/dist/validation/ajv.d.ts +42 -0
- package/dist/validation/ajv.d.ts.map +1 -0
- package/dist/validation/ajv.js +170 -0
- package/dist/validation/ajv.js.map +1 -0
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +3 -0
- package/dist/validation/index.js.map +1 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,GAMV,MAAM,2BAA2B,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Router, HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { TSchema } from '@sinclair/typebox';
|
|
3
|
+
/**
|
|
4
|
+
* Validation schemas for request data.
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidationSchemas {
|
|
7
|
+
body?: TSchema;
|
|
8
|
+
query?: TSchema;
|
|
9
|
+
params?: TSchema;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Extended HttpContext with validated data and auth.
|
|
13
|
+
*/
|
|
14
|
+
export interface ValidatedContext extends HttpContext {
|
|
15
|
+
validatedBody?: unknown;
|
|
16
|
+
validatedQuery?: unknown;
|
|
17
|
+
validatedParams?: unknown;
|
|
18
|
+
auth: {
|
|
19
|
+
authenticate(): Promise<unknown>;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Validator function type.
|
|
24
|
+
*/
|
|
25
|
+
export type ValidateFn = <T>(schema: TSchema, data: unknown) => T;
|
|
26
|
+
/**
|
|
27
|
+
* Options for registering decorator routes.
|
|
28
|
+
*/
|
|
29
|
+
export interface RegisterRoutesOptions {
|
|
30
|
+
/** Validation function (e.g., AJV validate) */
|
|
31
|
+
validate: ValidateFn;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Registers all routes defined via @Endpoint decorators.
|
|
35
|
+
* Call this in your routes.ts file after importing decorated controllers.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // start/routes.ts
|
|
40
|
+
* import router from '@adonisjs/core/services/router'
|
|
41
|
+
* import { registerDecoratorRoutes } from '@kontract/adonis'
|
|
42
|
+
* import { validate } from '#validators/ajv'
|
|
43
|
+
*
|
|
44
|
+
* // Import controllers to trigger decorator registration
|
|
45
|
+
* import '#controllers/games_controller'
|
|
46
|
+
* import '#controllers/books_controller'
|
|
47
|
+
*
|
|
48
|
+
* // Register all decorated routes
|
|
49
|
+
* registerDecoratorRoutes(router, { validate })
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function registerDecoratorRoutes(router: Router, options: RegisterRoutesOptions): void;
|
|
53
|
+
//# sourceMappingURL=route-registrar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-registrar.d.ts","sourceRoot":"","sources":["../../src/adapters/route-registrar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAE9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAShD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,IAAI,EAAE;QACJ,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;KACjC,CAAA;CACF;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,CAAC,CAAA;AAEjE;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,QAAQ,EAAE,UAAU,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,GAC7B,IAAI,CAaN"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { getApiMetadata, getEndpointMetadata, getRegisteredControllers, isBinaryResponse, } from 'kontract';
|
|
2
|
+
/**
|
|
3
|
+
* Registers all routes defined via @Endpoint decorators.
|
|
4
|
+
* Call this in your routes.ts file after importing decorated controllers.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // start/routes.ts
|
|
9
|
+
* import router from '@adonisjs/core/services/router'
|
|
10
|
+
* import { registerDecoratorRoutes } from '@kontract/adonis'
|
|
11
|
+
* import { validate } from '#validators/ajv'
|
|
12
|
+
*
|
|
13
|
+
* // Import controllers to trigger decorator registration
|
|
14
|
+
* import '#controllers/games_controller'
|
|
15
|
+
* import '#controllers/books_controller'
|
|
16
|
+
*
|
|
17
|
+
* // Register all decorated routes
|
|
18
|
+
* registerDecoratorRoutes(router, { validate })
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function registerDecoratorRoutes(router, options) {
|
|
22
|
+
const controllers = getRegisteredControllers();
|
|
23
|
+
for (const controller of controllers) {
|
|
24
|
+
const apiMeta = getApiMetadata(controller);
|
|
25
|
+
const endpoints = getEndpointMetadata(controller);
|
|
26
|
+
if (!apiMeta || endpoints.length === 0)
|
|
27
|
+
continue;
|
|
28
|
+
for (const endpoint of endpoints) {
|
|
29
|
+
registerEndpoint(router, controller, endpoint, options.validate);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Register a single endpoint.
|
|
35
|
+
*/
|
|
36
|
+
function registerEndpoint(router, Controller, endpoint, validate) {
|
|
37
|
+
const { method, path, methodName, auth, body, query, params, middleware } = endpoint;
|
|
38
|
+
// Build validation schemas
|
|
39
|
+
const validationSchemas = {};
|
|
40
|
+
if (body)
|
|
41
|
+
validationSchemas.body = body;
|
|
42
|
+
if (query)
|
|
43
|
+
validationSchemas.query = query;
|
|
44
|
+
if (params)
|
|
45
|
+
validationSchemas.params = params;
|
|
46
|
+
// Create handler
|
|
47
|
+
const handler = createHandler(Controller, methodName, auth, validationSchemas, validate);
|
|
48
|
+
// Register the route
|
|
49
|
+
let route;
|
|
50
|
+
switch (method) {
|
|
51
|
+
case 'get':
|
|
52
|
+
route = router.get(path, handler);
|
|
53
|
+
break;
|
|
54
|
+
case 'post':
|
|
55
|
+
route = router.post(path, handler);
|
|
56
|
+
break;
|
|
57
|
+
case 'put':
|
|
58
|
+
route = router.put(path, handler);
|
|
59
|
+
break;
|
|
60
|
+
case 'patch':
|
|
61
|
+
route = router.patch(path, handler);
|
|
62
|
+
break;
|
|
63
|
+
case 'delete':
|
|
64
|
+
route = router.delete(path, handler);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
// Apply additional middleware (cast to expected type)
|
|
68
|
+
if (middleware && Array.isArray(middleware) && middleware.length > 0) {
|
|
69
|
+
route.use(middleware);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create a request handler for an endpoint.
|
|
74
|
+
*/
|
|
75
|
+
function createHandler(Controller, methodName, auth, validationSchemas, validate) {
|
|
76
|
+
return async (ctx) => {
|
|
77
|
+
const validatedCtx = ctx;
|
|
78
|
+
// Handle authentication
|
|
79
|
+
if (auth === 'required') {
|
|
80
|
+
await validatedCtx.auth.authenticate();
|
|
81
|
+
}
|
|
82
|
+
else if (auth === 'optional') {
|
|
83
|
+
try {
|
|
84
|
+
await validatedCtx.auth.authenticate();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Ignore auth failure for optional auth
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Validate request data
|
|
91
|
+
if (validationSchemas.body) {
|
|
92
|
+
validatedCtx.validatedBody = validate(validationSchemas.body, ctx.request.body());
|
|
93
|
+
}
|
|
94
|
+
if (validationSchemas.query) {
|
|
95
|
+
validatedCtx.validatedQuery = validate(validationSchemas.query, ctx.request.qs());
|
|
96
|
+
}
|
|
97
|
+
if (validationSchemas.params) {
|
|
98
|
+
validatedCtx.validatedParams = validate(validationSchemas.params, ctx.params);
|
|
99
|
+
}
|
|
100
|
+
const controller = await ctx.containerResolver.make(Controller);
|
|
101
|
+
const result = await controller[methodName](ctx, validatedCtx.validatedBody, validatedCtx.validatedQuery, validatedCtx.validatedParams);
|
|
102
|
+
// Handle the response
|
|
103
|
+
return handleResponse(ctx, result);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Handle the response from a controller method.
|
|
108
|
+
*/
|
|
109
|
+
function handleResponse(ctx, result) {
|
|
110
|
+
// Handle binary response (file downloads)
|
|
111
|
+
if (isBinaryResponse(result)) {
|
|
112
|
+
ctx.response.header('Content-Type', result.contentType);
|
|
113
|
+
if (result.filename) {
|
|
114
|
+
ctx.response.header('Content-Disposition', `attachment; filename="${result.filename}"`);
|
|
115
|
+
}
|
|
116
|
+
return ctx.response.status(result.status).send(result.data);
|
|
117
|
+
}
|
|
118
|
+
// Handle structured API response
|
|
119
|
+
if (isApiResponse(result)) {
|
|
120
|
+
if (result.status === 204) {
|
|
121
|
+
return ctx.response.noContent();
|
|
122
|
+
}
|
|
123
|
+
return ctx.response.status(result.status).json(result.data);
|
|
124
|
+
}
|
|
125
|
+
// Return raw result for backwards compatibility
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Type guard for API responses.
|
|
130
|
+
*/
|
|
131
|
+
function isApiResponse(value) {
|
|
132
|
+
return (value !== null
|
|
133
|
+
&& typeof value === 'object'
|
|
134
|
+
&& 'status' in value
|
|
135
|
+
&& 'data' in value
|
|
136
|
+
&& !('binary' in value)
|
|
137
|
+
&& typeof value.status === 'number');
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=route-registrar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-registrar.js","sourceRoot":"","sources":["../../src/adapters/route-registrar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Router, HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { TSchema } from '@sinclair/typebox';
|
|
3
|
+
import { type RouterAdapter } from 'kontract';
|
|
4
|
+
/**
|
|
5
|
+
* Validation schemas for request data.
|
|
6
|
+
*/
|
|
7
|
+
export interface ValidationSchemas {
|
|
8
|
+
body?: TSchema;
|
|
9
|
+
query?: TSchema;
|
|
10
|
+
params?: TSchema;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extended HttpContext with validated data.
|
|
14
|
+
*/
|
|
15
|
+
export interface ValidatedContext extends HttpContext {
|
|
16
|
+
validatedBody?: unknown;
|
|
17
|
+
validatedQuery?: unknown;
|
|
18
|
+
validatedParams?: unknown;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validator function type.
|
|
22
|
+
*/
|
|
23
|
+
export type ValidateFn = <T>(schema: TSchema, data: unknown) => T;
|
|
24
|
+
/**
|
|
25
|
+
* Options for creating the AdonisJS router adapter.
|
|
26
|
+
*/
|
|
27
|
+
export interface AdonisRouterAdapterOptions {
|
|
28
|
+
/** The AdonisJS router instance */
|
|
29
|
+
router: Router;
|
|
30
|
+
/** Validation function (e.g., AJV validate) */
|
|
31
|
+
validate: ValidateFn;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create an AdonisJS router adapter.
|
|
35
|
+
*/
|
|
36
|
+
export declare function createAdonisRouterAdapter(options: AdonisRouterAdapterOptions): RouterAdapter;
|
|
37
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/adapters/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,0BAA0B,CAAA;AAEjC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,KAAK,CAAC,CAAA;AAEjE;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,QAAQ,EAAE,UAAU,CAAA;CACrB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,0BAA0B,GAClC,aAAa,CA4Df"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { isBinaryResponse, } from '@blog/openapi-decorators';
|
|
2
|
+
/**
|
|
3
|
+
* Create an AdonisJS router adapter.
|
|
4
|
+
*/
|
|
5
|
+
export function createAdonisRouterAdapter(options) {
|
|
6
|
+
const { router, validate } = options;
|
|
7
|
+
const registeredRoutes = [];
|
|
8
|
+
return {
|
|
9
|
+
register(method, path, _handler, metadata) {
|
|
10
|
+
const { methodName, auth, body, query, params, middleware } = metadata;
|
|
11
|
+
// Build validation schemas
|
|
12
|
+
const validationSchemas = {};
|
|
13
|
+
if (body)
|
|
14
|
+
validationSchemas.body = body;
|
|
15
|
+
if (query)
|
|
16
|
+
validationSchemas.query = query;
|
|
17
|
+
if (params)
|
|
18
|
+
validationSchemas.params = params;
|
|
19
|
+
// Create the handler
|
|
20
|
+
const handler = createHandler(metadata, methodName, auth, validationSchemas, validate);
|
|
21
|
+
// Register the route
|
|
22
|
+
let route;
|
|
23
|
+
switch (method) {
|
|
24
|
+
case 'get':
|
|
25
|
+
route = router.get(path, handler);
|
|
26
|
+
break;
|
|
27
|
+
case 'post':
|
|
28
|
+
route = router.post(path, handler);
|
|
29
|
+
break;
|
|
30
|
+
case 'put':
|
|
31
|
+
route = router.put(path, handler);
|
|
32
|
+
break;
|
|
33
|
+
case 'patch':
|
|
34
|
+
route = router.patch(path, handler);
|
|
35
|
+
break;
|
|
36
|
+
case 'delete':
|
|
37
|
+
route = router.delete(path, handler);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
// Apply additional middleware
|
|
41
|
+
if (middleware && Array.isArray(middleware) && middleware.length > 0) {
|
|
42
|
+
route.use(middleware);
|
|
43
|
+
}
|
|
44
|
+
registeredRoutes.push({ method, path });
|
|
45
|
+
},
|
|
46
|
+
getRoutes() {
|
|
47
|
+
return registeredRoutes;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create a request handler for an endpoint.
|
|
53
|
+
*/
|
|
54
|
+
function createHandler(metadata, methodName, auth, validationSchemas, validate) {
|
|
55
|
+
// Get the controller class from metadata
|
|
56
|
+
// This will be set by the route registrar
|
|
57
|
+
let Controller = null;
|
|
58
|
+
return async (ctx) => {
|
|
59
|
+
const validatedCtx = ctx;
|
|
60
|
+
// Handle authentication
|
|
61
|
+
if (auth === 'required') {
|
|
62
|
+
await ctx.auth.authenticate();
|
|
63
|
+
}
|
|
64
|
+
else if (auth === 'optional') {
|
|
65
|
+
try {
|
|
66
|
+
await ctx.auth.authenticate();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Ignore auth failure for optional auth
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Validate request data
|
|
73
|
+
if (validationSchemas.body) {
|
|
74
|
+
validatedCtx.validatedBody = validate(validationSchemas.body, ctx.request.body());
|
|
75
|
+
}
|
|
76
|
+
if (validationSchemas.query) {
|
|
77
|
+
validatedCtx.validatedQuery = validate(validationSchemas.query, ctx.request.qs());
|
|
78
|
+
}
|
|
79
|
+
if (validationSchemas.params) {
|
|
80
|
+
validatedCtx.validatedParams = validate(validationSchemas.params, ctx.params);
|
|
81
|
+
}
|
|
82
|
+
// Resolve controller from container
|
|
83
|
+
// The Controller will be passed via the metadata
|
|
84
|
+
if (!Controller) {
|
|
85
|
+
// For now, we'll need to get it from the route's controller reference
|
|
86
|
+
// This will be handled by the registration function
|
|
87
|
+
throw new Error(`Controller not found for endpoint ${methodName}. ` +
|
|
88
|
+
'Use registerDecoratorRoutes() to register routes.');
|
|
89
|
+
}
|
|
90
|
+
const controller = await ctx.containerResolver.make(Controller);
|
|
91
|
+
const result = await controller[methodName](ctx, validatedCtx.validatedBody, validatedCtx.validatedQuery, validatedCtx.validatedParams);
|
|
92
|
+
// Handle the response
|
|
93
|
+
return handleResponse(ctx, result);
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Handle the response from a controller method.
|
|
98
|
+
*/
|
|
99
|
+
function handleResponse(ctx, result) {
|
|
100
|
+
// Handle binary response (file downloads)
|
|
101
|
+
if (isBinaryResponse(result)) {
|
|
102
|
+
ctx.response.header('Content-Type', result.contentType);
|
|
103
|
+
if (result.filename) {
|
|
104
|
+
ctx.response.header('Content-Disposition', `attachment; filename="${result.filename}"`);
|
|
105
|
+
}
|
|
106
|
+
return ctx.response.status(result.status).send(result.data);
|
|
107
|
+
}
|
|
108
|
+
// Handle structured API response
|
|
109
|
+
if (isApiResponse(result)) {
|
|
110
|
+
if (result.status === 204) {
|
|
111
|
+
return ctx.response.noContent();
|
|
112
|
+
}
|
|
113
|
+
return ctx.response.status(result.status).json(result.data);
|
|
114
|
+
}
|
|
115
|
+
// Return raw result for backwards compatibility
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Type guard for API responses.
|
|
120
|
+
*/
|
|
121
|
+
function isApiResponse(value) {
|
|
122
|
+
return (value !== null &&
|
|
123
|
+
typeof value === 'object' &&
|
|
124
|
+
'status' in value &&
|
|
125
|
+
'data' in value &&
|
|
126
|
+
!('binary' in value) &&
|
|
127
|
+
typeof value.status === 'number');
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/adapters/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builder/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builder/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,OAAO,EAAE,cAAc,EAA8B,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { type OpenApiDocument, type OpenApiVersion } from 'kontract';
|
|
2
|
+
/**
|
|
3
|
+
* Options for building the OpenAPI document.
|
|
4
|
+
*/
|
|
5
|
+
export interface OpenApiBuilderOptions {
|
|
6
|
+
title: string;
|
|
7
|
+
description: string;
|
|
8
|
+
version: string;
|
|
9
|
+
servers: Array<{
|
|
10
|
+
url: string;
|
|
11
|
+
description: string;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* OpenAPI specification version.
|
|
15
|
+
* @default '3.1.0'
|
|
16
|
+
*/
|
|
17
|
+
openapiVersion?: OpenApiVersion;
|
|
18
|
+
/**
|
|
19
|
+
* Security scheme configuration.
|
|
20
|
+
* @default Bearer JWT authentication
|
|
21
|
+
*/
|
|
22
|
+
securityScheme?: {
|
|
23
|
+
name: string;
|
|
24
|
+
type: 'http' | 'apiKey' | 'oauth2';
|
|
25
|
+
scheme?: string;
|
|
26
|
+
bearerFormat?: string;
|
|
27
|
+
description?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Builds an OpenAPI specification from registered @Api and @Endpoint decorators.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const builder = new OpenApiBuilder({
|
|
36
|
+
* title: 'My API',
|
|
37
|
+
* description: 'API description',
|
|
38
|
+
* version: '1.0.0',
|
|
39
|
+
* servers: [{ url: 'http://localhost:3333', description: 'Development' }],
|
|
40
|
+
* })
|
|
41
|
+
*
|
|
42
|
+
* const spec = builder.build()
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class OpenApiBuilder {
|
|
46
|
+
private document;
|
|
47
|
+
private schemas;
|
|
48
|
+
private tags;
|
|
49
|
+
private securitySchemeName;
|
|
50
|
+
constructor(options: OpenApiBuilderOptions);
|
|
51
|
+
/**
|
|
52
|
+
* Build the OpenAPI document from registered decorators.
|
|
53
|
+
*/
|
|
54
|
+
build(): OpenApiDocument;
|
|
55
|
+
/**
|
|
56
|
+
* Process a single endpoint and add it to the document.
|
|
57
|
+
*/
|
|
58
|
+
private processEndpoint;
|
|
59
|
+
/**
|
|
60
|
+
* Build file upload request body.
|
|
61
|
+
*/
|
|
62
|
+
private buildFileRequestBody;
|
|
63
|
+
/**
|
|
64
|
+
* Build parameters from endpoint metadata.
|
|
65
|
+
*/
|
|
66
|
+
private buildParameters;
|
|
67
|
+
/**
|
|
68
|
+
* Convert a TypeBox schema to OpenAPI parameters.
|
|
69
|
+
*/
|
|
70
|
+
private schemaToParameters;
|
|
71
|
+
/**
|
|
72
|
+
* Build responses from endpoint metadata.
|
|
73
|
+
*/
|
|
74
|
+
private buildResponses;
|
|
75
|
+
/**
|
|
76
|
+
* Register a schema and return its name.
|
|
77
|
+
*/
|
|
78
|
+
private registerSchema;
|
|
79
|
+
/**
|
|
80
|
+
* Extract and register nested schemas with $id.
|
|
81
|
+
*/
|
|
82
|
+
private extractNestedSchemas;
|
|
83
|
+
/**
|
|
84
|
+
* Convert TypeBox schema to JSON Schema (for OpenAPI).
|
|
85
|
+
*/
|
|
86
|
+
private toJsonSchema;
|
|
87
|
+
/**
|
|
88
|
+
* Remove TypeBox-specific properties from schema.
|
|
89
|
+
*/
|
|
90
|
+
private removeTypeBoxProps;
|
|
91
|
+
/**
|
|
92
|
+
* Generate an operation ID from endpoint metadata.
|
|
93
|
+
*/
|
|
94
|
+
private generateOperationId;
|
|
95
|
+
/**
|
|
96
|
+
* Get default description for a status code.
|
|
97
|
+
*/
|
|
98
|
+
private defaultDescription;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=openapi-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openapi-builder.d.ts","sourceRoot":"","sources":["../../src/builder/openapi-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,cAAc,EAMpB,MAAM,0BAA0B,CAAA;AAEjC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpD;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;OAGG;IACH,cAAc,CAAC,EAAE;QACf,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;QAClC,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,kBAAkB,CAAQ;gBAEtB,OAAO,EAAE,qBAAqB;IAgC1C;;OAEG;IACH,KAAK,IAAI,eAAe;IA+BxB;;OAEG;IACH,OAAO,CAAC,eAAe;IA4DvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgD5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAwCvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,OAAO,CAAC,cAAc;IA0CtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgC3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAc3B"}
|