@ibabkin/openapi-express-server 1.4.0 → 2.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 +13 -11
- package/esm/containerMiddleware.d.ts +7 -1
- package/esm/containerMiddleware.d.ts.map +1 -1
- package/esm/containerMiddleware.js +8 -3
- package/esm/containerMiddleware.js.map +1 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/routeExtractor.d.ts.map +1 -1
- package/esm/routeExtractor.js +2 -12
- package/esm/routeExtractor.js.map +1 -1
- package/esm/types.d.ts +5 -5
- package/esm/types.d.ts.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
# @ibabkin/openapi-express-server
|
|
2
2
|
|
|
3
|
-
Express.js building blocks for wiring routes from an OpenAPI spec to
|
|
3
|
+
Express.js building blocks for wiring routes from an OpenAPI spec to use cases resolved from a
|
|
4
4
|
[`ts-ioc-container`](https://github.com/IgorBabkin/ts-ioc-container) scope. Pairs with
|
|
5
|
-
`@ibabkin/openapi-to-server` (
|
|
5
|
+
`@ibabkin/openapi-to-server` (one `<Op>UseCase` interface per operation) and `@ibabkin/openapi-to-zod`
|
|
6
6
|
(Zod payload validators).
|
|
7
7
|
|
|
8
8
|
## Exports
|
|
9
9
|
|
|
10
|
-
- `extractRoutes(spec)` — flattens an `OpenAPIV3.Document` into `RouteMetadata[]` (path
|
|
10
|
+
- `extractRoutes(spec)` — flattens an `OpenAPIV3.Document` into `RouteMetadata[]` (`path`, `method`, `operationId`, `tags`); `operationId` is the DI key of the operation's use case, `tags` are the operation's tags verbatim
|
|
11
11
|
- `convertOpenAPIPathToExpress(path)` — `/users/{id}` → `/users/:id`
|
|
12
12
|
- `buildPayload(req)` — picks `params`, `query`, `body`, `headers` off an Express request
|
|
13
|
-
- `containerMiddleware(appContainer)` — creates a request-scoped child container, attaches it to `req.container`, and disposes it when the response finishes
|
|
13
|
+
- `containerMiddleware(appContainer, tags?)` — creates a request-scoped child container tagged `['request', ...tags]`, attaches it to `req.container`, and disposes it when the response finishes. Mount it per route with `route.tags` so registrations bound to a tag (`scope((s) => s.hasTag('admins'))`) apply to exactly the operations carrying it
|
|
14
14
|
- `getContainerOrFail(req)` — reads `req.container` or throws
|
|
15
15
|
|
|
16
16
|
## Usage
|
|
17
17
|
|
|
18
|
-
Register
|
|
19
|
-
operation. A reference `RouteBuilder` that does exactly this lives in
|
|
18
|
+
Register one use case per operation in an application container, keyed by its `operationId`, then register one
|
|
19
|
+
Express route per operation. A reference `RouteBuilder` that does exactly this lives in
|
|
20
|
+
[`__tests__/RouteBuilder.ts`](./__tests__/RouteBuilder.ts):
|
|
20
21
|
|
|
21
22
|
```typescript
|
|
22
23
|
import 'reflect-metadata';
|
|
23
24
|
import express from 'express';
|
|
24
25
|
import { Container, Registration } from 'ts-ioc-container';
|
|
25
|
-
import { containerMiddleware } from '@ibabkin/openapi-express-server';
|
|
26
26
|
import { PAYLOADS } from './generated-validators';
|
|
27
27
|
import { RouteBuilder } from './RouteBuilder';
|
|
28
28
|
|
|
29
29
|
const container = new Container({ tags: ['application'] });
|
|
30
|
-
container.addRegistration(Registration.fromClass(
|
|
30
|
+
container.addRegistration(Registration.fromClass(GetUsers).bindToKey('getUsers'));
|
|
31
|
+
container.addRegistration(Registration.fromClass(CreateUser).bindToKey('createUser'));
|
|
31
32
|
|
|
32
33
|
const app = express();
|
|
33
34
|
app.use(express.json());
|
|
34
|
-
app.use(containerMiddleware(container));
|
|
35
35
|
|
|
36
36
|
container.resolve(RouteBuilder, { args: [spec, PAYLOADS] }).applyTo(app);
|
|
37
37
|
|
|
@@ -40,8 +40,10 @@ app.use((error, req, res, next) => {
|
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Each
|
|
44
|
-
`
|
|
43
|
+
Each route mounts `containerMiddleware(container, route.tags)`, so every request gets a scope tagged with
|
|
44
|
+
`request` and the operation's tags. The handler resolves the use case from that scope under the `operationId`,
|
|
45
|
+
validates `req` with the Zod schema for the same `operationId`, calls `useCase.handle(payload, scope)`, and writes
|
|
46
|
+
`{ status, headers, body }` to the response.
|
|
45
47
|
|
|
46
48
|
## Development
|
|
47
49
|
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { RequestHandler, Request } from 'express-serve-static-core';
|
|
2
2
|
import { IContainer } from 'ts-ioc-container';
|
|
3
|
-
export declare
|
|
3
|
+
export declare const REQUEST_SCOPE_TAG = "request";
|
|
4
|
+
/**
|
|
5
|
+
* Creates a request-scoped container for every request that reaches it and disposes it when the
|
|
6
|
+
* response ends. Mounted per route with the route's `tags`, so registrations bound to a tag
|
|
7
|
+
* (`scope((s) => s.hasTag('admins'))`) apply to exactly the operations carrying it (SPEC-007 UC-6).
|
|
8
|
+
*/
|
|
9
|
+
export declare function containerMiddleware(appContainer: IContainer, tags?: string[]): RequestHandler;
|
|
4
10
|
export declare function getContainerOrFail(req: Request): IContainer;
|
|
5
11
|
//# sourceMappingURL=containerMiddleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerMiddleware.d.ts","sourceRoot":"","sources":["../lib/containerMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,UAAU,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"containerMiddleware.d.ts","sourceRoot":"","sources":["../lib/containerMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,UAAU,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,cAAc,CAqBjG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,cAK9C"}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const REQUEST_SCOPE_TAG = 'request';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a request-scoped container for every request that reaches it and disposes it when the
|
|
4
|
+
* response ends. Mounted per route with the route's `tags`, so registrations bound to a tag
|
|
5
|
+
* (`scope((s) => s.hasTag('admins'))`) apply to exactly the operations carrying it (SPEC-007 UC-6).
|
|
6
|
+
*/
|
|
7
|
+
export function containerMiddleware(appContainer, tags = []) {
|
|
2
8
|
return (req, res, next) => {
|
|
3
|
-
|
|
4
|
-
const requestScope = appContainer.createScope({ tags: ['request'] });
|
|
9
|
+
const requestScope = appContainer.createScope({ tags: [REQUEST_SCOPE_TAG, ...tags] });
|
|
5
10
|
// Attach to request
|
|
6
11
|
req.container = requestScope;
|
|
7
12
|
// Cleanup on response finish
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerMiddleware.js","sourceRoot":"","sources":["../lib/containerMiddleware.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,mBAAmB,CAAC,YAAwB;
|
|
1
|
+
{"version":3,"file":"containerMiddleware.js","sourceRoot":"","sources":["../lib/containerMiddleware.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAwB,EAAE,OAAiB,EAAE;IAC/E,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,MAAM,YAAY,GAAG,YAAY,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,CAAC,iBAAiB,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAEtF,oBAAoB;QACpB,GAAG,CAAC,SAAS,GAAG,YAAY,CAAC;QAE7B,6BAA6B;QAC7B,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACpB,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,mBAAmB;QACnB,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;gBACvB,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,GAAG,CAAC,SAAS,CAAC;AACvB,CAAC"}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { OpenAPIServerConfig, RouteMetadata, ErrorHandler,
|
|
1
|
+
export { OpenAPIServerConfig, RouteMetadata, ErrorHandler, UseCaseInstance } from './types.js';
|
|
2
2
|
export { buildPayload, Payload } from './payloadBuilder.js';
|
|
3
3
|
export { extractRoutes, convertOpenAPIPathToExpress } from './routeExtractor.js';
|
|
4
|
-
export { containerMiddleware, getContainerOrFail } from './containerMiddleware.js';
|
|
4
|
+
export { containerMiddleware, getContainerOrFail, REQUEST_SCOPE_TAG } from './containerMiddleware.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { buildPayload } from './payloadBuilder.js';
|
|
2
2
|
export { extractRoutes, convertOpenAPIPathToExpress } from './routeExtractor.js';
|
|
3
|
-
export { containerMiddleware, getContainerOrFail } from './containerMiddleware.js';
|
|
3
|
+
export { containerMiddleware, getContainerOrFail, REQUEST_SCOPE_TAG } from './containerMiddleware.js';
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAW,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAW,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeExtractor.d.ts","sourceRoot":"","sources":["../lib/routeExtractor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routeExtractor.d.ts","sourceRoot":"","sources":["../lib/routeExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,aAAa,EAAE,CA8BvE;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvE"}
|
package/esm/routeExtractor.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { toIdentifier } from '@ibabkin/openapi-to-server/identifier';
|
|
2
1
|
export function extractRoutes(spec) {
|
|
3
2
|
const routes = [];
|
|
4
3
|
if (!spec.paths) {
|
|
@@ -13,21 +12,12 @@ export function extractRoutes(spec) {
|
|
|
13
12
|
if (!operation || !operation.operationId) {
|
|
14
13
|
continue;
|
|
15
14
|
}
|
|
16
|
-
const tags = operation.tags || [];
|
|
17
|
-
const firstTag = tags[0];
|
|
18
|
-
if (!firstTag) {
|
|
19
|
-
console.warn(`Operation ${operation.operationId} has no tags, skipping`);
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
const controllerName = toIdentifier(firstTag);
|
|
23
|
-
const methodName = operation.operationId;
|
|
24
15
|
routes.push({
|
|
25
16
|
path,
|
|
26
17
|
method: method.toUpperCase(),
|
|
27
18
|
operationId: operation.operationId,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
methodName,
|
|
19
|
+
// Tags name nothing; they are attached to the request scope verbatim (SPEC-007 UC-5/UC-6).
|
|
20
|
+
tags: operation.tags ?? [],
|
|
31
21
|
});
|
|
32
22
|
}
|
|
33
23
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeExtractor.js","sourceRoot":"","sources":["../lib/routeExtractor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"routeExtractor.js","sourceRoot":"","sources":["../lib/routeExtractor.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,aAAa,CAAC,IAAwB;IACpD,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC,QAAQ;YAAE,SAAS;QAExB,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAU,CAAC;QAEtF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAA0C,CAAC;YAE5E,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;gBACzC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE;gBAC5B,WAAW,EAAE,SAAS,CAAC,WAAW;gBAClC,2FAA2F;gBAC3F,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,EAAE;aAC3B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,WAAmB;IAC7D,OAAO,WAAW,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC"}
|
package/esm/types.d.ts
CHANGED
|
@@ -3,21 +3,21 @@ import { OpenAPIV3 } from 'openapi-types';
|
|
|
3
3
|
import { IContainer } from 'ts-ioc-container';
|
|
4
4
|
export interface OpenAPIServerConfig {
|
|
5
5
|
spec: OpenAPIV3.Document;
|
|
6
|
-
|
|
6
|
+
/** One use case per operation, keyed by `operationId`. */
|
|
7
|
+
useCases: Record<string, any>;
|
|
7
8
|
basePath?: string;
|
|
8
9
|
errorHandler?: ErrorHandler;
|
|
9
10
|
}
|
|
11
|
+
/** One operation of the document. `operationId` is the DI key of its use case (SPEC-007 UC-4). */
|
|
10
12
|
export interface RouteMetadata {
|
|
11
13
|
path: string;
|
|
12
14
|
method: string;
|
|
13
15
|
operationId: string;
|
|
14
16
|
tags: string[];
|
|
15
|
-
controllerName: string;
|
|
16
|
-
methodName: string;
|
|
17
17
|
}
|
|
18
18
|
export type ErrorHandler = (error: Error, req: Request, res: Response, next: NextFunction) => void;
|
|
19
|
-
export interface
|
|
20
|
-
|
|
19
|
+
export interface UseCaseInstance {
|
|
20
|
+
handle(payload: any, context: IContainer): Promise<any>;
|
|
21
21
|
}
|
|
22
22
|
declare global {
|
|
23
23
|
namespace Express {
|
package/esm/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC;IACzB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;AAEnG,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACzD;AAED,OAAO,CAAC,MAAM,CAAC;IAEb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,SAAS,EAAE,UAAU,CAAC;SACvB;KACF;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ibabkin/openapi-express-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public",
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -43,8 +43,7 @@
|
|
|
43
43
|
"reflect-metadata": "^0.2.2",
|
|
44
44
|
"ts-ioc-container": "^68.0.0",
|
|
45
45
|
"zod": "^4.6.5",
|
|
46
|
-
"@ibabkin/openapi-to-
|
|
47
|
-
"@ibabkin/openapi-to-zod": "1.4.2"
|
|
46
|
+
"@ibabkin/openapi-to-zod": "1.4.3"
|
|
48
47
|
},
|
|
49
48
|
"devDependencies": {
|
|
50
49
|
"@jest/test-sequencer": "29.7.0",
|
|
@@ -59,12 +58,13 @@
|
|
|
59
58
|
"supertest": "^6.3.3",
|
|
60
59
|
"ts-jest": "29.4.12",
|
|
61
60
|
"tsx": "^4.23.13",
|
|
62
|
-
"typescript": "5.7.3"
|
|
61
|
+
"typescript": "5.7.3",
|
|
62
|
+
"@ibabkin/openapi-to-server": "3.0.0"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "pnpm run clean && pnpm run build:ts",
|
|
66
66
|
"test": "jest",
|
|
67
|
-
"test:generate:code": "tsx ./__tests__/generate.ts && prettier --write __tests__/
|
|
67
|
+
"test:generate:code": "tsx ./__tests__/generate.ts && prettier --write __tests__/operations.ts __tests__/validators.ts",
|
|
68
68
|
"test:watch": "jest --coverage --watch",
|
|
69
69
|
"clean": "rimraf esm *.tsbuildinfo",
|
|
70
70
|
"watch": "nodemon --watch lib --exec 'pnpm run compile'",
|