@ehuelsmann/openapi-validator 0.16.2 → 0.17.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 CHANGED
@@ -4,9 +4,88 @@
4
4
 
5
5
  [![downloads](https://img.shields.io/npm/dm/@ehuelsmann%2Fopenapi-validator)](https://www.npmjs.com/package/@ehuelsmann/openapi-validator)
6
6
  [![npm](https://img.shields.io/npm/v/@ehuelsmann%2Fopenapi-validator.svg)](https://www.npmjs.com/package/@ehuelsmann/openapi-validator)
7
+ ![build status](https://github.com/ehuelsmann/OpenAPIValidators/actions/workflows/ci.yml/badge.svg)
8
+ ![style](https://img.shields.io/badge/code%20style-airbnb-ff5a5f.svg)
9
+ [![codecov](https://codecov.io/gh/ehuelsmann/OpenAPIValidators/branch/master/graph/badge.svg)](https://codecov.io/gh/ehuelsmann/OpenAPIValidators)
10
+ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/ehuelsmann/OpenAPIValidators/blob/master/CONTRIBUTING.md)
7
11
 
8
12
  **Note** This project is a fork from the [openapi-library](https://github.com/openapi-library) project because that project is not maintained at the moment. This project contains updates and security fixes, but ideally will be merged back into that project, as soon as it's maintained again.
9
13
 
14
+ Common code for [@ehuelsmann/jest-openapi](https://www.npmjs.com/package/@ehuelsmann/jest-openapi) and [Chai OpenAPI Response Validator](https://www.npmjs.com/package/@ehuelsmann/chai-openapi-response-validator)
10
15
 
16
+ ## Keywords
11
17
 
12
- Common code for [@ehuelsmann/jest-openapi](https://www.npmjs.com/package/@ehuelsmann/jest-openapi) and [Chai OpenAPI Response Validator](https://www.npmjs.com/package/@ehuelsmann/chai-openapi-response-validator)
18
+ `openapi` `swagger` `validate` `response` `testing` `jest` `chai` `http` `api` `schema`
19
+
20
+ ## Contributing ✨
21
+
22
+ If you've come here to help contribute - thanks! Take a look at the [contributing](https://github.com/ehuelsmann/OpenAPIValidators/blob/master/CONTRIBUTING.md) docs to get started.
23
+
24
+ ## Installation
25
+
26
+ [npm](http://npmjs.org)
27
+
28
+ ```bash
29
+ npm install --save-dev @ehuelsmann/openapi-validator
30
+ ```
31
+
32
+ [yarn](https://yarnpkg.com/)
33
+
34
+ ```bash
35
+ yarn add --dev @ehuelsmann/openapi-validator
36
+ ```
37
+
38
+ ## Importing
39
+
40
+ This package ships with both **ESM** (preferred) and **CommonJS** builds, so it works in any environment.
41
+
42
+ ESM / TypeScript
43
+
44
+ ```typescript
45
+ import { makeApiSpec, makeResponse } from '@ehuelsmann/openapi-validator';
46
+ ```
47
+
48
+ CommonJS / JavaScript
49
+
50
+ ```javascript
51
+ const { makeApiSpec, makeResponse } = require('@ehuelsmann/openapi-validator');
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ This package provides the shared validation logic used by [@ehuelsmann/jest-openapi](https://www.npmjs.com/package/@ehuelsmann/jest-openapi) and [@ehuelsmann/chai-openapi-response-validator](https://www.npmjs.com/package/@ehuelsmann/chai-openapi-response-validator). Use it to build your own OpenAPI validation integration.
57
+
58
+ ### Loading an OpenAPI spec
59
+
60
+ `makeApiSpec` accepts either an absolute filepath or an object representing an OpenAPI (v2 or v3) document:
61
+
62
+ ```typescript
63
+ import { makeApiSpec } from '@ehuelsmann/openapi-validator';
64
+
65
+ // From an absolute filepath (YAML or JSON)
66
+ const spec = makeApiSpec('/absolute/path/to/openapi.yml');
67
+
68
+ // From an object
69
+ const spec = makeApiSpec({
70
+ openapi: '3.0.0',
71
+ info: { title: 'Example API', version: '1.0.0' },
72
+ paths: {},
73
+ });
74
+ ```
75
+
76
+ ### Validating a response
77
+
78
+ `makeResponse` wraps an HTTP response from `axios`, `supertest`, `superagent`, or `chai-http` so it can be validated against the loaded spec:
79
+
80
+ ```typescript
81
+ import { makeApiSpec, makeResponse } from '@ehuelsmann/openapi-validator';
82
+
83
+ const spec = makeApiSpec('/absolute/path/to/openapi.yml');
84
+
85
+ // res is an axios, supertest, superagent, or chai-http response object
86
+ const response = makeResponse(res);
87
+ const validationError = spec.validateResponse(response);
88
+ if (validationError) {
89
+ throw new Error(validationError.message);
90
+ }
91
+ ```
package/dist/index.js CHANGED
@@ -69,10 +69,7 @@ var import_path_parser = require("path-parser");
69
69
  var import_url = __toESM(require("url"));
70
70
  var import_util = require("util");
71
71
  var stringify = (obj) => (0, import_util.inspect)(obj, { depth: null });
72
- var getPathname = (request) => (
73
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
74
- import_url.default.parse(request.path).pathname
75
- );
72
+ var getPathname = (request) => import_url.default.parse(request.path).pathname;
76
73
  var convertOpenApiPathToColonForm = (openApiPath) => openApiPath.replace(/{/g, ":").replace(/}/g, "");
77
74
  var doesColonPathMatchPathname = (pathInColonForm, pathname) => {
78
75
  const pathWithoutCommas = pathname.replace(/,/g, "");
@@ -104,6 +101,8 @@ var getPathnameWithoutBasePath = (basePath, pathname) => basePath === defaultBas
104
101
 
105
102
  // lib/classes/AbstractOpenApiSpec.ts
106
103
  var import_openapi_response_validator = __toESM(require("openapi-response-validator"));
104
+ var _a;
105
+ var OpenAPIResponseValidator = (_a = import_openapi_response_validator.default.default) != null ? _a : import_openapi_response_validator.default;
107
106
  var OpenApiSpec = class {
108
107
  constructor(spec) {
109
108
  this.spec = spec;
@@ -118,8 +117,8 @@ var OpenApiSpec = class {
118
117
  return Object.keys(this.pathsObject());
119
118
  }
120
119
  getSchemaObject(schemaName) {
121
- var _a2;
122
- return (_a2 = this.getSchemaObjects()) == null ? void 0 : _a2[schemaName];
120
+ var _a3;
121
+ return (_a3 = this.getSchemaObjects()) == null ? void 0 : _a3[schemaName];
123
122
  }
124
123
  getExpectedResponse(responseOperation, status) {
125
124
  const response = responseOperation.responses[status];
@@ -173,7 +172,7 @@ var OpenApiSpec = class {
173
172
  }
174
173
  throw error;
175
174
  }
176
- const validator = new import_openapi_response_validator.default({
175
+ const validator = new OpenAPIResponseValidator({
177
176
  responses: expectedResponse,
178
177
  ...this.getComponentDefinitionsProperty()
179
178
  });
@@ -198,10 +197,9 @@ var OpenApiSpec = class {
198
197
  validateObject(actualObject, schema) {
199
198
  const mockResStatus = "200";
200
199
  const mockExpectedResponse = { [mockResStatus]: { schema } };
201
- const validator = new import_openapi_response_validator.default({
200
+ const validator = new OpenAPIResponseValidator({
202
201
  responses: mockExpectedResponse,
203
202
  ...this.getComponentDefinitionsProperty(),
204
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
205
203
  errorTransformer: ({ path: path2, message }) => ({
206
204
  message: `${path2.replace("response", "object")} ${message}`
207
205
  })
@@ -245,9 +243,9 @@ var OpenApi2Spec = class extends OpenApiSpec {
245
243
  return openApiPath;
246
244
  }
247
245
  findResponseDefinition(referenceString) {
248
- var _a2;
246
+ var _a3;
249
247
  const nameOfResponseDefinition = referenceString.split("#/responses/")[1];
250
- return (_a2 = this.spec.responses) == null ? void 0 : _a2[nameOfResponseDefinition];
248
+ return (_a3 = this.spec.responses) == null ? void 0 : _a3[nameOfResponseDefinition];
251
249
  }
252
250
  getComponentDefinitionsProperty() {
253
251
  return { definitions: this.spec.definitions };
@@ -369,24 +367,24 @@ var OpenApi3Spec = class extends OpenApiSpec {
369
367
  return openApiPath;
370
368
  }
371
369
  findResponseDefinition(referenceString) {
372
- var _a2, _b;
370
+ var _a3, _b;
373
371
  const nameOfResponseDefinition = referenceString.split(
374
372
  "#/components/responses/"
375
373
  )[1];
376
- return (_b = (_a2 = this.spec.components) == null ? void 0 : _a2.responses) == null ? void 0 : _b[nameOfResponseDefinition];
374
+ return (_b = (_a3 = this.spec.components) == null ? void 0 : _a3.responses) == null ? void 0 : _b[nameOfResponseDefinition];
377
375
  }
378
376
  getComponentDefinitionsProperty() {
379
377
  return { components: this.spec.components };
380
378
  }
381
379
  getSchemaObjects() {
382
- var _a2;
383
- return (_a2 = this.spec.components) == null ? void 0 : _a2.schemas;
380
+ var _a3;
381
+ return (_a3 = this.spec.components) == null ? void 0 : _a3.schemas;
384
382
  }
385
383
  };
386
384
 
387
385
  // lib/openApiSpecFactory.ts
388
- var _a;
389
- var OpenAPISchemaValidator = (_a = import_openapi_schema_validator.default.default) != null ? _a : import_openapi_schema_validator.default;
386
+ var _a2;
387
+ var OpenAPISchemaValidator = (_a2 = import_openapi_schema_validator.default.default) != null ? _a2 : import_openapi_schema_validator.default;
390
388
  var isObject = (arg) => typeof arg === "object" && arg !== null && !Array.isArray(arg);
391
389
  function makeApiSpec(filepathOrObject) {
392
390
  const spec = loadSpec(filepathOrObject);
@@ -409,7 +407,8 @@ function loadSpec(arg) {
409
407
  } catch (error) {
410
408
  throw new Error(
411
409
  `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.
412
- Error details: ${error.message}`
410
+ Error details: ${error.message}`,
411
+ { cause: error }
413
412
  );
414
413
  }
415
414
  }
@@ -422,7 +421,7 @@ function loadFile(filepath) {
422
421
  return import_js_yaml.default.load(fileData);
423
422
  } catch (error) {
424
423
  throw new Error(`Invalid YAML or JSON:
425
- ${error.message}`);
424
+ ${error.message}`, { cause: error });
426
425
  }
427
426
  }
428
427
  function validateSpec(obj) {
@@ -438,7 +437,7 @@ function validateSpec(obj) {
438
437
  }
439
438
  return obj;
440
439
  } catch (error) {
441
- throw new Error(`Invalid OpenAPI spec: ${error.message}`);
440
+ throw new Error(`Invalid OpenAPI spec: ${error.message}`, { cause: error });
442
441
  }
443
442
  }
444
443
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/index.ts","../lib/classes/errors/ValidationError.ts","../lib/openApiSpecFactory.ts","../lib/utils/common.utils.ts","../lib/classes/AbstractOpenApiSpec.ts","../lib/classes/OpenApi2Spec.ts","../lib/utils/OpenApi3Spec.utils.ts","../lib/classes/OpenApi3Spec.ts","../lib/classes/AbstractResponse.ts","../lib/classes/AxiosResponse.ts","../lib/classes/SuperAgentResponse.ts","../lib/responseFactory.ts"],"sourcesContent":["import type { OpenAPI } from 'openapi-types';\nimport type OpenApi2Spec from './classes/OpenApi2Spec';\nimport type OpenApi3Spec from './classes/OpenApi3Spec';\n\nexport type { Schema } from './classes/AbstractOpenApiSpec';\nexport type {\n ActualRequest,\n ActualResponse,\n RawResponse,\n} from './classes/AbstractResponse';\nexport type { default as ValidationError } from './classes/errors/ValidationError';\nexport { ErrorCode } from './classes/errors/ValidationError';\nexport type { default as OpenApi2Spec } from './classes/OpenApi2Spec';\nexport type { default as OpenApi3Spec } from './classes/OpenApi3Spec';\nexport { default as makeApiSpec } from './openApiSpecFactory';\nexport { default as makeResponse } from './responseFactory';\n\nexport type OpenApiSpec = OpenApi2Spec | OpenApi3Spec;\nexport type OpenAPISpecObject = OpenAPI.Document;\n","export enum ErrorCode {\n ServerNotFound,\n BasePathNotFound,\n PathNotFound,\n MethodNotFound,\n StatusNotFound,\n InvalidBody,\n InvalidObject,\n}\n\nexport default class ValidationError extends Error {\n constructor(\n public code: ErrorCode,\n message?: string,\n ) {\n super(message);\n }\n\n override toString(): string {\n return this.message;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport OpenAPISchemaValidatorModule from 'openapi-schema-validator';\nimport type { OpenAPI, OpenAPIV2, OpenAPIV3 } from 'openapi-types';\nimport path from 'path';\nimport typeOf from 'typeof';\nimport OpenApi2Spec from './classes/OpenApi2Spec';\nimport OpenApi3Spec from './classes/OpenApi3Spec';\nimport { stringify } from './utils/common.utils';\n\n// openapi-schema-validator is a CommonJS module that sets `exports.__esModule = true`\n// and exports the class via `exports.default`. When imported natively as ESM, Node.js\n// exposes the whole `module.exports` object as the default, so we must unwrap `.default`\n// to get the actual constructor. The `??` fallback covers the CJS build context where\n// the bundler (esbuild/__toESM) has already unwrapped it for us.\nconst OpenAPISchemaValidator = (\n (\n OpenAPISchemaValidatorModule as unknown as {\n default?: typeof OpenAPISchemaValidatorModule;\n }\n ).default ?? OpenAPISchemaValidatorModule\n);\n\ntype AnyObject = Record<string, unknown>;\n\nconst isObject = (arg: unknown): arg is AnyObject =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg);\n\nexport default function makeApiSpec(\n filepathOrObject: string | OpenAPI.Document,\n): OpenApi2Spec | OpenApi3Spec {\n const spec = loadSpec(filepathOrObject);\n validateSpec(spec);\n const validSpec = spec as OpenAPI.Document;\n if ('swagger' in validSpec) {\n return new OpenApi2Spec(validSpec);\n }\n return new OpenApi3Spec(validSpec as OpenAPIV3.Document);\n}\n\nfunction loadSpec(arg: unknown): AnyObject {\n try {\n if (typeof arg === 'string') {\n return loadFile(arg);\n }\n if (isObject(arg)) {\n return arg;\n }\n throw new Error(`Received type '${typeOf(arg)}'`);\n } catch (error) {\n throw new Error(\n `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.\\nError details: ${\n (error as Error).message\n }`,\n );\n }\n}\n\nfunction loadFile(filepath: string): AnyObject {\n if (!path.isAbsolute(filepath)) {\n throw new Error(`'${filepath}' is not an absolute filepath`);\n }\n const fileData = fs.readFileSync(filepath, { encoding: 'utf8' });\n try {\n return yaml.load(fileData) as AnyObject;\n } catch (error) {\n throw new Error(`Invalid YAML or JSON:\\n${(error as Error).message}`);\n }\n}\n\nfunction validateSpec(obj: AnyObject): OpenAPI.Document {\n try {\n const validator = new OpenAPISchemaValidator({\n version:\n (obj as unknown as OpenAPIV2.Document).swagger || // '2.0'\n (obj as unknown as OpenAPIV3.Document).openapi, // '3.X.X'\n });\n const { errors } = validator.validate(obj as OpenAPI.Document);\n if (errors.length > 0) {\n throw new Error(stringify(errors));\n }\n return obj as OpenAPI.Document;\n } catch (error) {\n throw new Error(`Invalid OpenAPI spec: ${(error as Error).message}`);\n }\n}\n","import { Path } from 'path-parser';\nimport url from 'url';\nimport { inspect } from 'util';\nimport type { ActualRequest } from '../classes/AbstractResponse';\n\nexport const stringify = (obj: unknown): string =>\n inspect(obj, { depth: null });\n\n/**\n * Excludes the query because path = pathname + query\n */\nexport const getPathname = (request: ActualRequest): string =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n url.parse(request.path).pathname!;\n\n/**\n * Converts all {foo} to :foo\n */\nconst convertOpenApiPathToColonForm = (openApiPath: string): string =>\n openApiPath.replace(/{/g, ':').replace(/}/g, '');\n\nconst doesColonPathMatchPathname = (\n pathInColonForm: string,\n pathname: string,\n): boolean => {\n /*\n * By default, OpenAPI path parameters have `style: simple; explode: false` (https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)\n * So array path parameters in the pathname of the actual request should be in the form: `/pathParams/a,b,c`\n * `path-parser` fails to match parameter patterns to parameters containing commas.\n * So we remove the commas.\n */\n const pathWithoutCommas = pathname.replace(/,/g, '');\n const pathParamsInPathname = new Path(pathInColonForm).test(\n pathWithoutCommas,\n ); // => one of: null, {}, {exampleParam: 'foo'}\n return Boolean(pathParamsInPathname);\n};\n\nconst doesOpenApiPathMatchPathname = (\n openApiPath: string,\n pathname: string,\n): boolean => {\n const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);\n return doesColonPathMatchPathname(pathInColonForm, pathname);\n};\n\nexport const findOpenApiPathMatchingPossiblePathnames = (\n possiblePathnames: string[],\n OAPaths: string[],\n): string | undefined => {\n let openApiPath: string | undefined;\n // eslint-disable-next-line no-restricted-syntax\n for (const pathname of possiblePathnames) {\n // eslint-disable-next-line no-restricted-syntax\n for (const OAPath of OAPaths) {\n if (OAPath === pathname) {\n return OAPath;\n }\n if (doesOpenApiPathMatchPathname(OAPath, pathname)) {\n openApiPath = OAPath;\n }\n }\n }\n return openApiPath;\n};\n\nexport const defaultBasePath = '/';\n\nexport const getPathnameWithoutBasePath = (\n basePath: string,\n pathname: string,\n): string =>\n basePath === defaultBasePath ? pathname : pathname.replace(basePath, '');\n","import OpenAPIResponseValidator, {\n type OpenAPIResponseValidatorArgs,\n} from 'openapi-response-validator';\nimport type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport { getPathname } from '../utils/common.utils';\nimport type { ActualRequest, ActualResponse } from './AbstractResponse';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\ntype Document = OpenAPIV2.Document | OpenAPIV3.Document;\n\ntype Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;\n\ntype HttpMethods = OpenAPIV2.HttpMethods;\n\ntype PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;\n\nexport type ResponseObjectWithSchema =\n | (OpenAPIV2.ResponseObject & { schema: OpenAPIV2.Schema })\n | (OpenAPIV3.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3.MediaTypeObject & {\n schema: OpenAPIV3.SchemaObject;\n };\n };\n })\n | (OpenAPIV3_1.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3_1.MediaTypeObject & {\n schema: OpenAPIV3_1.SchemaObject;\n };\n };\n });\n\nexport type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;\n\nexport default abstract class OpenApiSpec {\n protected abstract getSchemaObjects(): Record<string, Schema> | undefined;\n\n protected abstract findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined;\n\n protected abstract findOpenApiPathMatchingPathname(pathname: string): string;\n\n protected abstract getComponentDefinitionsProperty():\n | {\n definitions: OpenAPIV2.Document['definitions'];\n }\n | {\n components: OpenAPIV3.Document['components'];\n };\n\n constructor(protected spec: Document) {}\n\n pathsObject(): Document['paths'] {\n return this.spec.paths;\n }\n\n getPathItem(openApiPath: string): PathItemObject {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.pathsObject()[openApiPath]!;\n }\n\n paths(): string[] {\n return Object.keys(this.pathsObject());\n }\n\n getSchemaObject(schemaName: string): Schema | undefined {\n return this.getSchemaObjects()?.[schemaName];\n }\n\n getExpectedResponse(\n responseOperation: Operation,\n status: ActualResponse['status'],\n ): ResponseObjectWithSchema | undefined {\n const response = responseOperation.responses[status];\n if (!response) {\n return undefined;\n }\n if ('$ref' in response) {\n return this.findResponseDefinition(response.$ref);\n }\n return response as ResponseObjectWithSchema;\n }\n\n findExpectedResponse(\n actualResponse: ActualResponse,\n ): Record<string, ResponseObjectWithSchema> {\n const actualRequest = actualResponse.req;\n const expectedResponseOperation =\n this.findExpectedResponseOperation(actualRequest);\n if (!expectedResponseOperation) {\n throw new ValidationError(ErrorCode.MethodNotFound);\n }\n\n const { status } = actualResponse;\n const expectedResponse = this.getExpectedResponse(\n expectedResponseOperation,\n status,\n );\n if (!expectedResponse) {\n throw new ValidationError(ErrorCode.StatusNotFound);\n }\n\n return { [status]: expectedResponse };\n }\n\n findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n return openApiPath;\n }\n\n findExpectedPathItem(actualRequest: ActualRequest): PathItemObject {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n const pathItemObject = this.getPathItem(openApiPath);\n return pathItemObject;\n }\n\n findExpectedResponseOperation(\n actualRequest: ActualRequest,\n ): Operation | undefined {\n const pathItemObject = this.findExpectedPathItem(actualRequest);\n const operationObject =\n pathItemObject[actualRequest.method.toLowerCase() as HttpMethods];\n return operationObject;\n }\n\n validateResponse(actualResponse: ActualResponse): ValidationError | null {\n let expectedResponse: Record<string, ResponseObjectWithSchema>;\n try {\n expectedResponse = this.findExpectedResponse(actualResponse);\n } catch (error) {\n if (error instanceof ValidationError) {\n return error;\n }\n throw error;\n }\n const validator = new OpenAPIResponseValidator({\n responses: expectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n } as OpenAPIResponseValidatorArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const expectedResStatus = Object.keys(expectedResponse)[0]!;\n const validationError = validator.validateResponse(\n expectedResStatus,\n actualResponse.getBodyForValidation(),\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidBody,\n validationError.errors!\n .map(({ path, message }: { path?: string; message: string }) => `${path} ${message}`)\n .join(', '),\n )\n : null;\n }\n\n /*\n * For consistency and to save maintaining another dependency,\n * we validate objects using our response validator:\n * We put the object inside a mock response, then validate\n * the whole response against a mock expected response.\n * The 2 mock responses are identical except for the body,\n * thus validating the object against its schema.\n */\n validateObject(\n actualObject: unknown,\n schema: Schema,\n ): ValidationError | null {\n const mockResStatus = '200';\n const mockExpectedResponse = { [mockResStatus]: { schema } };\n const validator = new OpenAPIResponseValidator({\n responses: mockExpectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n errorTransformer: ({ path, message }: { path?: string; message: string; errorCode: string }) => ({\n message: `${path!.replace('response', 'object')} ${message}`,\n }),\n } as OpenAPIResponseValidatorArgs);\n const validationError = validator.validateResponse(\n mockResStatus,\n actualObject,\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidObject,\n validationError.errors!.map((error: { message: string }) => error.message).join(', '),\n )\n : null;\n }\n}\n","import type { OpenAPIV2 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n getPathnameWithoutBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n} from '../utils/common.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nconst basePathPropertyNotProvided = (spec: OpenAPIV2.Document): boolean =>\n !spec.basePath;\n\nexport default class OpenApi2Spec extends AbstractOpenApiSpec {\n public didUserDefineBasePath: boolean;\n\n constructor(public override spec: OpenAPIV2.Document) {\n super(spec);\n this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);\n }\n\n /**\n * \"If the basePath property is not provided, the API is served directly under the host\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields\n */\n findOpenApiPathMatchingPathname(pathname: string): string {\n const { basePath } = this.spec;\n if (basePath && !pathname.startsWith(basePath)) {\n throw new ValidationError(ErrorCode.BasePathNotFound);\n }\n const pathnameWithoutBasePath = basePath\n ? getPathnameWithoutBasePath(basePath, pathname)\n : pathname;\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n [pathnameWithoutBasePath],\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split('#/responses/')[1]!;\n return this.spec.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n definitions: OpenAPIV2.Document['definitions'];\n } {\n return { definitions: this.spec.definitions };\n }\n\n getSchemaObjects(): OpenAPIV2.Document['definitions'] {\n return this.spec.definitions;\n }\n}\n","import generateCombinations from 'combos';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { defaultBasePath } from './common.utils';\n\ntype ServerVariables = OpenAPIV3.ServerObject['variables'];\n\nconst unique = <T>(array: T[]): T[] => [...new Set(array)];\n\nexport const serversPropertyNotProvidedOrIsEmptyArray = (\n spec: OpenAPIV3.Document,\n): boolean => !spec.servers || !spec.servers.length;\n\nconst getBasePath = (url: string): string => {\n const basePathStartIndex = url.replace('//', ' ').indexOf('/');\n return basePathStartIndex !== -1\n ? url.slice(basePathStartIndex)\n : defaultBasePath;\n};\n\nconst getPossibleValuesOfServerVariable = ({\n default: defaultValue,\n enum: enumMembers,\n}: OpenAPIV3.ServerVariableObject): string[] =>\n enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];\n\nconst mapServerVariablesToPossibleValues = (\n serverVariables: NonNullable<ServerVariables>,\n): Record<string, string[]> =>\n Object.entries(serverVariables).reduce(\n (currentMap, [variableName, detailsOfPossibleValues]) => ({\n ...currentMap,\n [variableName]: getPossibleValuesOfServerVariable(\n detailsOfPossibleValues,\n ),\n }),\n {},\n );\n\nconst convertTemplateExpressionToConcreteExpression = (\n templateExpression: string,\n mapOfVariablesToValues: Record<string, string>,\n) =>\n Object.entries(mapOfVariablesToValues).reduce(\n (currentExpression, [variable, value]) =>\n currentExpression.replace(`{${variable}}`, value),\n templateExpression,\n );\n\nconst getPossibleConcreteBasePaths = (\n basePath: string,\n serverVariables: NonNullable<ServerVariables>,\n): string[] => {\n const mapOfServerVariablesToPossibleValues =\n mapServerVariablesToPossibleValues(serverVariables);\n const combinationsOfBasePathVariableValues = generateCombinations(\n mapOfServerVariablesToPossibleValues,\n );\n const possibleBasePaths = combinationsOfBasePathVariableValues.map(\n (mapOfVariablesToValues) =>\n convertTemplateExpressionToConcreteExpression(\n basePath,\n mapOfVariablesToValues,\n ),\n );\n return possibleBasePaths;\n};\n\nconst getPossibleBasePaths = (\n url: string,\n serverVariables: ServerVariables,\n): string[] => {\n const basePath = getBasePath(url);\n return serverVariables\n ? getPossibleConcreteBasePaths(basePath, serverVariables)\n : [basePath];\n};\n\nexport const getMatchingServerUrlsAndServerBasePaths = (\n servers: OpenAPIV3.ServerObject[],\n pathname: string,\n): { concreteUrl: string; matchingBasePath: string }[] => {\n const matchesPathname = (basePath: string): boolean =>\n pathname.startsWith(basePath);\n return servers\n .map(({ url: templatedUrl, variables }) => ({\n templatedUrl,\n possibleBasePaths: getPossibleBasePaths(templatedUrl, variables),\n }))\n .filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname))\n .map(({ templatedUrl, possibleBasePaths }) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const matchingBasePath = possibleBasePaths.find(matchesPathname)!;\n return {\n concreteUrl: templatedUrl.replace(\n getBasePath(templatedUrl),\n matchingBasePath,\n ),\n matchingBasePath,\n };\n });\n};\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n defaultBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n getPathnameWithoutBasePath,\n} from '../utils/common.utils';\nimport {\n serversPropertyNotProvidedOrIsEmptyArray,\n getMatchingServerUrlsAndServerBasePaths,\n} from '../utils/OpenApi3Spec.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nexport default class OpenApi3Spec extends AbstractOpenApiSpec {\n public didUserDefineServers: boolean;\n\n constructor(protected override spec: OpenAPIV3.Document) {\n super(spec);\n this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);\n this.ensureDefaultServer();\n }\n\n /**\n * \"If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of '/'\"\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields\n */\n ensureDefaultServer(): void {\n if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {\n this.spec.servers = [{ url: defaultBasePath }];\n }\n }\n\n servers(): OpenAPIV3.ServerObject[] {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.spec.servers!;\n }\n\n getServerUrls(): string[] {\n return this.servers().map((server) => server.url);\n }\n\n getMatchingServerUrls(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ concreteUrl }) => concreteUrl);\n }\n\n getMatchingServerBasePaths(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ matchingBasePath }) => matchingBasePath);\n }\n\n findOpenApiPathMatchingPathname(pathname: string): string {\n const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);\n if (!matchingServerBasePaths.length) {\n throw new ValidationError(ErrorCode.ServerNotFound);\n }\n const possiblePathnames = matchingServerBasePaths.map((basePath) =>\n getPathnameWithoutBasePath(basePath, pathname),\n );\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n possiblePathnames,\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split(\n '#/components/responses/',\n )[1]!;\n return this.spec.components?.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n components: OpenAPIV3.Document['components'];\n } {\n return { components: this.spec.components };\n }\n\n getSchemaObjects(): OpenAPIV3.ComponentsObject['schemas'] {\n return this.spec.components?.schemas;\n }\n}\n","import { stringify } from '../utils/common.utils';\nimport type { RawAxiosResponse } from './AxiosResponse';\nimport type { RawSuperAgentResponse } from './SuperAgentResponse';\n\nexport type RawResponse =\n | RawAxiosResponse\n | RawSuperAgentResponse;\n\nexport default abstract class AbstractResponse {\n declare public status: number;\n\n declare public req: { method: string; path: string };\n\n public abstract getBodyForValidation(): unknown;\n\n protected body: unknown;\n\n declare protected bodyHasNoContent: boolean;\n\n constructor(protected res: RawResponse) {}\n\n summary(): { body: unknown } {\n return {\n body: this.body,\n };\n }\n\n toString(): string {\n return stringify(this.summary());\n }\n}\n\nexport type ActualResponse = AbstractResponse;\n\nexport type ActualRequest = AbstractResponse['req'];\n","import type { AxiosResponse as AxiosResponseType } from 'axios';\nimport AbstractResponse from './AbstractResponse';\n\nexport type RawAxiosResponse = AxiosResponseType;\n\nexport default class AxiosResponse extends AbstractResponse {\n constructor(protected override res: RawAxiosResponse) {\n super(res);\n this.status = res.status;\n this.body = res.data;\n this.req = res.request;\n this.bodyHasNoContent = this.body === '';\n }\n\n getBodyForValidation(): AxiosResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n return this.body;\n }\n}\n","import type { Response, SuperAgentRequest } from 'superagent';\nimport AbstractResponse from './AbstractResponse';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst isEmptyObj = (obj: any): obj is Record<string, never> =>\n !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;\n\nexport type RawSuperAgentResponse = Response & {\n req: SuperAgentRequest & { path: string };\n};\n\nexport default class SuperAgentResponse extends AbstractResponse {\n private isResTextPopulatedInsteadOfResBody: boolean;\n\n constructor(protected override res: RawSuperAgentResponse) {\n super(res);\n this.status = res.status;\n this.body = res.body;\n this.req = res.req;\n this.isResTextPopulatedInsteadOfResBody =\n res.text !== '{}' && isEmptyObj(this.body);\n this.bodyHasNoContent = res.text === '';\n }\n\n getBodyForValidation(): SuperAgentResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n if (this.isResTextPopulatedInsteadOfResBody) {\n return this.res.text;\n }\n return this.body;\n }\n\n override summary(): ReturnType<AbstractResponse['summary']> & {\n text?: string;\n } {\n return {\n ...super.summary(),\n ...(this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }),\n };\n }\n}\n","import { RawResponse } from './classes/AbstractResponse';\nimport AxiosResponse from './classes/AxiosResponse';\nimport SuperAgentResponse from './classes/SuperAgentResponse';\n\nexport default function makeResponse(\n res: RawResponse,\n): AxiosResponse | SuperAgentResponse {\n if ('data' in res) {\n return new AxiosResponse(res);\n }\n if ('status' in res) {\n return new SuperAgentResponse(res);\n }\n throw new Error(\n 'Unsupported response object: expected axios, supertest, superagent, or chai-http response shape.',\n );\n}\n"],"mappings":"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","names":["ErrorCode","url","_a","OpenAPIResponseValidator","path","_a","url","generateCombinations","_a","OpenAPISchemaValidatorModule","typeOf","path","fs","yaml"]}
1
+ {"version":3,"sources":["../lib/index.ts","../lib/classes/errors/ValidationError.ts","../lib/openApiSpecFactory.ts","../lib/utils/common.utils.ts","../lib/classes/AbstractOpenApiSpec.ts","../lib/classes/OpenApi2Spec.ts","../lib/utils/OpenApi3Spec.utils.ts","../lib/classes/OpenApi3Spec.ts","../lib/classes/AbstractResponse.ts","../lib/classes/AxiosResponse.ts","../lib/classes/SuperAgentResponse.ts","../lib/responseFactory.ts"],"sourcesContent":["import type { OpenAPI } from 'openapi-types';\nimport type OpenApi2Spec from './classes/OpenApi2Spec';\nimport type OpenApi3Spec from './classes/OpenApi3Spec';\n\nexport type { Schema } from './classes/AbstractOpenApiSpec';\nexport type {\n ActualRequest,\n ActualResponse,\n RawResponse,\n} from './classes/AbstractResponse';\nexport type { default as ValidationError } from './classes/errors/ValidationError';\nexport { ErrorCode } from './classes/errors/ValidationError';\nexport type { default as OpenApi2Spec } from './classes/OpenApi2Spec';\nexport type { default as OpenApi3Spec } from './classes/OpenApi3Spec';\nexport { default as makeApiSpec } from './openApiSpecFactory';\nexport { default as makeResponse } from './responseFactory';\n\nexport type OpenApiSpec = OpenApi2Spec | OpenApi3Spec;\nexport type OpenAPISpecObject = OpenAPI.Document;\n","export enum ErrorCode {\n ServerNotFound,\n BasePathNotFound,\n PathNotFound,\n MethodNotFound,\n StatusNotFound,\n InvalidBody,\n InvalidObject,\n}\n\nexport default class ValidationError extends Error {\n constructor(\n public code: ErrorCode,\n message?: string,\n ) {\n super(message);\n }\n\n override toString(): string {\n return this.message;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport OpenAPISchemaValidatorModule from 'openapi-schema-validator';\nimport type { OpenAPI, OpenAPIV2, OpenAPIV3 } from 'openapi-types';\nimport path from 'path';\nimport typeOf from 'typeof';\nimport OpenApi2Spec from './classes/OpenApi2Spec';\nimport OpenApi3Spec from './classes/OpenApi3Spec';\nimport { stringify } from './utils/common.utils';\n\n// openapi-schema-validator is a CommonJS module that sets `exports.__esModule = true`\n// and exports the class via `exports.default`. When imported natively as ESM, Node.js\n// exposes the whole `module.exports` object as the default, so we must unwrap `.default`\n// to get the actual constructor. The `??` fallback covers the CJS build context where\n// the bundler (esbuild/__toESM) has already unwrapped it for us.\nconst OpenAPISchemaValidator = (\n (\n OpenAPISchemaValidatorModule as unknown as {\n default?: typeof OpenAPISchemaValidatorModule;\n }\n ).default ?? OpenAPISchemaValidatorModule\n);\n\ntype AnyObject = Record<string, unknown>;\n\nconst isObject = (arg: unknown): arg is AnyObject =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg);\n\nexport default function makeApiSpec(\n filepathOrObject: string | OpenAPI.Document,\n): OpenApi2Spec | OpenApi3Spec {\n const spec = loadSpec(filepathOrObject);\n validateSpec(spec);\n const validSpec = spec as OpenAPI.Document;\n if ('swagger' in validSpec) {\n return new OpenApi2Spec(validSpec);\n }\n return new OpenApi3Spec(validSpec as OpenAPIV3.Document);\n}\n\nfunction loadSpec(arg: unknown): AnyObject {\n try {\n if (typeof arg === 'string') {\n return loadFile(arg);\n }\n if (isObject(arg)) {\n return arg;\n }\n throw new Error(`Received type '${typeOf(arg)}'`);\n } catch (error) {\n throw new Error(\n `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.\\nError details: ${\n (error as Error).message\n }`,\n { cause: error },\n );\n }\n}\n\nfunction loadFile(filepath: string): AnyObject {\n if (!path.isAbsolute(filepath)) {\n throw new Error(`'${filepath}' is not an absolute filepath`);\n }\n const fileData = fs.readFileSync(filepath, { encoding: 'utf8' });\n try {\n return yaml.load(fileData) as AnyObject;\n } catch (error) {\n throw new Error(`Invalid YAML or JSON:\\n${(error as Error).message}`, { cause: error });\n }\n}\n\nfunction validateSpec(obj: AnyObject): OpenAPI.Document {\n try {\n const validator = new OpenAPISchemaValidator({\n version:\n (obj as unknown as OpenAPIV2.Document).swagger || // '2.0'\n (obj as unknown as OpenAPIV3.Document).openapi, // '3.X.X'\n });\n const { errors } = validator.validate(obj as OpenAPI.Document);\n if (errors.length > 0) {\n throw new Error(stringify(errors));\n }\n return obj as OpenAPI.Document;\n } catch (error) {\n throw new Error(`Invalid OpenAPI spec: ${(error as Error).message}`, { cause: error });\n }\n}\n","import { Path } from 'path-parser';\nimport url from 'url';\nimport { inspect } from 'util';\nimport type { ActualRequest } from '../classes/AbstractResponse';\n\nexport const stringify = (obj: unknown): string =>\n inspect(obj, { depth: null });\n\n/**\n * Excludes the query because path = pathname + query\n */\nexport const getPathname = (request: ActualRequest): string =>\n \n url.parse(request.path).pathname!;\n\n/**\n * Converts all {foo} to :foo\n */\nconst convertOpenApiPathToColonForm = (openApiPath: string): string =>\n openApiPath.replace(/{/g, ':').replace(/}/g, '');\n\nconst doesColonPathMatchPathname = (\n pathInColonForm: string,\n pathname: string,\n): boolean => {\n /*\n * By default, OpenAPI path parameters have `style: simple; explode: false` (https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)\n * So array path parameters in the pathname of the actual request should be in the form: `/pathParams/a,b,c`\n * `path-parser` fails to match parameter patterns to parameters containing commas.\n * So we remove the commas.\n */\n const pathWithoutCommas = pathname.replace(/,/g, '');\n const pathParamsInPathname = new Path(pathInColonForm).test(\n pathWithoutCommas,\n ); // => one of: null, {}, {exampleParam: 'foo'}\n return Boolean(pathParamsInPathname);\n};\n\nconst doesOpenApiPathMatchPathname = (\n openApiPath: string,\n pathname: string,\n): boolean => {\n const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);\n return doesColonPathMatchPathname(pathInColonForm, pathname);\n};\n\nexport const findOpenApiPathMatchingPossiblePathnames = (\n possiblePathnames: string[],\n OAPaths: string[],\n): string | undefined => {\n let openApiPath: string | undefined;\n // eslint-disable-next-line no-restricted-syntax\n for (const pathname of possiblePathnames) {\n // eslint-disable-next-line no-restricted-syntax\n for (const OAPath of OAPaths) {\n if (OAPath === pathname) {\n return OAPath;\n }\n if (doesOpenApiPathMatchPathname(OAPath, pathname)) {\n openApiPath = OAPath;\n }\n }\n }\n return openApiPath;\n};\n\nexport const defaultBasePath = '/';\n\nexport const getPathnameWithoutBasePath = (\n basePath: string,\n pathname: string,\n): string =>\n basePath === defaultBasePath ? pathname : pathname.replace(basePath, '');\n","import OpenAPIResponseValidatorModule, {\n type OpenAPIResponseValidatorArgs,\n} from 'openapi-response-validator';\nimport type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport { getPathname } from '../utils/common.utils';\nimport type { ActualRequest, ActualResponse } from './AbstractResponse';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\ntype Document = OpenAPIV2.Document | OpenAPIV3.Document;\n\ntype Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;\n\ntype HttpMethods = OpenAPIV2.HttpMethods;\n\ntype PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;\n\nconst OpenAPIResponseValidator = (\n OpenAPIResponseValidatorModule as unknown as {\n default?: typeof OpenAPIResponseValidatorModule;\n }\n).default ?? OpenAPIResponseValidatorModule;\n\nexport type ResponseObjectWithSchema =\n | (OpenAPIV2.ResponseObject & { schema: OpenAPIV2.Schema })\n | (OpenAPIV3.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3.MediaTypeObject & {\n schema: OpenAPIV3.SchemaObject;\n };\n };\n })\n | (OpenAPIV3_1.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3_1.MediaTypeObject & {\n schema: OpenAPIV3_1.SchemaObject;\n };\n };\n });\n\nexport type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;\n\nexport default abstract class OpenApiSpec {\n protected abstract getSchemaObjects(): Record<string, Schema> | undefined;\n\n protected abstract findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined;\n\n protected abstract findOpenApiPathMatchingPathname(pathname: string): string;\n\n protected abstract getComponentDefinitionsProperty():\n | {\n definitions: OpenAPIV2.Document['definitions'];\n }\n | {\n components: OpenAPIV3.Document['components'];\n };\n\n constructor(protected spec: Document) {}\n\n pathsObject(): Document['paths'] {\n return this.spec.paths;\n }\n\n getPathItem(openApiPath: string): PathItemObject {\n \n return this.pathsObject()[openApiPath]!;\n }\n\n paths(): string[] {\n return Object.keys(this.pathsObject());\n }\n\n getSchemaObject(schemaName: string): Schema | undefined {\n return this.getSchemaObjects()?.[schemaName];\n }\n\n getExpectedResponse(\n responseOperation: Operation,\n status: ActualResponse['status'],\n ): ResponseObjectWithSchema | undefined {\n const response = responseOperation.responses[status];\n if (!response) {\n return undefined;\n }\n if ('$ref' in response) {\n return this.findResponseDefinition(response.$ref);\n }\n return response as ResponseObjectWithSchema;\n }\n\n findExpectedResponse(\n actualResponse: ActualResponse,\n ): Record<string, ResponseObjectWithSchema> {\n const actualRequest = actualResponse.req;\n const expectedResponseOperation =\n this.findExpectedResponseOperation(actualRequest);\n if (!expectedResponseOperation) {\n throw new ValidationError(ErrorCode.MethodNotFound);\n }\n\n const { status } = actualResponse;\n const expectedResponse = this.getExpectedResponse(\n expectedResponseOperation,\n status,\n );\n if (!expectedResponse) {\n throw new ValidationError(ErrorCode.StatusNotFound);\n }\n\n return { [status]: expectedResponse };\n }\n\n findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n return openApiPath;\n }\n\n findExpectedPathItem(actualRequest: ActualRequest): PathItemObject {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n const pathItemObject = this.getPathItem(openApiPath);\n return pathItemObject;\n }\n\n findExpectedResponseOperation(\n actualRequest: ActualRequest,\n ): Operation | undefined {\n const pathItemObject = this.findExpectedPathItem(actualRequest);\n const operationObject =\n pathItemObject[actualRequest.method.toLowerCase() as HttpMethods];\n return operationObject;\n }\n\n validateResponse(actualResponse: ActualResponse): ValidationError | null {\n let expectedResponse: Record<string, ResponseObjectWithSchema>;\n try {\n expectedResponse = this.findExpectedResponse(actualResponse);\n } catch (error) {\n if (error instanceof ValidationError) {\n return error;\n }\n throw error;\n }\n const validator = new OpenAPIResponseValidator({\n responses: expectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n } as OpenAPIResponseValidatorArgs);\n\n \n const expectedResStatus = Object.keys(expectedResponse)[0]!;\n const validationError = validator.validateResponse(\n expectedResStatus,\n actualResponse.getBodyForValidation(),\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidBody,\n validationError.errors!\n .map(({ path, message }: { path?: string; message: string }) => `${path} ${message}`)\n .join(', '),\n )\n : null;\n }\n\n /*\n * For consistency and to save maintaining another dependency,\n * we validate objects using our response validator:\n * We put the object inside a mock response, then validate\n * the whole response against a mock expected response.\n * The 2 mock responses are identical except for the body,\n * thus validating the object against its schema.\n */\n validateObject(\n actualObject: unknown,\n schema: Schema,\n ): ValidationError | null {\n const mockResStatus = '200';\n const mockExpectedResponse = { [mockResStatus]: { schema } };\n const validator = new OpenAPIResponseValidator({\n responses: mockExpectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n \n errorTransformer: ({ path, message }: { path?: string; message: string; errorCode: string }) => ({\n message: `${path!.replace('response', 'object')} ${message}`,\n }),\n } as OpenAPIResponseValidatorArgs);\n const validationError = validator.validateResponse(\n mockResStatus,\n actualObject,\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidObject,\n validationError.errors!.map((error: { message: string }) => error.message).join(', '),\n )\n : null;\n }\n}\n","import type { OpenAPIV2 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n getPathnameWithoutBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n} from '../utils/common.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nconst basePathPropertyNotProvided = (spec: OpenAPIV2.Document): boolean =>\n !spec.basePath;\n\nexport default class OpenApi2Spec extends AbstractOpenApiSpec {\n public didUserDefineBasePath: boolean;\n\n constructor(public override spec: OpenAPIV2.Document) {\n super(spec);\n this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);\n }\n\n /**\n * \"If the basePath property is not provided, the API is served directly under the host\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields\n */\n findOpenApiPathMatchingPathname(pathname: string): string {\n const { basePath } = this.spec;\n if (basePath && !pathname.startsWith(basePath)) {\n throw new ValidationError(ErrorCode.BasePathNotFound);\n }\n const pathnameWithoutBasePath = basePath\n ? getPathnameWithoutBasePath(basePath, pathname)\n : pathname;\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n [pathnameWithoutBasePath],\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n \n const nameOfResponseDefinition = referenceString.split('#/responses/')[1]!;\n return this.spec.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n definitions: OpenAPIV2.Document['definitions'];\n } {\n return { definitions: this.spec.definitions };\n }\n\n getSchemaObjects(): OpenAPIV2.Document['definitions'] {\n return this.spec.definitions;\n }\n}\n","import generateCombinations from 'combos';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { defaultBasePath } from './common.utils';\n\ntype ServerVariables = OpenAPIV3.ServerObject['variables'];\n\nconst unique = <T>(array: T[]): T[] => [...new Set(array)];\n\nexport const serversPropertyNotProvidedOrIsEmptyArray = (\n spec: OpenAPIV3.Document,\n): boolean => !spec.servers || !spec.servers.length;\n\nconst getBasePath = (url: string): string => {\n const basePathStartIndex = url.replace('//', ' ').indexOf('/');\n return basePathStartIndex !== -1\n ? url.slice(basePathStartIndex)\n : defaultBasePath;\n};\n\nconst getPossibleValuesOfServerVariable = ({\n default: defaultValue,\n enum: enumMembers,\n}: OpenAPIV3.ServerVariableObject): string[] =>\n enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];\n\nconst mapServerVariablesToPossibleValues = (\n serverVariables: NonNullable<ServerVariables>,\n): Record<string, string[]> =>\n Object.entries(serverVariables).reduce(\n (currentMap, [variableName, detailsOfPossibleValues]) => ({\n ...currentMap,\n [variableName]: getPossibleValuesOfServerVariable(\n detailsOfPossibleValues,\n ),\n }),\n {},\n );\n\nconst convertTemplateExpressionToConcreteExpression = (\n templateExpression: string,\n mapOfVariablesToValues: Record<string, string>,\n) =>\n Object.entries(mapOfVariablesToValues).reduce(\n (currentExpression, [variable, value]) =>\n currentExpression.replace(`{${variable}}`, value),\n templateExpression,\n );\n\nconst getPossibleConcreteBasePaths = (\n basePath: string,\n serverVariables: NonNullable<ServerVariables>,\n): string[] => {\n const mapOfServerVariablesToPossibleValues =\n mapServerVariablesToPossibleValues(serverVariables);\n const combinationsOfBasePathVariableValues = generateCombinations(\n mapOfServerVariablesToPossibleValues,\n );\n const possibleBasePaths = combinationsOfBasePathVariableValues.map(\n (mapOfVariablesToValues) =>\n convertTemplateExpressionToConcreteExpression(\n basePath,\n mapOfVariablesToValues,\n ),\n );\n return possibleBasePaths;\n};\n\nconst getPossibleBasePaths = (\n url: string,\n serverVariables: ServerVariables,\n): string[] => {\n const basePath = getBasePath(url);\n return serverVariables\n ? getPossibleConcreteBasePaths(basePath, serverVariables)\n : [basePath];\n};\n\nexport const getMatchingServerUrlsAndServerBasePaths = (\n servers: OpenAPIV3.ServerObject[],\n pathname: string,\n): { concreteUrl: string; matchingBasePath: string }[] => {\n const matchesPathname = (basePath: string): boolean =>\n pathname.startsWith(basePath);\n return servers\n .map(({ url: templatedUrl, variables }) => ({\n templatedUrl,\n possibleBasePaths: getPossibleBasePaths(templatedUrl, variables),\n }))\n .filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname))\n .map(({ templatedUrl, possibleBasePaths }) => {\n \n const matchingBasePath = possibleBasePaths.find(matchesPathname)!;\n return {\n concreteUrl: templatedUrl.replace(\n getBasePath(templatedUrl),\n matchingBasePath,\n ),\n matchingBasePath,\n };\n });\n};\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n defaultBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n getPathnameWithoutBasePath,\n} from '../utils/common.utils';\nimport {\n serversPropertyNotProvidedOrIsEmptyArray,\n getMatchingServerUrlsAndServerBasePaths,\n} from '../utils/OpenApi3Spec.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nexport default class OpenApi3Spec extends AbstractOpenApiSpec {\n public didUserDefineServers: boolean;\n\n constructor(protected override spec: OpenAPIV3.Document) {\n super(spec);\n this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);\n this.ensureDefaultServer();\n }\n\n /**\n * \"If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of '/'\"\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields\n */\n ensureDefaultServer(): void {\n if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {\n this.spec.servers = [{ url: defaultBasePath }];\n }\n }\n\n servers(): OpenAPIV3.ServerObject[] {\n \n return this.spec.servers!;\n }\n\n getServerUrls(): string[] {\n return this.servers().map((server) => server.url);\n }\n\n getMatchingServerUrls(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ concreteUrl }) => concreteUrl);\n }\n\n getMatchingServerBasePaths(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ matchingBasePath }) => matchingBasePath);\n }\n\n findOpenApiPathMatchingPathname(pathname: string): string {\n const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);\n if (!matchingServerBasePaths.length) {\n throw new ValidationError(ErrorCode.ServerNotFound);\n }\n const possiblePathnames = matchingServerBasePaths.map((basePath) =>\n getPathnameWithoutBasePath(basePath, pathname),\n );\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n possiblePathnames,\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n \n const nameOfResponseDefinition = referenceString.split(\n '#/components/responses/',\n )[1]!;\n return this.spec.components?.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n components: OpenAPIV3.Document['components'];\n } {\n return { components: this.spec.components };\n }\n\n getSchemaObjects(): OpenAPIV3.ComponentsObject['schemas'] {\n return this.spec.components?.schemas;\n }\n}\n","import { stringify } from '../utils/common.utils';\nimport type { RawAxiosResponse } from './AxiosResponse';\nimport type { RawSuperAgentResponse } from './SuperAgentResponse';\n\nexport type RawResponse =\n | RawAxiosResponse\n | RawSuperAgentResponse;\n\nexport default abstract class AbstractResponse {\n declare public status: number;\n\n declare public req: { method: string; path: string };\n\n public abstract getBodyForValidation(): unknown;\n\n protected body: unknown;\n\n declare protected bodyHasNoContent: boolean;\n\n constructor(protected res: RawResponse) {}\n\n summary(): { body: unknown } {\n return {\n body: this.body,\n };\n }\n\n toString(): string {\n return stringify(this.summary());\n }\n}\n\nexport type ActualResponse = AbstractResponse;\n\nexport type ActualRequest = AbstractResponse['req'];\n","import type { AxiosResponse as AxiosResponseType } from 'axios';\nimport AbstractResponse from './AbstractResponse';\n\nexport type RawAxiosResponse = AxiosResponseType;\n\nexport default class AxiosResponse extends AbstractResponse {\n constructor(protected override res: RawAxiosResponse) {\n super(res);\n this.status = res.status;\n this.body = res.data;\n this.req = res.request;\n this.bodyHasNoContent = this.body === '';\n }\n\n getBodyForValidation(): AxiosResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n return this.body;\n }\n}\n","import type { Response, SuperAgentRequest } from 'superagent';\nimport AbstractResponse from './AbstractResponse';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst isEmptyObj = (obj: any): obj is Record<string, never> =>\n !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;\n\nexport type RawSuperAgentResponse = Response & {\n req: SuperAgentRequest & { path: string };\n};\n\nexport default class SuperAgentResponse extends AbstractResponse {\n private isResTextPopulatedInsteadOfResBody: boolean;\n\n constructor(protected override res: RawSuperAgentResponse) {\n super(res);\n this.status = res.status;\n this.body = res.body;\n this.req = res.req;\n this.isResTextPopulatedInsteadOfResBody =\n res.text !== '{}' && isEmptyObj(this.body);\n this.bodyHasNoContent = res.text === '';\n }\n\n getBodyForValidation(): SuperAgentResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n if (this.isResTextPopulatedInsteadOfResBody) {\n return this.res.text;\n }\n return this.body;\n }\n\n override summary(): ReturnType<AbstractResponse['summary']> & {\n text?: string;\n } {\n return {\n ...super.summary(),\n ...(this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }),\n };\n }\n}\n","import { RawResponse } from './classes/AbstractResponse';\nimport AxiosResponse from './classes/AxiosResponse';\nimport SuperAgentResponse from './classes/SuperAgentResponse';\n\nexport default function makeResponse(\n res: RawResponse,\n): AxiosResponse | SuperAgentResponse {\n if ('data' in res) {\n return new AxiosResponse(res);\n }\n if ('status' in res) {\n return new SuperAgentResponse(res);\n }\n throw new Error(\n 'Unsupported response object: expected axios, supertest, superagent, or chai-http response shape.',\n );\n}\n"],"mappings":"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","names":["ErrorCode","url","OpenAPIResponseValidatorModule","_a","path","_a","url","generateCombinations","_a","_a","OpenAPISchemaValidatorModule","typeOf","path","fs","yaml"]}
package/dist/index.mjs CHANGED
@@ -31,10 +31,7 @@ import { Path } from "path-parser";
31
31
  import url from "url";
32
32
  import { inspect } from "util";
33
33
  var stringify = (obj) => inspect(obj, { depth: null });
34
- var getPathname = (request) => (
35
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
- url.parse(request.path).pathname
37
- );
34
+ var getPathname = (request) => url.parse(request.path).pathname;
38
35
  var convertOpenApiPathToColonForm = (openApiPath) => openApiPath.replace(/{/g, ":").replace(/}/g, "");
39
36
  var doesColonPathMatchPathname = (pathInColonForm, pathname) => {
40
37
  const pathWithoutCommas = pathname.replace(/,/g, "");
@@ -65,7 +62,9 @@ var defaultBasePath = "/";
65
62
  var getPathnameWithoutBasePath = (basePath, pathname) => basePath === defaultBasePath ? pathname : pathname.replace(basePath, "");
66
63
 
67
64
  // lib/classes/AbstractOpenApiSpec.ts
68
- import OpenAPIResponseValidator from "openapi-response-validator";
65
+ import OpenAPIResponseValidatorModule from "openapi-response-validator";
66
+ var _a;
67
+ var OpenAPIResponseValidator = (_a = OpenAPIResponseValidatorModule.default) != null ? _a : OpenAPIResponseValidatorModule;
69
68
  var OpenApiSpec = class {
70
69
  constructor(spec) {
71
70
  this.spec = spec;
@@ -80,8 +79,8 @@ var OpenApiSpec = class {
80
79
  return Object.keys(this.pathsObject());
81
80
  }
82
81
  getSchemaObject(schemaName) {
83
- var _a2;
84
- return (_a2 = this.getSchemaObjects()) == null ? void 0 : _a2[schemaName];
82
+ var _a3;
83
+ return (_a3 = this.getSchemaObjects()) == null ? void 0 : _a3[schemaName];
85
84
  }
86
85
  getExpectedResponse(responseOperation, status) {
87
86
  const response = responseOperation.responses[status];
@@ -163,7 +162,6 @@ var OpenApiSpec = class {
163
162
  const validator = new OpenAPIResponseValidator({
164
163
  responses: mockExpectedResponse,
165
164
  ...this.getComponentDefinitionsProperty(),
166
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
167
165
  errorTransformer: ({ path: path2, message }) => ({
168
166
  message: `${path2.replace("response", "object")} ${message}`
169
167
  })
@@ -207,9 +205,9 @@ var OpenApi2Spec = class extends OpenApiSpec {
207
205
  return openApiPath;
208
206
  }
209
207
  findResponseDefinition(referenceString) {
210
- var _a2;
208
+ var _a3;
211
209
  const nameOfResponseDefinition = referenceString.split("#/responses/")[1];
212
- return (_a2 = this.spec.responses) == null ? void 0 : _a2[nameOfResponseDefinition];
210
+ return (_a3 = this.spec.responses) == null ? void 0 : _a3[nameOfResponseDefinition];
213
211
  }
214
212
  getComponentDefinitionsProperty() {
215
213
  return { definitions: this.spec.definitions };
@@ -331,24 +329,24 @@ var OpenApi3Spec = class extends OpenApiSpec {
331
329
  return openApiPath;
332
330
  }
333
331
  findResponseDefinition(referenceString) {
334
- var _a2, _b;
332
+ var _a3, _b;
335
333
  const nameOfResponseDefinition = referenceString.split(
336
334
  "#/components/responses/"
337
335
  )[1];
338
- return (_b = (_a2 = this.spec.components) == null ? void 0 : _a2.responses) == null ? void 0 : _b[nameOfResponseDefinition];
336
+ return (_b = (_a3 = this.spec.components) == null ? void 0 : _a3.responses) == null ? void 0 : _b[nameOfResponseDefinition];
339
337
  }
340
338
  getComponentDefinitionsProperty() {
341
339
  return { components: this.spec.components };
342
340
  }
343
341
  getSchemaObjects() {
344
- var _a2;
345
- return (_a2 = this.spec.components) == null ? void 0 : _a2.schemas;
342
+ var _a3;
343
+ return (_a3 = this.spec.components) == null ? void 0 : _a3.schemas;
346
344
  }
347
345
  };
348
346
 
349
347
  // lib/openApiSpecFactory.ts
350
- var _a;
351
- var OpenAPISchemaValidator = (_a = OpenAPISchemaValidatorModule.default) != null ? _a : OpenAPISchemaValidatorModule;
348
+ var _a2;
349
+ var OpenAPISchemaValidator = (_a2 = OpenAPISchemaValidatorModule.default) != null ? _a2 : OpenAPISchemaValidatorModule;
352
350
  var isObject = (arg) => typeof arg === "object" && arg !== null && !Array.isArray(arg);
353
351
  function makeApiSpec(filepathOrObject) {
354
352
  const spec = loadSpec(filepathOrObject);
@@ -371,7 +369,8 @@ function loadSpec(arg) {
371
369
  } catch (error) {
372
370
  throw new Error(
373
371
  `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.
374
- Error details: ${error.message}`
372
+ Error details: ${error.message}`,
373
+ { cause: error }
375
374
  );
376
375
  }
377
376
  }
@@ -384,7 +383,7 @@ function loadFile(filepath) {
384
383
  return yaml.load(fileData);
385
384
  } catch (error) {
386
385
  throw new Error(`Invalid YAML or JSON:
387
- ${error.message}`);
386
+ ${error.message}`, { cause: error });
388
387
  }
389
388
  }
390
389
  function validateSpec(obj) {
@@ -400,7 +399,7 @@ function validateSpec(obj) {
400
399
  }
401
400
  return obj;
402
401
  } catch (error) {
403
- throw new Error(`Invalid OpenAPI spec: ${error.message}`);
402
+ throw new Error(`Invalid OpenAPI spec: ${error.message}`, { cause: error });
404
403
  }
405
404
  }
406
405
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/classes/errors/ValidationError.ts","../lib/openApiSpecFactory.ts","../lib/utils/common.utils.ts","../lib/classes/AbstractOpenApiSpec.ts","../lib/classes/OpenApi2Spec.ts","../lib/utils/OpenApi3Spec.utils.ts","../lib/classes/OpenApi3Spec.ts","../lib/classes/AbstractResponse.ts","../lib/classes/AxiosResponse.ts","../lib/classes/SuperAgentResponse.ts","../lib/responseFactory.ts"],"sourcesContent":["export enum ErrorCode {\n ServerNotFound,\n BasePathNotFound,\n PathNotFound,\n MethodNotFound,\n StatusNotFound,\n InvalidBody,\n InvalidObject,\n}\n\nexport default class ValidationError extends Error {\n constructor(\n public code: ErrorCode,\n message?: string,\n ) {\n super(message);\n }\n\n override toString(): string {\n return this.message;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport OpenAPISchemaValidatorModule from 'openapi-schema-validator';\nimport type { OpenAPI, OpenAPIV2, OpenAPIV3 } from 'openapi-types';\nimport path from 'path';\nimport typeOf from 'typeof';\nimport OpenApi2Spec from './classes/OpenApi2Spec';\nimport OpenApi3Spec from './classes/OpenApi3Spec';\nimport { stringify } from './utils/common.utils';\n\n// openapi-schema-validator is a CommonJS module that sets `exports.__esModule = true`\n// and exports the class via `exports.default`. When imported natively as ESM, Node.js\n// exposes the whole `module.exports` object as the default, so we must unwrap `.default`\n// to get the actual constructor. The `??` fallback covers the CJS build context where\n// the bundler (esbuild/__toESM) has already unwrapped it for us.\nconst OpenAPISchemaValidator = (\n (\n OpenAPISchemaValidatorModule as unknown as {\n default?: typeof OpenAPISchemaValidatorModule;\n }\n ).default ?? OpenAPISchemaValidatorModule\n);\n\ntype AnyObject = Record<string, unknown>;\n\nconst isObject = (arg: unknown): arg is AnyObject =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg);\n\nexport default function makeApiSpec(\n filepathOrObject: string | OpenAPI.Document,\n): OpenApi2Spec | OpenApi3Spec {\n const spec = loadSpec(filepathOrObject);\n validateSpec(spec);\n const validSpec = spec as OpenAPI.Document;\n if ('swagger' in validSpec) {\n return new OpenApi2Spec(validSpec);\n }\n return new OpenApi3Spec(validSpec as OpenAPIV3.Document);\n}\n\nfunction loadSpec(arg: unknown): AnyObject {\n try {\n if (typeof arg === 'string') {\n return loadFile(arg);\n }\n if (isObject(arg)) {\n return arg;\n }\n throw new Error(`Received type '${typeOf(arg)}'`);\n } catch (error) {\n throw new Error(\n `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.\\nError details: ${\n (error as Error).message\n }`,\n );\n }\n}\n\nfunction loadFile(filepath: string): AnyObject {\n if (!path.isAbsolute(filepath)) {\n throw new Error(`'${filepath}' is not an absolute filepath`);\n }\n const fileData = fs.readFileSync(filepath, { encoding: 'utf8' });\n try {\n return yaml.load(fileData) as AnyObject;\n } catch (error) {\n throw new Error(`Invalid YAML or JSON:\\n${(error as Error).message}`);\n }\n}\n\nfunction validateSpec(obj: AnyObject): OpenAPI.Document {\n try {\n const validator = new OpenAPISchemaValidator({\n version:\n (obj as unknown as OpenAPIV2.Document).swagger || // '2.0'\n (obj as unknown as OpenAPIV3.Document).openapi, // '3.X.X'\n });\n const { errors } = validator.validate(obj as OpenAPI.Document);\n if (errors.length > 0) {\n throw new Error(stringify(errors));\n }\n return obj as OpenAPI.Document;\n } catch (error) {\n throw new Error(`Invalid OpenAPI spec: ${(error as Error).message}`);\n }\n}\n","import { Path } from 'path-parser';\nimport url from 'url';\nimport { inspect } from 'util';\nimport type { ActualRequest } from '../classes/AbstractResponse';\n\nexport const stringify = (obj: unknown): string =>\n inspect(obj, { depth: null });\n\n/**\n * Excludes the query because path = pathname + query\n */\nexport const getPathname = (request: ActualRequest): string =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n url.parse(request.path).pathname!;\n\n/**\n * Converts all {foo} to :foo\n */\nconst convertOpenApiPathToColonForm = (openApiPath: string): string =>\n openApiPath.replace(/{/g, ':').replace(/}/g, '');\n\nconst doesColonPathMatchPathname = (\n pathInColonForm: string,\n pathname: string,\n): boolean => {\n /*\n * By default, OpenAPI path parameters have `style: simple; explode: false` (https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)\n * So array path parameters in the pathname of the actual request should be in the form: `/pathParams/a,b,c`\n * `path-parser` fails to match parameter patterns to parameters containing commas.\n * So we remove the commas.\n */\n const pathWithoutCommas = pathname.replace(/,/g, '');\n const pathParamsInPathname = new Path(pathInColonForm).test(\n pathWithoutCommas,\n ); // => one of: null, {}, {exampleParam: 'foo'}\n return Boolean(pathParamsInPathname);\n};\n\nconst doesOpenApiPathMatchPathname = (\n openApiPath: string,\n pathname: string,\n): boolean => {\n const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);\n return doesColonPathMatchPathname(pathInColonForm, pathname);\n};\n\nexport const findOpenApiPathMatchingPossiblePathnames = (\n possiblePathnames: string[],\n OAPaths: string[],\n): string | undefined => {\n let openApiPath: string | undefined;\n // eslint-disable-next-line no-restricted-syntax\n for (const pathname of possiblePathnames) {\n // eslint-disable-next-line no-restricted-syntax\n for (const OAPath of OAPaths) {\n if (OAPath === pathname) {\n return OAPath;\n }\n if (doesOpenApiPathMatchPathname(OAPath, pathname)) {\n openApiPath = OAPath;\n }\n }\n }\n return openApiPath;\n};\n\nexport const defaultBasePath = '/';\n\nexport const getPathnameWithoutBasePath = (\n basePath: string,\n pathname: string,\n): string =>\n basePath === defaultBasePath ? pathname : pathname.replace(basePath, '');\n","import OpenAPIResponseValidator, {\n type OpenAPIResponseValidatorArgs,\n} from 'openapi-response-validator';\nimport type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport { getPathname } from '../utils/common.utils';\nimport type { ActualRequest, ActualResponse } from './AbstractResponse';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\ntype Document = OpenAPIV2.Document | OpenAPIV3.Document;\n\ntype Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;\n\ntype HttpMethods = OpenAPIV2.HttpMethods;\n\ntype PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;\n\nexport type ResponseObjectWithSchema =\n | (OpenAPIV2.ResponseObject & { schema: OpenAPIV2.Schema })\n | (OpenAPIV3.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3.MediaTypeObject & {\n schema: OpenAPIV3.SchemaObject;\n };\n };\n })\n | (OpenAPIV3_1.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3_1.MediaTypeObject & {\n schema: OpenAPIV3_1.SchemaObject;\n };\n };\n });\n\nexport type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;\n\nexport default abstract class OpenApiSpec {\n protected abstract getSchemaObjects(): Record<string, Schema> | undefined;\n\n protected abstract findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined;\n\n protected abstract findOpenApiPathMatchingPathname(pathname: string): string;\n\n protected abstract getComponentDefinitionsProperty():\n | {\n definitions: OpenAPIV2.Document['definitions'];\n }\n | {\n components: OpenAPIV3.Document['components'];\n };\n\n constructor(protected spec: Document) {}\n\n pathsObject(): Document['paths'] {\n return this.spec.paths;\n }\n\n getPathItem(openApiPath: string): PathItemObject {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.pathsObject()[openApiPath]!;\n }\n\n paths(): string[] {\n return Object.keys(this.pathsObject());\n }\n\n getSchemaObject(schemaName: string): Schema | undefined {\n return this.getSchemaObjects()?.[schemaName];\n }\n\n getExpectedResponse(\n responseOperation: Operation,\n status: ActualResponse['status'],\n ): ResponseObjectWithSchema | undefined {\n const response = responseOperation.responses[status];\n if (!response) {\n return undefined;\n }\n if ('$ref' in response) {\n return this.findResponseDefinition(response.$ref);\n }\n return response as ResponseObjectWithSchema;\n }\n\n findExpectedResponse(\n actualResponse: ActualResponse,\n ): Record<string, ResponseObjectWithSchema> {\n const actualRequest = actualResponse.req;\n const expectedResponseOperation =\n this.findExpectedResponseOperation(actualRequest);\n if (!expectedResponseOperation) {\n throw new ValidationError(ErrorCode.MethodNotFound);\n }\n\n const { status } = actualResponse;\n const expectedResponse = this.getExpectedResponse(\n expectedResponseOperation,\n status,\n );\n if (!expectedResponse) {\n throw new ValidationError(ErrorCode.StatusNotFound);\n }\n\n return { [status]: expectedResponse };\n }\n\n findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n return openApiPath;\n }\n\n findExpectedPathItem(actualRequest: ActualRequest): PathItemObject {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n const pathItemObject = this.getPathItem(openApiPath);\n return pathItemObject;\n }\n\n findExpectedResponseOperation(\n actualRequest: ActualRequest,\n ): Operation | undefined {\n const pathItemObject = this.findExpectedPathItem(actualRequest);\n const operationObject =\n pathItemObject[actualRequest.method.toLowerCase() as HttpMethods];\n return operationObject;\n }\n\n validateResponse(actualResponse: ActualResponse): ValidationError | null {\n let expectedResponse: Record<string, ResponseObjectWithSchema>;\n try {\n expectedResponse = this.findExpectedResponse(actualResponse);\n } catch (error) {\n if (error instanceof ValidationError) {\n return error;\n }\n throw error;\n }\n const validator = new OpenAPIResponseValidator({\n responses: expectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n } as OpenAPIResponseValidatorArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const expectedResStatus = Object.keys(expectedResponse)[0]!;\n const validationError = validator.validateResponse(\n expectedResStatus,\n actualResponse.getBodyForValidation(),\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidBody,\n validationError.errors!\n .map(({ path, message }: { path?: string; message: string }) => `${path} ${message}`)\n .join(', '),\n )\n : null;\n }\n\n /*\n * For consistency and to save maintaining another dependency,\n * we validate objects using our response validator:\n * We put the object inside a mock response, then validate\n * the whole response against a mock expected response.\n * The 2 mock responses are identical except for the body,\n * thus validating the object against its schema.\n */\n validateObject(\n actualObject: unknown,\n schema: Schema,\n ): ValidationError | null {\n const mockResStatus = '200';\n const mockExpectedResponse = { [mockResStatus]: { schema } };\n const validator = new OpenAPIResponseValidator({\n responses: mockExpectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n errorTransformer: ({ path, message }: { path?: string; message: string; errorCode: string }) => ({\n message: `${path!.replace('response', 'object')} ${message}`,\n }),\n } as OpenAPIResponseValidatorArgs);\n const validationError = validator.validateResponse(\n mockResStatus,\n actualObject,\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidObject,\n validationError.errors!.map((error: { message: string }) => error.message).join(', '),\n )\n : null;\n }\n}\n","import type { OpenAPIV2 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n getPathnameWithoutBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n} from '../utils/common.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nconst basePathPropertyNotProvided = (spec: OpenAPIV2.Document): boolean =>\n !spec.basePath;\n\nexport default class OpenApi2Spec extends AbstractOpenApiSpec {\n public didUserDefineBasePath: boolean;\n\n constructor(public override spec: OpenAPIV2.Document) {\n super(spec);\n this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);\n }\n\n /**\n * \"If the basePath property is not provided, the API is served directly under the host\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields\n */\n findOpenApiPathMatchingPathname(pathname: string): string {\n const { basePath } = this.spec;\n if (basePath && !pathname.startsWith(basePath)) {\n throw new ValidationError(ErrorCode.BasePathNotFound);\n }\n const pathnameWithoutBasePath = basePath\n ? getPathnameWithoutBasePath(basePath, pathname)\n : pathname;\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n [pathnameWithoutBasePath],\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split('#/responses/')[1]!;\n return this.spec.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n definitions: OpenAPIV2.Document['definitions'];\n } {\n return { definitions: this.spec.definitions };\n }\n\n getSchemaObjects(): OpenAPIV2.Document['definitions'] {\n return this.spec.definitions;\n }\n}\n","import generateCombinations from 'combos';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { defaultBasePath } from './common.utils';\n\ntype ServerVariables = OpenAPIV3.ServerObject['variables'];\n\nconst unique = <T>(array: T[]): T[] => [...new Set(array)];\n\nexport const serversPropertyNotProvidedOrIsEmptyArray = (\n spec: OpenAPIV3.Document,\n): boolean => !spec.servers || !spec.servers.length;\n\nconst getBasePath = (url: string): string => {\n const basePathStartIndex = url.replace('//', ' ').indexOf('/');\n return basePathStartIndex !== -1\n ? url.slice(basePathStartIndex)\n : defaultBasePath;\n};\n\nconst getPossibleValuesOfServerVariable = ({\n default: defaultValue,\n enum: enumMembers,\n}: OpenAPIV3.ServerVariableObject): string[] =>\n enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];\n\nconst mapServerVariablesToPossibleValues = (\n serverVariables: NonNullable<ServerVariables>,\n): Record<string, string[]> =>\n Object.entries(serverVariables).reduce(\n (currentMap, [variableName, detailsOfPossibleValues]) => ({\n ...currentMap,\n [variableName]: getPossibleValuesOfServerVariable(\n detailsOfPossibleValues,\n ),\n }),\n {},\n );\n\nconst convertTemplateExpressionToConcreteExpression = (\n templateExpression: string,\n mapOfVariablesToValues: Record<string, string>,\n) =>\n Object.entries(mapOfVariablesToValues).reduce(\n (currentExpression, [variable, value]) =>\n currentExpression.replace(`{${variable}}`, value),\n templateExpression,\n );\n\nconst getPossibleConcreteBasePaths = (\n basePath: string,\n serverVariables: NonNullable<ServerVariables>,\n): string[] => {\n const mapOfServerVariablesToPossibleValues =\n mapServerVariablesToPossibleValues(serverVariables);\n const combinationsOfBasePathVariableValues = generateCombinations(\n mapOfServerVariablesToPossibleValues,\n );\n const possibleBasePaths = combinationsOfBasePathVariableValues.map(\n (mapOfVariablesToValues) =>\n convertTemplateExpressionToConcreteExpression(\n basePath,\n mapOfVariablesToValues,\n ),\n );\n return possibleBasePaths;\n};\n\nconst getPossibleBasePaths = (\n url: string,\n serverVariables: ServerVariables,\n): string[] => {\n const basePath = getBasePath(url);\n return serverVariables\n ? getPossibleConcreteBasePaths(basePath, serverVariables)\n : [basePath];\n};\n\nexport const getMatchingServerUrlsAndServerBasePaths = (\n servers: OpenAPIV3.ServerObject[],\n pathname: string,\n): { concreteUrl: string; matchingBasePath: string }[] => {\n const matchesPathname = (basePath: string): boolean =>\n pathname.startsWith(basePath);\n return servers\n .map(({ url: templatedUrl, variables }) => ({\n templatedUrl,\n possibleBasePaths: getPossibleBasePaths(templatedUrl, variables),\n }))\n .filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname))\n .map(({ templatedUrl, possibleBasePaths }) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const matchingBasePath = possibleBasePaths.find(matchesPathname)!;\n return {\n concreteUrl: templatedUrl.replace(\n getBasePath(templatedUrl),\n matchingBasePath,\n ),\n matchingBasePath,\n };\n });\n};\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n defaultBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n getPathnameWithoutBasePath,\n} from '../utils/common.utils';\nimport {\n serversPropertyNotProvidedOrIsEmptyArray,\n getMatchingServerUrlsAndServerBasePaths,\n} from '../utils/OpenApi3Spec.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nexport default class OpenApi3Spec extends AbstractOpenApiSpec {\n public didUserDefineServers: boolean;\n\n constructor(protected override spec: OpenAPIV3.Document) {\n super(spec);\n this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);\n this.ensureDefaultServer();\n }\n\n /**\n * \"If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of '/'\"\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields\n */\n ensureDefaultServer(): void {\n if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {\n this.spec.servers = [{ url: defaultBasePath }];\n }\n }\n\n servers(): OpenAPIV3.ServerObject[] {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.spec.servers!;\n }\n\n getServerUrls(): string[] {\n return this.servers().map((server) => server.url);\n }\n\n getMatchingServerUrls(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ concreteUrl }) => concreteUrl);\n }\n\n getMatchingServerBasePaths(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ matchingBasePath }) => matchingBasePath);\n }\n\n findOpenApiPathMatchingPathname(pathname: string): string {\n const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);\n if (!matchingServerBasePaths.length) {\n throw new ValidationError(ErrorCode.ServerNotFound);\n }\n const possiblePathnames = matchingServerBasePaths.map((basePath) =>\n getPathnameWithoutBasePath(basePath, pathname),\n );\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n possiblePathnames,\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split(\n '#/components/responses/',\n )[1]!;\n return this.spec.components?.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n components: OpenAPIV3.Document['components'];\n } {\n return { components: this.spec.components };\n }\n\n getSchemaObjects(): OpenAPIV3.ComponentsObject['schemas'] {\n return this.spec.components?.schemas;\n }\n}\n","import { stringify } from '../utils/common.utils';\nimport type { RawAxiosResponse } from './AxiosResponse';\nimport type { RawSuperAgentResponse } from './SuperAgentResponse';\n\nexport type RawResponse =\n | RawAxiosResponse\n | RawSuperAgentResponse;\n\nexport default abstract class AbstractResponse {\n declare public status: number;\n\n declare public req: { method: string; path: string };\n\n public abstract getBodyForValidation(): unknown;\n\n protected body: unknown;\n\n declare protected bodyHasNoContent: boolean;\n\n constructor(protected res: RawResponse) {}\n\n summary(): { body: unknown } {\n return {\n body: this.body,\n };\n }\n\n toString(): string {\n return stringify(this.summary());\n }\n}\n\nexport type ActualResponse = AbstractResponse;\n\nexport type ActualRequest = AbstractResponse['req'];\n","import type { AxiosResponse as AxiosResponseType } from 'axios';\nimport AbstractResponse from './AbstractResponse';\n\nexport type RawAxiosResponse = AxiosResponseType;\n\nexport default class AxiosResponse extends AbstractResponse {\n constructor(protected override res: RawAxiosResponse) {\n super(res);\n this.status = res.status;\n this.body = res.data;\n this.req = res.request;\n this.bodyHasNoContent = this.body === '';\n }\n\n getBodyForValidation(): AxiosResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n return this.body;\n }\n}\n","import type { Response, SuperAgentRequest } from 'superagent';\nimport AbstractResponse from './AbstractResponse';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst isEmptyObj = (obj: any): obj is Record<string, never> =>\n !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;\n\nexport type RawSuperAgentResponse = Response & {\n req: SuperAgentRequest & { path: string };\n};\n\nexport default class SuperAgentResponse extends AbstractResponse {\n private isResTextPopulatedInsteadOfResBody: boolean;\n\n constructor(protected override res: RawSuperAgentResponse) {\n super(res);\n this.status = res.status;\n this.body = res.body;\n this.req = res.req;\n this.isResTextPopulatedInsteadOfResBody =\n res.text !== '{}' && isEmptyObj(this.body);\n this.bodyHasNoContent = res.text === '';\n }\n\n getBodyForValidation(): SuperAgentResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n if (this.isResTextPopulatedInsteadOfResBody) {\n return this.res.text;\n }\n return this.body;\n }\n\n override summary(): ReturnType<AbstractResponse['summary']> & {\n text?: string;\n } {\n return {\n ...super.summary(),\n ...(this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }),\n };\n }\n}\n","import { RawResponse } from './classes/AbstractResponse';\nimport AxiosResponse from './classes/AxiosResponse';\nimport SuperAgentResponse from './classes/SuperAgentResponse';\n\nexport default function makeResponse(\n res: RawResponse,\n): AxiosResponse | SuperAgentResponse {\n if ('data' in res) {\n return new AxiosResponse(res);\n }\n if ('status' in res) {\n return new SuperAgentResponse(res);\n }\n throw new Error(\n 'Unsupported response object: expected axios, supertest, superagent, or chai-http response shape.',\n );\n}\n"],"mappings":"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","names":["ErrorCode","_a","path","_a","url","_a"]}
1
+ {"version":3,"sources":["../lib/classes/errors/ValidationError.ts","../lib/openApiSpecFactory.ts","../lib/utils/common.utils.ts","../lib/classes/AbstractOpenApiSpec.ts","../lib/classes/OpenApi2Spec.ts","../lib/utils/OpenApi3Spec.utils.ts","../lib/classes/OpenApi3Spec.ts","../lib/classes/AbstractResponse.ts","../lib/classes/AxiosResponse.ts","../lib/classes/SuperAgentResponse.ts","../lib/responseFactory.ts"],"sourcesContent":["export enum ErrorCode {\n ServerNotFound,\n BasePathNotFound,\n PathNotFound,\n MethodNotFound,\n StatusNotFound,\n InvalidBody,\n InvalidObject,\n}\n\nexport default class ValidationError extends Error {\n constructor(\n public code: ErrorCode,\n message?: string,\n ) {\n super(message);\n }\n\n override toString(): string {\n return this.message;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport OpenAPISchemaValidatorModule from 'openapi-schema-validator';\nimport type { OpenAPI, OpenAPIV2, OpenAPIV3 } from 'openapi-types';\nimport path from 'path';\nimport typeOf from 'typeof';\nimport OpenApi2Spec from './classes/OpenApi2Spec';\nimport OpenApi3Spec from './classes/OpenApi3Spec';\nimport { stringify } from './utils/common.utils';\n\n// openapi-schema-validator is a CommonJS module that sets `exports.__esModule = true`\n// and exports the class via `exports.default`. When imported natively as ESM, Node.js\n// exposes the whole `module.exports` object as the default, so we must unwrap `.default`\n// to get the actual constructor. The `??` fallback covers the CJS build context where\n// the bundler (esbuild/__toESM) has already unwrapped it for us.\nconst OpenAPISchemaValidator = (\n (\n OpenAPISchemaValidatorModule as unknown as {\n default?: typeof OpenAPISchemaValidatorModule;\n }\n ).default ?? OpenAPISchemaValidatorModule\n);\n\ntype AnyObject = Record<string, unknown>;\n\nconst isObject = (arg: unknown): arg is AnyObject =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg);\n\nexport default function makeApiSpec(\n filepathOrObject: string | OpenAPI.Document,\n): OpenApi2Spec | OpenApi3Spec {\n const spec = loadSpec(filepathOrObject);\n validateSpec(spec);\n const validSpec = spec as OpenAPI.Document;\n if ('swagger' in validSpec) {\n return new OpenApi2Spec(validSpec);\n }\n return new OpenApi3Spec(validSpec as OpenAPIV3.Document);\n}\n\nfunction loadSpec(arg: unknown): AnyObject {\n try {\n if (typeof arg === 'string') {\n return loadFile(arg);\n }\n if (isObject(arg)) {\n return arg;\n }\n throw new Error(`Received type '${typeOf(arg)}'`);\n } catch (error) {\n throw new Error(\n `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.\\nError details: ${\n (error as Error).message\n }`,\n { cause: error },\n );\n }\n}\n\nfunction loadFile(filepath: string): AnyObject {\n if (!path.isAbsolute(filepath)) {\n throw new Error(`'${filepath}' is not an absolute filepath`);\n }\n const fileData = fs.readFileSync(filepath, { encoding: 'utf8' });\n try {\n return yaml.load(fileData) as AnyObject;\n } catch (error) {\n throw new Error(`Invalid YAML or JSON:\\n${(error as Error).message}`, { cause: error });\n }\n}\n\nfunction validateSpec(obj: AnyObject): OpenAPI.Document {\n try {\n const validator = new OpenAPISchemaValidator({\n version:\n (obj as unknown as OpenAPIV2.Document).swagger || // '2.0'\n (obj as unknown as OpenAPIV3.Document).openapi, // '3.X.X'\n });\n const { errors } = validator.validate(obj as OpenAPI.Document);\n if (errors.length > 0) {\n throw new Error(stringify(errors));\n }\n return obj as OpenAPI.Document;\n } catch (error) {\n throw new Error(`Invalid OpenAPI spec: ${(error as Error).message}`, { cause: error });\n }\n}\n","import { Path } from 'path-parser';\nimport url from 'url';\nimport { inspect } from 'util';\nimport type { ActualRequest } from '../classes/AbstractResponse';\n\nexport const stringify = (obj: unknown): string =>\n inspect(obj, { depth: null });\n\n/**\n * Excludes the query because path = pathname + query\n */\nexport const getPathname = (request: ActualRequest): string =>\n \n url.parse(request.path).pathname!;\n\n/**\n * Converts all {foo} to :foo\n */\nconst convertOpenApiPathToColonForm = (openApiPath: string): string =>\n openApiPath.replace(/{/g, ':').replace(/}/g, '');\n\nconst doesColonPathMatchPathname = (\n pathInColonForm: string,\n pathname: string,\n): boolean => {\n /*\n * By default, OpenAPI path parameters have `style: simple; explode: false` (https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)\n * So array path parameters in the pathname of the actual request should be in the form: `/pathParams/a,b,c`\n * `path-parser` fails to match parameter patterns to parameters containing commas.\n * So we remove the commas.\n */\n const pathWithoutCommas = pathname.replace(/,/g, '');\n const pathParamsInPathname = new Path(pathInColonForm).test(\n pathWithoutCommas,\n ); // => one of: null, {}, {exampleParam: 'foo'}\n return Boolean(pathParamsInPathname);\n};\n\nconst doesOpenApiPathMatchPathname = (\n openApiPath: string,\n pathname: string,\n): boolean => {\n const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);\n return doesColonPathMatchPathname(pathInColonForm, pathname);\n};\n\nexport const findOpenApiPathMatchingPossiblePathnames = (\n possiblePathnames: string[],\n OAPaths: string[],\n): string | undefined => {\n let openApiPath: string | undefined;\n // eslint-disable-next-line no-restricted-syntax\n for (const pathname of possiblePathnames) {\n // eslint-disable-next-line no-restricted-syntax\n for (const OAPath of OAPaths) {\n if (OAPath === pathname) {\n return OAPath;\n }\n if (doesOpenApiPathMatchPathname(OAPath, pathname)) {\n openApiPath = OAPath;\n }\n }\n }\n return openApiPath;\n};\n\nexport const defaultBasePath = '/';\n\nexport const getPathnameWithoutBasePath = (\n basePath: string,\n pathname: string,\n): string =>\n basePath === defaultBasePath ? pathname : pathname.replace(basePath, '');\n","import OpenAPIResponseValidatorModule, {\n type OpenAPIResponseValidatorArgs,\n} from 'openapi-response-validator';\nimport type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport { getPathname } from '../utils/common.utils';\nimport type { ActualRequest, ActualResponse } from './AbstractResponse';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\ntype Document = OpenAPIV2.Document | OpenAPIV3.Document;\n\ntype Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;\n\ntype HttpMethods = OpenAPIV2.HttpMethods;\n\ntype PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;\n\nconst OpenAPIResponseValidator = (\n OpenAPIResponseValidatorModule as unknown as {\n default?: typeof OpenAPIResponseValidatorModule;\n }\n).default ?? OpenAPIResponseValidatorModule;\n\nexport type ResponseObjectWithSchema =\n | (OpenAPIV2.ResponseObject & { schema: OpenAPIV2.Schema })\n | (OpenAPIV3.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3.MediaTypeObject & {\n schema: OpenAPIV3.SchemaObject;\n };\n };\n })\n | (OpenAPIV3_1.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3_1.MediaTypeObject & {\n schema: OpenAPIV3_1.SchemaObject;\n };\n };\n });\n\nexport type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;\n\nexport default abstract class OpenApiSpec {\n protected abstract getSchemaObjects(): Record<string, Schema> | undefined;\n\n protected abstract findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined;\n\n protected abstract findOpenApiPathMatchingPathname(pathname: string): string;\n\n protected abstract getComponentDefinitionsProperty():\n | {\n definitions: OpenAPIV2.Document['definitions'];\n }\n | {\n components: OpenAPIV3.Document['components'];\n };\n\n constructor(protected spec: Document) {}\n\n pathsObject(): Document['paths'] {\n return this.spec.paths;\n }\n\n getPathItem(openApiPath: string): PathItemObject {\n \n return this.pathsObject()[openApiPath]!;\n }\n\n paths(): string[] {\n return Object.keys(this.pathsObject());\n }\n\n getSchemaObject(schemaName: string): Schema | undefined {\n return this.getSchemaObjects()?.[schemaName];\n }\n\n getExpectedResponse(\n responseOperation: Operation,\n status: ActualResponse['status'],\n ): ResponseObjectWithSchema | undefined {\n const response = responseOperation.responses[status];\n if (!response) {\n return undefined;\n }\n if ('$ref' in response) {\n return this.findResponseDefinition(response.$ref);\n }\n return response as ResponseObjectWithSchema;\n }\n\n findExpectedResponse(\n actualResponse: ActualResponse,\n ): Record<string, ResponseObjectWithSchema> {\n const actualRequest = actualResponse.req;\n const expectedResponseOperation =\n this.findExpectedResponseOperation(actualRequest);\n if (!expectedResponseOperation) {\n throw new ValidationError(ErrorCode.MethodNotFound);\n }\n\n const { status } = actualResponse;\n const expectedResponse = this.getExpectedResponse(\n expectedResponseOperation,\n status,\n );\n if (!expectedResponse) {\n throw new ValidationError(ErrorCode.StatusNotFound);\n }\n\n return { [status]: expectedResponse };\n }\n\n findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n return openApiPath;\n }\n\n findExpectedPathItem(actualRequest: ActualRequest): PathItemObject {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n const pathItemObject = this.getPathItem(openApiPath);\n return pathItemObject;\n }\n\n findExpectedResponseOperation(\n actualRequest: ActualRequest,\n ): Operation | undefined {\n const pathItemObject = this.findExpectedPathItem(actualRequest);\n const operationObject =\n pathItemObject[actualRequest.method.toLowerCase() as HttpMethods];\n return operationObject;\n }\n\n validateResponse(actualResponse: ActualResponse): ValidationError | null {\n let expectedResponse: Record<string, ResponseObjectWithSchema>;\n try {\n expectedResponse = this.findExpectedResponse(actualResponse);\n } catch (error) {\n if (error instanceof ValidationError) {\n return error;\n }\n throw error;\n }\n const validator = new OpenAPIResponseValidator({\n responses: expectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n } as OpenAPIResponseValidatorArgs);\n\n \n const expectedResStatus = Object.keys(expectedResponse)[0]!;\n const validationError = validator.validateResponse(\n expectedResStatus,\n actualResponse.getBodyForValidation(),\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidBody,\n validationError.errors!\n .map(({ path, message }: { path?: string; message: string }) => `${path} ${message}`)\n .join(', '),\n )\n : null;\n }\n\n /*\n * For consistency and to save maintaining another dependency,\n * we validate objects using our response validator:\n * We put the object inside a mock response, then validate\n * the whole response against a mock expected response.\n * The 2 mock responses are identical except for the body,\n * thus validating the object against its schema.\n */\n validateObject(\n actualObject: unknown,\n schema: Schema,\n ): ValidationError | null {\n const mockResStatus = '200';\n const mockExpectedResponse = { [mockResStatus]: { schema } };\n const validator = new OpenAPIResponseValidator({\n responses: mockExpectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n \n errorTransformer: ({ path, message }: { path?: string; message: string; errorCode: string }) => ({\n message: `${path!.replace('response', 'object')} ${message}`,\n }),\n } as OpenAPIResponseValidatorArgs);\n const validationError = validator.validateResponse(\n mockResStatus,\n actualObject,\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidObject,\n validationError.errors!.map((error: { message: string }) => error.message).join(', '),\n )\n : null;\n }\n}\n","import type { OpenAPIV2 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n getPathnameWithoutBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n} from '../utils/common.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nconst basePathPropertyNotProvided = (spec: OpenAPIV2.Document): boolean =>\n !spec.basePath;\n\nexport default class OpenApi2Spec extends AbstractOpenApiSpec {\n public didUserDefineBasePath: boolean;\n\n constructor(public override spec: OpenAPIV2.Document) {\n super(spec);\n this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);\n }\n\n /**\n * \"If the basePath property is not provided, the API is served directly under the host\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields\n */\n findOpenApiPathMatchingPathname(pathname: string): string {\n const { basePath } = this.spec;\n if (basePath && !pathname.startsWith(basePath)) {\n throw new ValidationError(ErrorCode.BasePathNotFound);\n }\n const pathnameWithoutBasePath = basePath\n ? getPathnameWithoutBasePath(basePath, pathname)\n : pathname;\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n [pathnameWithoutBasePath],\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n \n const nameOfResponseDefinition = referenceString.split('#/responses/')[1]!;\n return this.spec.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n definitions: OpenAPIV2.Document['definitions'];\n } {\n return { definitions: this.spec.definitions };\n }\n\n getSchemaObjects(): OpenAPIV2.Document['definitions'] {\n return this.spec.definitions;\n }\n}\n","import generateCombinations from 'combos';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { defaultBasePath } from './common.utils';\n\ntype ServerVariables = OpenAPIV3.ServerObject['variables'];\n\nconst unique = <T>(array: T[]): T[] => [...new Set(array)];\n\nexport const serversPropertyNotProvidedOrIsEmptyArray = (\n spec: OpenAPIV3.Document,\n): boolean => !spec.servers || !spec.servers.length;\n\nconst getBasePath = (url: string): string => {\n const basePathStartIndex = url.replace('//', ' ').indexOf('/');\n return basePathStartIndex !== -1\n ? url.slice(basePathStartIndex)\n : defaultBasePath;\n};\n\nconst getPossibleValuesOfServerVariable = ({\n default: defaultValue,\n enum: enumMembers,\n}: OpenAPIV3.ServerVariableObject): string[] =>\n enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];\n\nconst mapServerVariablesToPossibleValues = (\n serverVariables: NonNullable<ServerVariables>,\n): Record<string, string[]> =>\n Object.entries(serverVariables).reduce(\n (currentMap, [variableName, detailsOfPossibleValues]) => ({\n ...currentMap,\n [variableName]: getPossibleValuesOfServerVariable(\n detailsOfPossibleValues,\n ),\n }),\n {},\n );\n\nconst convertTemplateExpressionToConcreteExpression = (\n templateExpression: string,\n mapOfVariablesToValues: Record<string, string>,\n) =>\n Object.entries(mapOfVariablesToValues).reduce(\n (currentExpression, [variable, value]) =>\n currentExpression.replace(`{${variable}}`, value),\n templateExpression,\n );\n\nconst getPossibleConcreteBasePaths = (\n basePath: string,\n serverVariables: NonNullable<ServerVariables>,\n): string[] => {\n const mapOfServerVariablesToPossibleValues =\n mapServerVariablesToPossibleValues(serverVariables);\n const combinationsOfBasePathVariableValues = generateCombinations(\n mapOfServerVariablesToPossibleValues,\n );\n const possibleBasePaths = combinationsOfBasePathVariableValues.map(\n (mapOfVariablesToValues) =>\n convertTemplateExpressionToConcreteExpression(\n basePath,\n mapOfVariablesToValues,\n ),\n );\n return possibleBasePaths;\n};\n\nconst getPossibleBasePaths = (\n url: string,\n serverVariables: ServerVariables,\n): string[] => {\n const basePath = getBasePath(url);\n return serverVariables\n ? getPossibleConcreteBasePaths(basePath, serverVariables)\n : [basePath];\n};\n\nexport const getMatchingServerUrlsAndServerBasePaths = (\n servers: OpenAPIV3.ServerObject[],\n pathname: string,\n): { concreteUrl: string; matchingBasePath: string }[] => {\n const matchesPathname = (basePath: string): boolean =>\n pathname.startsWith(basePath);\n return servers\n .map(({ url: templatedUrl, variables }) => ({\n templatedUrl,\n possibleBasePaths: getPossibleBasePaths(templatedUrl, variables),\n }))\n .filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname))\n .map(({ templatedUrl, possibleBasePaths }) => {\n \n const matchingBasePath = possibleBasePaths.find(matchesPathname)!;\n return {\n concreteUrl: templatedUrl.replace(\n getBasePath(templatedUrl),\n matchingBasePath,\n ),\n matchingBasePath,\n };\n });\n};\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n defaultBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n getPathnameWithoutBasePath,\n} from '../utils/common.utils';\nimport {\n serversPropertyNotProvidedOrIsEmptyArray,\n getMatchingServerUrlsAndServerBasePaths,\n} from '../utils/OpenApi3Spec.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nexport default class OpenApi3Spec extends AbstractOpenApiSpec {\n public didUserDefineServers: boolean;\n\n constructor(protected override spec: OpenAPIV3.Document) {\n super(spec);\n this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);\n this.ensureDefaultServer();\n }\n\n /**\n * \"If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of '/'\"\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields\n */\n ensureDefaultServer(): void {\n if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {\n this.spec.servers = [{ url: defaultBasePath }];\n }\n }\n\n servers(): OpenAPIV3.ServerObject[] {\n \n return this.spec.servers!;\n }\n\n getServerUrls(): string[] {\n return this.servers().map((server) => server.url);\n }\n\n getMatchingServerUrls(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ concreteUrl }) => concreteUrl);\n }\n\n getMatchingServerBasePaths(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ matchingBasePath }) => matchingBasePath);\n }\n\n findOpenApiPathMatchingPathname(pathname: string): string {\n const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);\n if (!matchingServerBasePaths.length) {\n throw new ValidationError(ErrorCode.ServerNotFound);\n }\n const possiblePathnames = matchingServerBasePaths.map((basePath) =>\n getPathnameWithoutBasePath(basePath, pathname),\n );\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n possiblePathnames,\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n \n const nameOfResponseDefinition = referenceString.split(\n '#/components/responses/',\n )[1]!;\n return this.spec.components?.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n components: OpenAPIV3.Document['components'];\n } {\n return { components: this.spec.components };\n }\n\n getSchemaObjects(): OpenAPIV3.ComponentsObject['schemas'] {\n return this.spec.components?.schemas;\n }\n}\n","import { stringify } from '../utils/common.utils';\nimport type { RawAxiosResponse } from './AxiosResponse';\nimport type { RawSuperAgentResponse } from './SuperAgentResponse';\n\nexport type RawResponse =\n | RawAxiosResponse\n | RawSuperAgentResponse;\n\nexport default abstract class AbstractResponse {\n declare public status: number;\n\n declare public req: { method: string; path: string };\n\n public abstract getBodyForValidation(): unknown;\n\n protected body: unknown;\n\n declare protected bodyHasNoContent: boolean;\n\n constructor(protected res: RawResponse) {}\n\n summary(): { body: unknown } {\n return {\n body: this.body,\n };\n }\n\n toString(): string {\n return stringify(this.summary());\n }\n}\n\nexport type ActualResponse = AbstractResponse;\n\nexport type ActualRequest = AbstractResponse['req'];\n","import type { AxiosResponse as AxiosResponseType } from 'axios';\nimport AbstractResponse from './AbstractResponse';\n\nexport type RawAxiosResponse = AxiosResponseType;\n\nexport default class AxiosResponse extends AbstractResponse {\n constructor(protected override res: RawAxiosResponse) {\n super(res);\n this.status = res.status;\n this.body = res.data;\n this.req = res.request;\n this.bodyHasNoContent = this.body === '';\n }\n\n getBodyForValidation(): AxiosResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n return this.body;\n }\n}\n","import type { Response, SuperAgentRequest } from 'superagent';\nimport AbstractResponse from './AbstractResponse';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst isEmptyObj = (obj: any): obj is Record<string, never> =>\n !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;\n\nexport type RawSuperAgentResponse = Response & {\n req: SuperAgentRequest & { path: string };\n};\n\nexport default class SuperAgentResponse extends AbstractResponse {\n private isResTextPopulatedInsteadOfResBody: boolean;\n\n constructor(protected override res: RawSuperAgentResponse) {\n super(res);\n this.status = res.status;\n this.body = res.body;\n this.req = res.req;\n this.isResTextPopulatedInsteadOfResBody =\n res.text !== '{}' && isEmptyObj(this.body);\n this.bodyHasNoContent = res.text === '';\n }\n\n getBodyForValidation(): SuperAgentResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n if (this.isResTextPopulatedInsteadOfResBody) {\n return this.res.text;\n }\n return this.body;\n }\n\n override summary(): ReturnType<AbstractResponse['summary']> & {\n text?: string;\n } {\n return {\n ...super.summary(),\n ...(this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }),\n };\n }\n}\n","import { RawResponse } from './classes/AbstractResponse';\nimport AxiosResponse from './classes/AxiosResponse';\nimport SuperAgentResponse from './classes/SuperAgentResponse';\n\nexport default function makeResponse(\n res: RawResponse,\n): AxiosResponse | SuperAgentResponse {\n if ('data' in res) {\n return new AxiosResponse(res);\n }\n if ('status' in res) {\n return new SuperAgentResponse(res);\n }\n throw new Error(\n 'Unsupported response object: expected axios, supertest, superagent, or chai-http response shape.',\n );\n}\n"],"mappings":"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","names":["ErrorCode","_a","path","_a","url","_a","_a"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ehuelsmann/openapi-validator",
3
- "version": "0.16.2",
3
+ "version": "0.17.0",
4
4
  "description": "Common code for jest-openapi and Chai OpenAPI Response Validator",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -41,6 +41,12 @@
41
41
  "keywords": [
42
42
  "jest",
43
43
  "chai",
44
+ "vitest",
45
+ "mocha",
46
+ "ava",
47
+ "jasmine",
48
+ "framework-agnostic",
49
+ "test-framework-agnostic",
44
50
  "openapi",
45
51
  "testing",
46
52
  "response",