@backstage/backend-openapi-utils 0.0.2 → 0.0.3-next.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/CHANGELOG.md +8 -0
- package/README.md +51 -7
- package/dist/index.cjs.js +56 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +26 -6
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @backstage/backend-openapi-utils
|
|
2
2
|
|
|
3
|
+
## 0.0.3-next.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ebeb77586975: Add a new `createRouter` method for generating an `express` router that validates against your spec. Also fixes a bug with the query parameters type resolution.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/errors@1.2.1
|
|
10
|
+
|
|
3
11
|
## 0.0.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -13,16 +13,56 @@ This package is meant to provide a typed Express router for an OpenAPI spec. Bas
|
|
|
13
13
|
2. In your plugin's `src/service/createRouter.ts`,
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
|
-
import {
|
|
17
|
-
import spec from '../schema/openapi.generated';
|
|
16
|
+
import { createOpenApiRouter } from '../schema/openapi.generated';
|
|
18
17
|
// ...
|
|
19
18
|
export function createRouter() {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const router = createOpenApiRouter();
|
|
20
|
+
// add routes to router, it's just an express router.
|
|
21
|
+
return router;
|
|
23
22
|
}
|
|
24
23
|
```
|
|
25
24
|
|
|
25
|
+
3. Add `@backstage/backend-openapi-utils` to your `package.json`'s `dependencies`.
|
|
26
|
+
|
|
27
|
+
Why do I need to add this to `dependencies`? If you check the `src/schema/openapi.generated.ts` file, we're creating a router stub for you with the `@backstage/backend-openapi-utils` package.
|
|
28
|
+
|
|
29
|
+
### Customization
|
|
30
|
+
|
|
31
|
+
If the out of the box `router` doesn't work, you can do the following,
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { createOpenApiRouter } from '../schema/openapi.generated';
|
|
35
|
+
// ...
|
|
36
|
+
export function createRouter() {
|
|
37
|
+
// See https://github.com/cdimascio/express-openapi-validator/wiki/Documentation for available options.
|
|
38
|
+
const router = createOpenApiRouter(validatorOptions);
|
|
39
|
+
// add routes to router, it's just an express router.
|
|
40
|
+
return router;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If you need even more control -- say for example you wanted to update the spec at runtime -- you can do the following,
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { spec } from '../schema/openapi.generated';
|
|
48
|
+
import { createValidatedOpenApiRouter } from '@backstage/backend-openapi-utils';
|
|
49
|
+
// ...
|
|
50
|
+
export function createRouter() {
|
|
51
|
+
// Update the spec here.
|
|
52
|
+
const newSpec = { ...spec, myproperty123: 123 };
|
|
53
|
+
|
|
54
|
+
// See https://github.com/cdimascio/express-openapi-validator/wiki/Documentation for available options.
|
|
55
|
+
const router = createValidatedOpenApiRouter<typeof newSpec>(
|
|
56
|
+
newSpec,
|
|
57
|
+
validatorOptions,
|
|
58
|
+
);
|
|
59
|
+
// add routes to router, it's just an express router.
|
|
60
|
+
return router;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## INTERNAL
|
|
65
|
+
|
|
26
66
|
### Limitations
|
|
27
67
|
|
|
28
68
|
1. `as const` makes all fields `readonly`
|
|
@@ -40,6 +80,10 @@ Router() as ApiRouter<DeepWriteable<typeof spec>>
|
|
|
40
80
|
|
|
41
81
|
## Future Work
|
|
42
82
|
|
|
43
|
-
###
|
|
83
|
+
### Response Validation
|
|
84
|
+
|
|
85
|
+
This is a murky ground and something that will take a while to gain adoption. For now, keep responses in the spec and at the type level, but will need to work to drive adoption of response validation.
|
|
86
|
+
|
|
87
|
+
### Common Error Format
|
|
44
88
|
|
|
45
|
-
|
|
89
|
+
With the new `createRouter` method, we can start to control error response formats for input and coercion errors.
|
package/dist/index.cjs.js
CHANGED
|
@@ -2,9 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var PromiseRouter = require('express-promise-router');
|
|
6
|
+
var express = require('express');
|
|
7
|
+
var errors = require('@backstage/errors');
|
|
8
|
+
var expressOpenapiValidator = require('express-openapi-validator');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
|
+
|
|
12
|
+
var PromiseRouter__default = /*#__PURE__*/_interopDefaultLegacy(PromiseRouter);
|
|
13
|
+
|
|
5
14
|
var index = /*#__PURE__*/Object.freeze({
|
|
6
|
-
|
|
15
|
+
__proto__: null
|
|
7
16
|
});
|
|
8
17
|
|
|
18
|
+
const baseUrlSymbol = Symbol();
|
|
19
|
+
const originalUrlSymbol = Symbol();
|
|
20
|
+
function validatorErrorTransformer() {
|
|
21
|
+
return (error, _, _2, next) => {
|
|
22
|
+
next(new errors.InputError(error.message));
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function getDefaultRouterMiddleware() {
|
|
26
|
+
return [express.json()];
|
|
27
|
+
}
|
|
28
|
+
function createValidatedOpenApiRouter(spec, options) {
|
|
29
|
+
const router = PromiseRouter__default["default"]();
|
|
30
|
+
router.use((options == null ? void 0 : options.middleware) || getDefaultRouterMiddleware());
|
|
31
|
+
router.use((req, _, next) => {
|
|
32
|
+
const customRequest = req;
|
|
33
|
+
customRequest[baseUrlSymbol] = customRequest.baseUrl;
|
|
34
|
+
customRequest.baseUrl = "";
|
|
35
|
+
customRequest[originalUrlSymbol] = customRequest.originalUrl;
|
|
36
|
+
customRequest.originalUrl = customRequest.url;
|
|
37
|
+
next();
|
|
38
|
+
});
|
|
39
|
+
router.use(
|
|
40
|
+
expressOpenapiValidator.middleware({
|
|
41
|
+
validateRequests: {
|
|
42
|
+
coerceTypes: false,
|
|
43
|
+
allowUnknownQueryParameters: false
|
|
44
|
+
},
|
|
45
|
+
ignoreUndocumented: true,
|
|
46
|
+
validateResponses: false,
|
|
47
|
+
...options == null ? void 0 : options.validatorOptions,
|
|
48
|
+
apiSpec: spec
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
router.use((req, _, next) => {
|
|
52
|
+
const customRequest = req;
|
|
53
|
+
customRequest.baseUrl = customRequest[baseUrlSymbol];
|
|
54
|
+
customRequest.originalUrl = customRequest[originalUrlSymbol];
|
|
55
|
+
delete customRequest[baseUrlSymbol];
|
|
56
|
+
delete customRequest[originalUrlSymbol];
|
|
57
|
+
next();
|
|
58
|
+
});
|
|
59
|
+
router.use(validatorErrorTransformer());
|
|
60
|
+
return router;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
exports.createValidatedOpenApiRouter = createValidatedOpenApiRouter;
|
|
9
64
|
exports.internal = index;
|
|
10
65
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/stub.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport PromiseRouter from 'express-promise-router';\nimport { ApiRouter } from './router';\nimport { RequiredDoc } from './types';\nimport {\n ErrorRequestHandler,\n RequestHandler,\n NextFunction,\n Request,\n Response,\n json,\n} from 'express';\nimport { InputError } from '@backstage/errors';\nimport { middleware as OpenApiValidator } from 'express-openapi-validator';\n\ntype PropertyOverrideRequest = Request & {\n [key: symbol]: string;\n};\n\nconst baseUrlSymbol = Symbol();\nconst originalUrlSymbol = Symbol();\n\nfunction validatorErrorTransformer(): ErrorRequestHandler {\n return (error: Error, _: Request, _2: Response, next: NextFunction) => {\n next(new InputError(error.message));\n };\n}\n\nexport function getDefaultRouterMiddleware() {\n return [json()];\n}\n\n/**\n * Create a new OpenAPI router with some default middleware.\n * @param spec - Your OpenAPI spec imported as a JSON object.\n * @param validatorOptions - `openapi-express-validator` options to override the defaults.\n * @returns A new express router with validation middleware.\n * @public\n */\nexport function createValidatedOpenApiRouter<T extends RequiredDoc>(\n spec: T,\n options?: {\n validatorOptions?: Partial<Parameters<typeof OpenApiValidator>['0']>;\n middleware?: RequestHandler[];\n },\n) {\n const router = PromiseRouter() as ApiRouter<typeof spec>;\n router.use(options?.middleware || getDefaultRouterMiddleware());\n\n /**\n * Middleware to setup the routing for OpenApiValidator. OpenApiValidator expects `req.originalUrl`\n * and `req.baseUrl` to be the full path. We adjust them here to basically be nothing and then\n * revive the old values in the last function in this method. We could instead update `req.path`\n * but that might affect the routing and I'd rather not.\n *\n * TODO: I opened https://github.com/cdimascio/express-openapi-validator/issues/843\n * to track this on the middleware side, but there was a similar ticket, https://github.com/cdimascio/express-openapi-validator/issues/113\n * that has had minimal activity. If that changes, update this to use a new option on their side.\n */\n router.use((req: Request, _, next) => {\n /**\n * Express typings are weird. They don't recognize PropertyOverrideRequest as a valid\n * Request child and try to overload as PathParams. Just cast it here, since we know\n * what we're doing.\n */\n const customRequest = req as PropertyOverrideRequest;\n customRequest[baseUrlSymbol] = customRequest.baseUrl;\n customRequest.baseUrl = '';\n customRequest[originalUrlSymbol] = customRequest.originalUrl;\n customRequest.originalUrl = customRequest.url;\n next();\n });\n\n // TODO: Handle errors by converting from OpenApiValidator errors to known @backstage/errors errors.\n router.use(\n OpenApiValidator({\n validateRequests: {\n coerceTypes: false,\n allowUnknownQueryParameters: false,\n },\n ignoreUndocumented: true,\n validateResponses: false,\n ...options?.validatorOptions,\n apiSpec: spec as any,\n }),\n );\n\n /**\n * Revert `req.baseUrl` and `req.originalUrl` changes. This ensures that any further usage\n * of these variables will be unchanged.\n */\n router.use((req: Request, _, next) => {\n const customRequest = req as PropertyOverrideRequest;\n customRequest.baseUrl = customRequest[baseUrlSymbol];\n customRequest.originalUrl = customRequest[originalUrlSymbol];\n delete customRequest[baseUrlSymbol];\n delete customRequest[originalUrlSymbol];\n next();\n });\n\n // Any errors from the middleware get through here.\n router.use(validatorErrorTransformer());\n\n return router;\n}\n"],"names":["InputError","json","PromiseRouter","OpenApiValidator"],"mappings":";;;;;;;;;;;;;;;;;AAkCA,MAAM,gBAAgB,MAAO,EAAA,CAAA;AAC7B,MAAM,oBAAoB,MAAO,EAAA,CAAA;AAEjC,SAAS,yBAAiD,GAAA;AACxD,EAAA,OAAO,CAAC,KAAA,EAAc,CAAY,EAAA,EAAA,EAAc,IAAuB,KAAA;AACrE,IAAA,IAAA,CAAK,IAAIA,iBAAA,CAAW,KAAM,CAAA,OAAO,CAAC,CAAA,CAAA;AAAA,GACpC,CAAA;AACF,CAAA;AAEO,SAAS,0BAA6B,GAAA;AAC3C,EAAO,OAAA,CAACC,cAAM,CAAA,CAAA;AAChB,CAAA;AASgB,SAAA,4BAAA,CACd,MACA,OAIA,EAAA;AACA,EAAA,MAAM,SAASC,iCAAc,EAAA,CAAA;AAC7B,EAAA,MAAA,CAAO,GAAI,CAAA,CAAA,OAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAS,UAAc,KAAA,0BAAA,EAA4B,CAAA,CAAA;AAY9D,EAAA,MAAA,CAAO,GAAI,CAAA,CAAC,GAAc,EAAA,CAAA,EAAG,IAAS,KAAA;AAMpC,IAAA,MAAM,aAAgB,GAAA,GAAA,CAAA;AACtB,IAAc,aAAA,CAAA,aAAa,IAAI,aAAc,CAAA,OAAA,CAAA;AAC7C,IAAA,aAAA,CAAc,OAAU,GAAA,EAAA,CAAA;AACxB,IAAc,aAAA,CAAA,iBAAiB,IAAI,aAAc,CAAA,WAAA,CAAA;AACjD,IAAA,aAAA,CAAc,cAAc,aAAc,CAAA,GAAA,CAAA;AAC1C,IAAK,IAAA,EAAA,CAAA;AAAA,GACN,CAAA,CAAA;AAGD,EAAO,MAAA,CAAA,GAAA;AAAA,IACLC,kCAAiB,CAAA;AAAA,MACf,gBAAkB,EAAA;AAAA,QAChB,WAAa,EAAA,KAAA;AAAA,QACb,2BAA6B,EAAA,KAAA;AAAA,OAC/B;AAAA,MACA,kBAAoB,EAAA,IAAA;AAAA,MACpB,iBAAmB,EAAA,KAAA;AAAA,MACnB,GAAG,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,gBAAA;AAAA,MACZ,OAAS,EAAA,IAAA;AAAA,KACV,CAAA;AAAA,GACH,CAAA;AAMA,EAAA,MAAA,CAAO,GAAI,CAAA,CAAC,GAAc,EAAA,CAAA,EAAG,IAAS,KAAA;AACpC,IAAA,MAAM,aAAgB,GAAA,GAAA,CAAA;AACtB,IAAc,aAAA,CAAA,OAAA,GAAU,cAAc,aAAa,CAAA,CAAA;AACnD,IAAc,aAAA,CAAA,WAAA,GAAc,cAAc,iBAAiB,CAAA,CAAA;AAC3D,IAAA,OAAO,cAAc,aAAa,CAAA,CAAA;AAClC,IAAA,OAAO,cAAc,iBAAiB,CAAA,CAAA;AACtC,IAAK,IAAA,EAAA,CAAA;AAAA,GACN,CAAA,CAAA;AAGD,EAAO,MAAA,CAAA,GAAA,CAAI,2BAA2B,CAAA,CAAA;AAEtC,EAAO,OAAA,MAAA,CAAA;AACT;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { JSONSchema7, FromSchema } from 'json-schema-to-ts';
|
|
2
2
|
import { ReferenceObject, OpenAPIObject, ContentObject, RequestBodyObject, ResponseObject, ParameterObject, SchemaObject } from 'openapi3-ts';
|
|
3
3
|
import core from 'express-serve-static-core';
|
|
4
|
-
import { Router } from 'express';
|
|
4
|
+
import { Router, RequestHandler } from 'express';
|
|
5
|
+
import { middleware } from 'express-openapi-validator';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* This file is meant to hold Immutable overwrites of the values provided by the `openapi3-ts`
|
|
@@ -279,11 +280,16 @@ type Filter<T, U> = T extends U ? T : never;
|
|
|
279
280
|
*/
|
|
280
281
|
type DocParameter<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path], Parameter extends keyof Doc['paths'][Path][Method]['parameters']> = DocOperation<Doc, Path, Method>['parameters'][Parameter] extends ImmutableReferenceObject ? 'parameters' extends ComponentTypes<Doc> ? ComponentRef<Doc, 'parameters', DocOperation<Doc, Path, Method>['parameters'][Parameter]> : never : DocOperation<Doc, Path, Method>['parameters'][Parameter];
|
|
281
282
|
/**
|
|
283
|
+
* Helper to convert from string to number, used to index arrays and pull out just the indices in the array.
|
|
282
284
|
* @public
|
|
283
285
|
*/
|
|
284
|
-
type
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
type FromNumberStringToNumber<NumberString extends string | number | symbol> = NumberString extends `${infer R extends number}` ? R : never;
|
|
287
|
+
/**
|
|
288
|
+
* @public
|
|
289
|
+
*/
|
|
290
|
+
type DocParameters<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path]> = {
|
|
291
|
+
[Index in keyof DocOperation<Doc, Path, Method>['parameters'] as FromNumberStringToNumber<Index>]: DocParameter<Doc, Path, Method, Index>;
|
|
292
|
+
};
|
|
287
293
|
/**
|
|
288
294
|
* @public
|
|
289
295
|
*/
|
|
@@ -297,7 +303,7 @@ type MapToSchema<Doc extends RequiredDoc, T extends Record<string, ImmutablePara
|
|
|
297
303
|
/**
|
|
298
304
|
* @public
|
|
299
305
|
*/
|
|
300
|
-
type ParametersSchema<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path], FilterType extends ImmutableParameterObject> =
|
|
306
|
+
type ParametersSchema<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path], FilterType extends ImmutableParameterObject> = MapToSchema<Doc, FullMap<MapDiscriminatedUnion<Filter<ValueOf<DocParameters<Doc, Path, Method>>, FilterType>, 'name'>>>;
|
|
301
307
|
/**
|
|
302
308
|
* @public
|
|
303
309
|
*/
|
|
@@ -433,6 +439,7 @@ type index_d_PathObject = PathObject;
|
|
|
433
439
|
type index_d_ImmutablePathObject = ImmutablePathObject;
|
|
434
440
|
type index_d_ImmutableSchemaObject = ImmutableSchemaObject;
|
|
435
441
|
type index_d_DocParameter<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path], Parameter extends keyof Doc['paths'][Path][Method]['parameters']> = DocParameter<Doc, Path, Method, Parameter>;
|
|
442
|
+
type index_d_FromNumberStringToNumber<NumberString extends string | number | symbol> = FromNumberStringToNumber<NumberString>;
|
|
436
443
|
type index_d_DocParameters<Doc extends RequiredDoc, Path extends Extract<keyof Doc['paths'], string>, Method extends keyof Doc['paths'][Path]> = DocParameters<Doc, Path, Method>;
|
|
437
444
|
type index_d_ParameterSchema<Doc extends RequiredDoc, Schema extends ImmutableParameterObject['schema']> = ParameterSchema<Doc, Schema>;
|
|
438
445
|
type index_d_MapToSchema<Doc extends RequiredDoc, T extends Record<string, ImmutableParameterObject>> = MapToSchema<Doc, T>;
|
|
@@ -498,6 +505,7 @@ declare namespace index_d {
|
|
|
498
505
|
index_d_ImmutablePathObject as ImmutablePathObject,
|
|
499
506
|
index_d_ImmutableSchemaObject as ImmutableSchemaObject,
|
|
500
507
|
index_d_DocParameter as DocParameter,
|
|
508
|
+
index_d_FromNumberStringToNumber as FromNumberStringToNumber,
|
|
501
509
|
index_d_DocParameters as DocParameters,
|
|
502
510
|
index_d_ParameterSchema as ParameterSchema,
|
|
503
511
|
index_d_MapToSchema as MapToSchema,
|
|
@@ -530,4 +538,16 @@ interface ApiRouter<Doc extends RequiredDoc> extends Router {
|
|
|
530
538
|
head: DocRequestMatcher<Doc, this, 'head'>;
|
|
531
539
|
}
|
|
532
540
|
|
|
533
|
-
|
|
541
|
+
/**
|
|
542
|
+
* Create a new OpenAPI router with some default middleware.
|
|
543
|
+
* @param spec - Your OpenAPI spec imported as a JSON object.
|
|
544
|
+
* @param validatorOptions - `openapi-express-validator` options to override the defaults.
|
|
545
|
+
* @returns A new express router with validation middleware.
|
|
546
|
+
* @public
|
|
547
|
+
*/
|
|
548
|
+
declare function createValidatedOpenApiRouter<T extends RequiredDoc>(spec: T, options?: {
|
|
549
|
+
validatorOptions?: Partial<Parameters<typeof middleware>['0']>;
|
|
550
|
+
middleware?: RequestHandler[];
|
|
551
|
+
}): ApiRouter<T>;
|
|
552
|
+
|
|
553
|
+
export { ApiRouter, createValidatedOpenApiRouter, index_d as internal };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/backend-openapi-utils",
|
|
3
3
|
"description": "OpenAPI typescript support.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3-next.0",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -24,17 +24,21 @@
|
|
|
24
24
|
"postpack": "backstage-cli package postpack"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@backstage/cli": "^0.22.
|
|
27
|
+
"@backstage/cli": "^0.22.10-next.0",
|
|
28
|
+
"supertest": "^6.1.3"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"dist"
|
|
31
32
|
],
|
|
32
33
|
"dependencies": {
|
|
34
|
+
"@backstage/errors": "^1.2.1",
|
|
33
35
|
"@types/express": "^4.17.6",
|
|
34
36
|
"@types/express-serve-static-core": "^4.17.5",
|
|
35
37
|
"express": "^4.17.1",
|
|
38
|
+
"express-openapi-validator": "^5.0.4",
|
|
36
39
|
"express-promise-router": "^4.1.0",
|
|
37
40
|
"json-schema-to-ts": "^2.6.2",
|
|
41
|
+
"lodash": "^4.17.21",
|
|
38
42
|
"openapi3-ts": "^3.1.2"
|
|
39
43
|
},
|
|
40
44
|
"module": "dist/index.esm.js"
|