@ehuelsmann/openapi-validator 0.16.3 → 0.17.1
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 +76 -3
- package/dist/index.js +5 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,12 +1,85 @@
|
|
|
1
1
|
# OpenAPI Validator
|
|
2
2
|
|
|
3
|
-
> **Notice:** Support for responses from [`request`](https://github.com/request/request#deprecated) and [`request-promise`](https://github.com/request/request-promise#deprecated) has been removed because both upstream projects are deprecated.
|
|
4
|
-
|
|
5
3
|
[](https://www.npmjs.com/package/@ehuelsmann/openapi-validator)
|
|
6
4
|
[](https://www.npmjs.com/package/@ehuelsmann/openapi-validator)
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
[](https://codecov.io/gh/ehuelsmann/OpenAPIValidators)
|
|
8
|
+
[](https://github.com/ehuelsmann/OpenAPIValidators/blob/master/CONTRIBUTING.md)
|
|
7
9
|
|
|
8
10
|
**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
11
|
|
|
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)
|
|
13
|
+
|
|
14
|
+
## Contributing ✨
|
|
10
15
|
|
|
16
|
+
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.
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
[npm](http://npmjs.org)
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install --save-dev @ehuelsmann/openapi-validator
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
[yarn](https://yarnpkg.com/)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
yarn add --dev @ehuelsmann/openapi-validator
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Importing
|
|
33
|
+
|
|
34
|
+
This package ships with both **ESM** (preferred) and **CommonJS** builds, so it works in any environment.
|
|
35
|
+
|
|
36
|
+
ESM / TypeScript
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { makeApiSpec, makeResponse } from '@ehuelsmann/openapi-validator';
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
CommonJS / JavaScript
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
const { makeApiSpec, makeResponse } = require('@ehuelsmann/openapi-validator');
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
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.
|
|
51
|
+
|
|
52
|
+
### Loading an OpenAPI spec
|
|
53
|
+
|
|
54
|
+
`makeApiSpec` accepts either an absolute filepath or an object representing an OpenAPI (v2 or v3) document:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { makeApiSpec } from '@ehuelsmann/openapi-validator';
|
|
58
|
+
|
|
59
|
+
// From an absolute filepath (YAML or JSON)
|
|
60
|
+
const spec = makeApiSpec('/absolute/path/to/openapi.yml');
|
|
61
|
+
|
|
62
|
+
// From an object
|
|
63
|
+
const spec = makeApiSpec({
|
|
64
|
+
openapi: '3.0.0',
|
|
65
|
+
info: { title: 'Example API', version: '1.0.0' },
|
|
66
|
+
paths: {},
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Validating a response
|
|
71
|
+
|
|
72
|
+
`makeResponse` wraps an HTTP response from `axios`, `supertest`, `superagent`, or `chai-http` so it can be validated against the loaded spec:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { makeApiSpec, makeResponse } from '@ehuelsmann/openapi-validator';
|
|
76
|
+
|
|
77
|
+
const spec = makeApiSpec('/absolute/path/to/openapi.yml');
|
|
78
|
+
|
|
79
|
+
// res is an axios, supertest, superagent, or chai-http response object
|
|
80
|
+
const response = makeResponse(res);
|
|
81
|
+
const validationError = spec.validateResponse(response);
|
|
82
|
+
if (validationError) {
|
|
83
|
+
throw new Error(validationError.message);
|
|
84
|
+
}
|
|
85
|
+
```
|
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, "");
|
|
@@ -203,7 +200,6 @@ var OpenApiSpec = class {
|
|
|
203
200
|
const validator = new OpenAPIResponseValidator({
|
|
204
201
|
responses: mockExpectedResponse,
|
|
205
202
|
...this.getComponentDefinitionsProperty(),
|
|
206
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
207
203
|
errorTransformer: ({ path: path2, message }) => ({
|
|
208
204
|
message: `${path2.replace("response", "object")} ${message}`
|
|
209
205
|
})
|
|
@@ -411,7 +407,8 @@ function loadSpec(arg) {
|
|
|
411
407
|
} catch (error) {
|
|
412
408
|
throw new Error(
|
|
413
409
|
`The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.
|
|
414
|
-
Error details: ${error.message}
|
|
410
|
+
Error details: ${error.message}`,
|
|
411
|
+
{ cause: error }
|
|
415
412
|
);
|
|
416
413
|
}
|
|
417
414
|
}
|
|
@@ -424,7 +421,7 @@ function loadFile(filepath) {
|
|
|
424
421
|
return import_js_yaml.default.load(fileData);
|
|
425
422
|
} catch (error) {
|
|
426
423
|
throw new Error(`Invalid YAML or JSON:
|
|
427
|
-
${error.message}
|
|
424
|
+
${error.message}`, { cause: error });
|
|
428
425
|
}
|
|
429
426
|
}
|
|
430
427
|
function validateSpec(obj) {
|
|
@@ -440,7 +437,7 @@ function validateSpec(obj) {
|
|
|
440
437
|
}
|
|
441
438
|
return obj;
|
|
442
439
|
} catch (error) {
|
|
443
|
-
throw new Error(`Invalid OpenAPI spec: ${error.message}
|
|
440
|
+
throw new Error(`Invalid OpenAPI spec: ${error.message}`, { cause: error });
|
|
444
441
|
}
|
|
445
442
|
}
|
|
446
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 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 // 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","OpenAPIResponseValidatorModule","_a","path","_a","url","generateCombinations","_a","_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, "");
|
|
@@ -165,7 +162,6 @@ var OpenApiSpec = class {
|
|
|
165
162
|
const validator = new OpenAPIResponseValidator({
|
|
166
163
|
responses: mockExpectedResponse,
|
|
167
164
|
...this.getComponentDefinitionsProperty(),
|
|
168
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
169
165
|
errorTransformer: ({ path: path2, message }) => ({
|
|
170
166
|
message: `${path2.replace("response", "object")} ${message}`
|
|
171
167
|
})
|
|
@@ -373,7 +369,8 @@ function loadSpec(arg) {
|
|
|
373
369
|
} catch (error) {
|
|
374
370
|
throw new Error(
|
|
375
371
|
`The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.
|
|
376
|
-
Error details: ${error.message}
|
|
372
|
+
Error details: ${error.message}`,
|
|
373
|
+
{ cause: error }
|
|
377
374
|
);
|
|
378
375
|
}
|
|
379
376
|
}
|
|
@@ -386,7 +383,7 @@ function loadFile(filepath) {
|
|
|
386
383
|
return yaml.load(fileData);
|
|
387
384
|
} catch (error) {
|
|
388
385
|
throw new Error(`Invalid YAML or JSON:
|
|
389
|
-
${error.message}
|
|
386
|
+
${error.message}`, { cause: error });
|
|
390
387
|
}
|
|
391
388
|
}
|
|
392
389
|
function validateSpec(obj) {
|
|
@@ -402,7 +399,7 @@ function validateSpec(obj) {
|
|
|
402
399
|
}
|
|
403
400
|
return obj;
|
|
404
401
|
} catch (error) {
|
|
405
|
-
throw new Error(`Invalid OpenAPI spec: ${error.message}
|
|
402
|
+
throw new Error(`Invalid OpenAPI spec: ${error.message}`, { cause: error });
|
|
406
403
|
}
|
|
407
404
|
}
|
|
408
405
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -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 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 // 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","_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.
|
|
3
|
+
"version": "0.17.1",
|
|
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",
|
|
@@ -57,10 +63,10 @@
|
|
|
57
63
|
"dist"
|
|
58
64
|
],
|
|
59
65
|
"dependencies": {
|
|
60
|
-
"@types/superagent": "^
|
|
66
|
+
"@types/superagent": "^8.1.9",
|
|
61
67
|
"axios": "^1.15.2",
|
|
62
68
|
"combos": "^0.2.0",
|
|
63
|
-
"fs-extra": "^
|
|
69
|
+
"fs-extra": "^11.3.5",
|
|
64
70
|
"js-yaml": "^4.0.0",
|
|
65
71
|
"openapi-response-validator": "^12.1.3",
|
|
66
72
|
"openapi-schema-validator": "^12.1.3",
|
|
@@ -68,7 +74,7 @@
|
|
|
68
74
|
"typeof": "^1.0.0"
|
|
69
75
|
},
|
|
70
76
|
"devDependencies": {
|
|
71
|
-
"@types/fs-extra": "^
|
|
77
|
+
"@types/fs-extra": "^11.0.4",
|
|
72
78
|
"@types/js-yaml": "^4.0.3",
|
|
73
79
|
"@types/typeof": "^1.0.0",
|
|
74
80
|
"openapi-types": "^12.1.3",
|