@ehuelsmann/openapi-validator 0.15.0 → 0.16.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.
Files changed (57) hide show
  1. package/README.md +6 -0
  2. package/dist/index.d.mts +149 -0
  3. package/dist/index.d.ts +149 -14
  4. package/dist/index.js +521 -11
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +484 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +26 -9
  9. package/dist/classes/AbstractOpenApiSpec.d.ts +0 -47
  10. package/dist/classes/AbstractOpenApiSpec.d.ts.map +0 -1
  11. package/dist/classes/AbstractOpenApiSpec.js +0 -149
  12. package/dist/classes/AbstractOpenApiSpec.js.map +0 -1
  13. package/dist/classes/AbstractResponse.d.ts +0 -23
  14. package/dist/classes/AbstractResponse.d.ts.map +0 -1
  15. package/dist/classes/AbstractResponse.js +0 -18
  16. package/dist/classes/AbstractResponse.js.map +0 -1
  17. package/dist/classes/AxiosResponse.d.ts +0 -9
  18. package/dist/classes/AxiosResponse.d.ts.map +0 -1
  19. package/dist/classes/AxiosResponse.js +0 -24
  20. package/dist/classes/AxiosResponse.js.map +0 -1
  21. package/dist/classes/OpenApi2Spec.d.ts +0 -19
  22. package/dist/classes/OpenApi2Spec.d.ts.map +0 -1
  23. package/dist/classes/OpenApi2Spec.js +0 -81
  24. package/dist/classes/OpenApi2Spec.js.map +0 -1
  25. package/dist/classes/OpenApi3Spec.d.ts +0 -24
  26. package/dist/classes/OpenApi3Spec.d.ts.map +0 -1
  27. package/dist/classes/OpenApi3Spec.js +0 -99
  28. package/dist/classes/OpenApi3Spec.js.map +0 -1
  29. package/dist/classes/RequestPromiseResponse.d.ts +0 -14
  30. package/dist/classes/RequestPromiseResponse.d.ts.map +0 -1
  31. package/dist/classes/RequestPromiseResponse.js +0 -34
  32. package/dist/classes/RequestPromiseResponse.js.map +0 -1
  33. package/dist/classes/SuperAgentResponse.d.ts +0 -17
  34. package/dist/classes/SuperAgentResponse.d.ts.map +0 -1
  35. package/dist/classes/SuperAgentResponse.js +0 -37
  36. package/dist/classes/SuperAgentResponse.js.map +0 -1
  37. package/dist/classes/errors/ValidationError.d.ts +0 -15
  38. package/dist/classes/errors/ValidationError.d.ts.map +0 -1
  39. package/dist/classes/errors/ValidationError.js +0 -24
  40. package/dist/classes/errors/ValidationError.js.map +0 -1
  41. package/dist/index.d.ts.map +0 -1
  42. package/dist/openApiSpecFactory.d.ts +0 -5
  43. package/dist/openApiSpecFactory.d.ts.map +0 -1
  44. package/dist/openApiSpecFactory.js +0 -67
  45. package/dist/openApiSpecFactory.js.map +0 -1
  46. package/dist/responseFactory.d.ts +0 -6
  47. package/dist/responseFactory.d.ts.map +0 -1
  48. package/dist/responseFactory.js +0 -19
  49. package/dist/responseFactory.js.map +0 -1
  50. package/dist/utils/OpenApi3Spec.utils.d.ts +0 -7
  51. package/dist/utils/OpenApi3Spec.utils.d.ts.map +0 -1
  52. package/dist/utils/OpenApi3Spec.utils.js +0 -54
  53. package/dist/utils/OpenApi3Spec.utils.js.map +0 -1
  54. package/dist/utils/common.utils.d.ts +0 -10
  55. package/dist/utils/common.utils.d.ts.map +0 -1
  56. package/dist/utils/common.utils.js +0 -58
  57. package/dist/utils/common.utils.js.map +0 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,484 @@
1
+ // lib/classes/errors/ValidationError.ts
2
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
3
+ ErrorCode2[ErrorCode2["ServerNotFound"] = 0] = "ServerNotFound";
4
+ ErrorCode2[ErrorCode2["BasePathNotFound"] = 1] = "BasePathNotFound";
5
+ ErrorCode2[ErrorCode2["PathNotFound"] = 2] = "PathNotFound";
6
+ ErrorCode2[ErrorCode2["MethodNotFound"] = 3] = "MethodNotFound";
7
+ ErrorCode2[ErrorCode2["StatusNotFound"] = 4] = "StatusNotFound";
8
+ ErrorCode2[ErrorCode2["InvalidBody"] = 5] = "InvalidBody";
9
+ ErrorCode2[ErrorCode2["InvalidObject"] = 6] = "InvalidObject";
10
+ return ErrorCode2;
11
+ })(ErrorCode || {});
12
+ var ValidationError = class extends Error {
13
+ constructor(code, message) {
14
+ super(message);
15
+ this.code = code;
16
+ }
17
+ toString() {
18
+ return this.message;
19
+ }
20
+ };
21
+
22
+ // lib/openApiSpecFactory.ts
23
+ import fs from "fs-extra";
24
+ import yaml from "js-yaml";
25
+ import OpenAPISchemaValidator from "openapi-schema-validator";
26
+ import path from "path";
27
+ import typeOf from "typeof";
28
+
29
+ // lib/utils/common.utils.ts
30
+ import { Path } from "path-parser";
31
+ import url from "url";
32
+ import { inspect } from "util";
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
+ );
38
+ var convertOpenApiPathToColonForm = (openApiPath) => openApiPath.replace(/{/g, ":").replace(/}/g, "");
39
+ var doesColonPathMatchPathname = (pathInColonForm, pathname) => {
40
+ const pathWithoutCommas = pathname.replace(/,/g, "");
41
+ const pathParamsInPathname = new Path(pathInColonForm).test(
42
+ pathWithoutCommas
43
+ );
44
+ return Boolean(pathParamsInPathname);
45
+ };
46
+ var doesOpenApiPathMatchPathname = (openApiPath, pathname) => {
47
+ const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);
48
+ return doesColonPathMatchPathname(pathInColonForm, pathname);
49
+ };
50
+ var findOpenApiPathMatchingPossiblePathnames = (possiblePathnames, OAPaths) => {
51
+ let openApiPath;
52
+ for (const pathname of possiblePathnames) {
53
+ for (const OAPath of OAPaths) {
54
+ if (OAPath === pathname) {
55
+ return OAPath;
56
+ }
57
+ if (doesOpenApiPathMatchPathname(OAPath, pathname)) {
58
+ openApiPath = OAPath;
59
+ }
60
+ }
61
+ }
62
+ return openApiPath;
63
+ };
64
+ var defaultBasePath = "/";
65
+ var getPathnameWithoutBasePath = (basePath, pathname) => basePath === defaultBasePath ? pathname : pathname.replace(basePath, "");
66
+
67
+ // lib/classes/AbstractOpenApiSpec.ts
68
+ import OpenAPIResponseValidator from "openapi-response-validator";
69
+ var OpenApiSpec = class {
70
+ constructor(spec) {
71
+ this.spec = spec;
72
+ }
73
+ pathsObject() {
74
+ return this.spec.paths;
75
+ }
76
+ getPathItem(openApiPath) {
77
+ return this.pathsObject()[openApiPath];
78
+ }
79
+ paths() {
80
+ return Object.keys(this.pathsObject());
81
+ }
82
+ getSchemaObject(schemaName) {
83
+ var _a;
84
+ return (_a = this.getSchemaObjects()) == null ? void 0 : _a[schemaName];
85
+ }
86
+ getExpectedResponse(responseOperation, status) {
87
+ const response = responseOperation.responses[status];
88
+ if (!response) {
89
+ return void 0;
90
+ }
91
+ if ("$ref" in response) {
92
+ return this.findResponseDefinition(response.$ref);
93
+ }
94
+ return response;
95
+ }
96
+ findExpectedResponse(actualResponse) {
97
+ const actualRequest = actualResponse.req;
98
+ const expectedResponseOperation = this.findExpectedResponseOperation(actualRequest);
99
+ if (!expectedResponseOperation) {
100
+ throw new ValidationError(3 /* MethodNotFound */);
101
+ }
102
+ const { status } = actualResponse;
103
+ const expectedResponse = this.getExpectedResponse(
104
+ expectedResponseOperation,
105
+ status
106
+ );
107
+ if (!expectedResponse) {
108
+ throw new ValidationError(4 /* StatusNotFound */);
109
+ }
110
+ return { [status]: expectedResponse };
111
+ }
112
+ findOpenApiPathMatchingRequest(actualRequest) {
113
+ const actualPathname = getPathname(actualRequest);
114
+ const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);
115
+ return openApiPath;
116
+ }
117
+ findExpectedPathItem(actualRequest) {
118
+ const actualPathname = getPathname(actualRequest);
119
+ const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);
120
+ const pathItemObject = this.getPathItem(openApiPath);
121
+ return pathItemObject;
122
+ }
123
+ findExpectedResponseOperation(actualRequest) {
124
+ const pathItemObject = this.findExpectedPathItem(actualRequest);
125
+ const operationObject = pathItemObject[actualRequest.method.toLowerCase()];
126
+ return operationObject;
127
+ }
128
+ validateResponse(actualResponse) {
129
+ let expectedResponse;
130
+ try {
131
+ expectedResponse = this.findExpectedResponse(actualResponse);
132
+ } catch (error) {
133
+ if (error instanceof ValidationError) {
134
+ return error;
135
+ }
136
+ throw error;
137
+ }
138
+ const validator = new OpenAPIResponseValidator({
139
+ responses: expectedResponse,
140
+ ...this.getComponentDefinitionsProperty()
141
+ });
142
+ const expectedResStatus = Object.keys(expectedResponse)[0];
143
+ const validationError = validator.validateResponse(
144
+ expectedResStatus,
145
+ actualResponse.getBodyForValidation()
146
+ );
147
+ return validationError ? new ValidationError(
148
+ 5 /* InvalidBody */,
149
+ validationError.errors.map(({ path: path2, message }) => `${path2} ${message}`).join(", ")
150
+ ) : null;
151
+ }
152
+ /*
153
+ * For consistency and to save maintaining another dependency,
154
+ * we validate objects using our response validator:
155
+ * We put the object inside a mock response, then validate
156
+ * the whole response against a mock expected response.
157
+ * The 2 mock responses are identical except for the body,
158
+ * thus validating the object against its schema.
159
+ */
160
+ validateObject(actualObject, schema) {
161
+ const mockResStatus = "200";
162
+ const mockExpectedResponse = { [mockResStatus]: { schema } };
163
+ const validator = new OpenAPIResponseValidator({
164
+ responses: mockExpectedResponse,
165
+ ...this.getComponentDefinitionsProperty(),
166
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
167
+ errorTransformer: ({ path: path2, message }) => ({
168
+ message: `${path2.replace("response", "object")} ${message}`
169
+ })
170
+ });
171
+ const validationError = validator.validateResponse(
172
+ mockResStatus,
173
+ actualObject
174
+ );
175
+ return validationError ? new ValidationError(
176
+ 6 /* InvalidObject */,
177
+ validationError.errors.map((error) => error.message).join(", ")
178
+ ) : null;
179
+ }
180
+ };
181
+
182
+ // lib/classes/OpenApi2Spec.ts
183
+ var basePathPropertyNotProvided = (spec) => !spec.basePath;
184
+ var OpenApi2Spec = class extends OpenApiSpec {
185
+ constructor(spec) {
186
+ super(spec);
187
+ this.spec = spec;
188
+ this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);
189
+ }
190
+ /**
191
+ * "If the basePath property is not provided, the API is served directly under the host
192
+ * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields
193
+ */
194
+ findOpenApiPathMatchingPathname(pathname) {
195
+ const { basePath } = this.spec;
196
+ if (basePath && !pathname.startsWith(basePath)) {
197
+ throw new ValidationError(1 /* BasePathNotFound */);
198
+ }
199
+ const pathnameWithoutBasePath = basePath ? getPathnameWithoutBasePath(basePath, pathname) : pathname;
200
+ const openApiPath = findOpenApiPathMatchingPossiblePathnames(
201
+ [pathnameWithoutBasePath],
202
+ this.paths()
203
+ );
204
+ if (!openApiPath) {
205
+ throw new ValidationError(2 /* PathNotFound */);
206
+ }
207
+ return openApiPath;
208
+ }
209
+ findResponseDefinition(referenceString) {
210
+ var _a;
211
+ const nameOfResponseDefinition = referenceString.split("#/responses/")[1];
212
+ return (_a = this.spec.responses) == null ? void 0 : _a[nameOfResponseDefinition];
213
+ }
214
+ getComponentDefinitionsProperty() {
215
+ return { definitions: this.spec.definitions };
216
+ }
217
+ getSchemaObjects() {
218
+ return this.spec.definitions;
219
+ }
220
+ };
221
+
222
+ // lib/utils/OpenApi3Spec.utils.ts
223
+ import generateCombinations from "combos";
224
+ var unique = (array) => [...new Set(array)];
225
+ var serversPropertyNotProvidedOrIsEmptyArray = (spec) => !spec.servers || !spec.servers.length;
226
+ var getBasePath = (url2) => {
227
+ const basePathStartIndex = url2.replace("//", " ").indexOf("/");
228
+ return basePathStartIndex !== -1 ? url2.slice(basePathStartIndex) : defaultBasePath;
229
+ };
230
+ var getPossibleValuesOfServerVariable = ({
231
+ default: defaultValue,
232
+ enum: enumMembers
233
+ }) => enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];
234
+ var mapServerVariablesToPossibleValues = (serverVariables) => Object.entries(serverVariables).reduce(
235
+ (currentMap, [variableName, detailsOfPossibleValues]) => ({
236
+ ...currentMap,
237
+ [variableName]: getPossibleValuesOfServerVariable(
238
+ detailsOfPossibleValues
239
+ )
240
+ }),
241
+ {}
242
+ );
243
+ var convertTemplateExpressionToConcreteExpression = (templateExpression, mapOfVariablesToValues) => Object.entries(mapOfVariablesToValues).reduce(
244
+ (currentExpression, [variable, value]) => currentExpression.replace(`{${variable}}`, value),
245
+ templateExpression
246
+ );
247
+ var getPossibleConcreteBasePaths = (basePath, serverVariables) => {
248
+ const mapOfServerVariablesToPossibleValues = mapServerVariablesToPossibleValues(serverVariables);
249
+ const combinationsOfBasePathVariableValues = generateCombinations(
250
+ mapOfServerVariablesToPossibleValues
251
+ );
252
+ const possibleBasePaths = combinationsOfBasePathVariableValues.map(
253
+ (mapOfVariablesToValues) => convertTemplateExpressionToConcreteExpression(
254
+ basePath,
255
+ mapOfVariablesToValues
256
+ )
257
+ );
258
+ return possibleBasePaths;
259
+ };
260
+ var getPossibleBasePaths = (url2, serverVariables) => {
261
+ const basePath = getBasePath(url2);
262
+ return serverVariables ? getPossibleConcreteBasePaths(basePath, serverVariables) : [basePath];
263
+ };
264
+ var getMatchingServerUrlsAndServerBasePaths = (servers, pathname) => {
265
+ const matchesPathname = (basePath) => pathname.startsWith(basePath);
266
+ return servers.map(({ url: templatedUrl, variables }) => ({
267
+ templatedUrl,
268
+ possibleBasePaths: getPossibleBasePaths(templatedUrl, variables)
269
+ })).filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname)).map(({ templatedUrl, possibleBasePaths }) => {
270
+ const matchingBasePath = possibleBasePaths.find(matchesPathname);
271
+ return {
272
+ concreteUrl: templatedUrl.replace(
273
+ getBasePath(templatedUrl),
274
+ matchingBasePath
275
+ ),
276
+ matchingBasePath
277
+ };
278
+ });
279
+ };
280
+
281
+ // lib/classes/OpenApi3Spec.ts
282
+ var OpenApi3Spec = class extends OpenApiSpec {
283
+ constructor(spec) {
284
+ super(spec);
285
+ this.spec = spec;
286
+ this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);
287
+ this.ensureDefaultServer();
288
+ }
289
+ /**
290
+ * "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 '/'"
291
+ * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields
292
+ */
293
+ ensureDefaultServer() {
294
+ if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {
295
+ this.spec.servers = [{ url: defaultBasePath }];
296
+ }
297
+ }
298
+ servers() {
299
+ return this.spec.servers;
300
+ }
301
+ getServerUrls() {
302
+ return this.servers().map((server) => server.url);
303
+ }
304
+ getMatchingServerUrls(pathname) {
305
+ return getMatchingServerUrlsAndServerBasePaths(
306
+ this.servers(),
307
+ pathname
308
+ ).map(({ concreteUrl }) => concreteUrl);
309
+ }
310
+ getMatchingServerBasePaths(pathname) {
311
+ return getMatchingServerUrlsAndServerBasePaths(
312
+ this.servers(),
313
+ pathname
314
+ ).map(({ matchingBasePath }) => matchingBasePath);
315
+ }
316
+ findOpenApiPathMatchingPathname(pathname) {
317
+ const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);
318
+ if (!matchingServerBasePaths.length) {
319
+ throw new ValidationError(0 /* ServerNotFound */);
320
+ }
321
+ const possiblePathnames = matchingServerBasePaths.map(
322
+ (basePath) => getPathnameWithoutBasePath(basePath, pathname)
323
+ );
324
+ const openApiPath = findOpenApiPathMatchingPossiblePathnames(
325
+ possiblePathnames,
326
+ this.paths()
327
+ );
328
+ if (!openApiPath) {
329
+ throw new ValidationError(2 /* PathNotFound */);
330
+ }
331
+ return openApiPath;
332
+ }
333
+ findResponseDefinition(referenceString) {
334
+ var _a, _b;
335
+ const nameOfResponseDefinition = referenceString.split(
336
+ "#/components/responses/"
337
+ )[1];
338
+ return (_b = (_a = this.spec.components) == null ? void 0 : _a.responses) == null ? void 0 : _b[nameOfResponseDefinition];
339
+ }
340
+ getComponentDefinitionsProperty() {
341
+ return { components: this.spec.components };
342
+ }
343
+ getSchemaObjects() {
344
+ var _a;
345
+ return (_a = this.spec.components) == null ? void 0 : _a.schemas;
346
+ }
347
+ };
348
+
349
+ // lib/openApiSpecFactory.ts
350
+ var isObject = (arg) => typeof arg === "object" && arg !== null && !Array.isArray(arg);
351
+ function makeApiSpec(filepathOrObject) {
352
+ const spec = loadSpec(filepathOrObject);
353
+ validateSpec(spec);
354
+ const validSpec = spec;
355
+ if ("swagger" in validSpec) {
356
+ return new OpenApi2Spec(validSpec);
357
+ }
358
+ return new OpenApi3Spec(validSpec);
359
+ }
360
+ function loadSpec(arg) {
361
+ try {
362
+ if (typeof arg === "string") {
363
+ return loadFile(arg);
364
+ }
365
+ if (isObject(arg)) {
366
+ return arg;
367
+ }
368
+ throw new Error(`Received type '${typeOf(arg)}'`);
369
+ } catch (error) {
370
+ throw new Error(
371
+ `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.
372
+ Error details: ${error.message}`
373
+ );
374
+ }
375
+ }
376
+ function loadFile(filepath) {
377
+ if (!path.isAbsolute(filepath)) {
378
+ throw new Error(`'${filepath}' is not an absolute filepath`);
379
+ }
380
+ const fileData = fs.readFileSync(filepath, { encoding: "utf8" });
381
+ try {
382
+ return yaml.load(fileData);
383
+ } catch (error) {
384
+ throw new Error(`Invalid YAML or JSON:
385
+ ${error.message}`);
386
+ }
387
+ }
388
+ function validateSpec(obj) {
389
+ try {
390
+ const validator = new OpenAPISchemaValidator({
391
+ version: obj.swagger || // '2.0'
392
+ obj.openapi
393
+ // '3.X.X'
394
+ });
395
+ const { errors } = validator.validate(obj);
396
+ if (errors.length > 0) {
397
+ throw new Error(stringify(errors));
398
+ }
399
+ return obj;
400
+ } catch (error) {
401
+ throw new Error(`Invalid OpenAPI spec: ${error.message}`);
402
+ }
403
+ }
404
+
405
+ // lib/classes/AbstractResponse.ts
406
+ var AbstractResponse = class {
407
+ constructor(res) {
408
+ this.res = res;
409
+ }
410
+ summary() {
411
+ return {
412
+ body: this.body
413
+ };
414
+ }
415
+ toString() {
416
+ return stringify(this.summary());
417
+ }
418
+ };
419
+
420
+ // lib/classes/AxiosResponse.ts
421
+ var AxiosResponse = class extends AbstractResponse {
422
+ constructor(res) {
423
+ super(res);
424
+ this.res = res;
425
+ this.status = res.status;
426
+ this.body = res.data;
427
+ this.req = res.request;
428
+ this.bodyHasNoContent = this.body === "";
429
+ }
430
+ getBodyForValidation() {
431
+ if (this.bodyHasNoContent) {
432
+ return null;
433
+ }
434
+ return this.body;
435
+ }
436
+ };
437
+
438
+ // lib/classes/SuperAgentResponse.ts
439
+ var isEmptyObj = (obj) => !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;
440
+ var SuperAgentResponse = class extends AbstractResponse {
441
+ constructor(res) {
442
+ super(res);
443
+ this.res = res;
444
+ this.status = res.status;
445
+ this.body = res.body;
446
+ this.req = res.req;
447
+ this.isResTextPopulatedInsteadOfResBody = res.text !== "{}" && isEmptyObj(this.body);
448
+ this.bodyHasNoContent = res.text === "";
449
+ }
450
+ getBodyForValidation() {
451
+ if (this.bodyHasNoContent) {
452
+ return null;
453
+ }
454
+ if (this.isResTextPopulatedInsteadOfResBody) {
455
+ return this.res.text;
456
+ }
457
+ return this.body;
458
+ }
459
+ summary() {
460
+ return {
461
+ ...super.summary(),
462
+ ...this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }
463
+ };
464
+ }
465
+ };
466
+
467
+ // lib/responseFactory.ts
468
+ function makeResponse(res) {
469
+ if ("data" in res) {
470
+ return new AxiosResponse(res);
471
+ }
472
+ if ("status" in res) {
473
+ return new SuperAgentResponse(res);
474
+ }
475
+ throw new Error(
476
+ "Unsupported response object: expected axios, supertest, superagent, or chai-http response shape."
477
+ );
478
+ }
479
+ export {
480
+ ErrorCode,
481
+ makeApiSpec,
482
+ makeResponse
483
+ };
484
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +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 OpenAPISchemaValidator 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\ntype AnyObject = Record<string, unknown>;\n\nconst isObject = (arg: unknown): arg is AnyObject =>\n typeof arg === 'object' && arg !== null && !Array.isArray(arg);\n\nexport default function makeApiSpec(\n filepathOrObject: string | OpenAPI.Document,\n): OpenApi2Spec | OpenApi3Spec {\n const spec = loadSpec(filepathOrObject);\n validateSpec(spec);\n const validSpec = spec as OpenAPI.Document;\n if ('swagger' in validSpec) {\n return new OpenApi2Spec(validSpec);\n }\n return new OpenApi3Spec(validSpec as OpenAPIV3.Document);\n}\n\nfunction loadSpec(arg: unknown): AnyObject {\n try {\n if (typeof arg === 'string') {\n return loadFile(arg);\n }\n if (isObject(arg)) {\n return arg;\n }\n throw new Error(`Received type '${typeOf(arg)}'`);\n } catch (error) {\n throw new Error(\n `The provided argument must be either an absolute filepath or an object representing an OpenAPI specification.\\nError details: ${\n (error as Error).message\n }`,\n );\n }\n}\n\nfunction loadFile(filepath: string): AnyObject {\n if (!path.isAbsolute(filepath)) {\n throw new Error(`'${filepath}' is not an absolute filepath`);\n }\n const fileData = fs.readFileSync(filepath, { encoding: 'utf8' });\n try {\n return yaml.load(fileData) as AnyObject;\n } catch (error) {\n throw new Error(`Invalid YAML or JSON:\\n${(error as Error).message}`);\n }\n}\n\nfunction validateSpec(obj: AnyObject): OpenAPI.Document {\n try {\n const validator = new OpenAPISchemaValidator({\n version:\n (obj as unknown as OpenAPIV2.Document).swagger || // '2.0'\n (obj as unknown as OpenAPIV3.Document).openapi, // '3.X.X'\n });\n const { errors } = validator.validate(obj as OpenAPI.Document);\n if (errors.length > 0) {\n throw new Error(stringify(errors));\n }\n return obj as OpenAPI.Document;\n } catch (error) {\n throw new Error(`Invalid OpenAPI spec: ${(error as Error).message}`);\n }\n}\n","import { Path } from 'path-parser';\nimport url from 'url';\nimport { inspect } from 'util';\nimport type { ActualRequest } from '../classes/AbstractResponse';\n\nexport const stringify = (obj: unknown): string =>\n inspect(obj, { depth: null });\n\n/**\n * Excludes the query because path = pathname + query\n */\nexport const getPathname = (request: ActualRequest): string =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n url.parse(request.path).pathname!;\n\n/**\n * Converts all {foo} to :foo\n */\nconst convertOpenApiPathToColonForm = (openApiPath: string): string =>\n openApiPath.replace(/{/g, ':').replace(/}/g, '');\n\nconst doesColonPathMatchPathname = (\n pathInColonForm: string,\n pathname: string,\n): boolean => {\n /*\n * By default, OpenAPI path parameters have `style: simple; explode: false` (https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object)\n * So array path parameters in the pathname of the actual request should be in the form: `/pathParams/a,b,c`\n * `path-parser` fails to match parameter patterns to parameters containing commas.\n * So we remove the commas.\n */\n const pathWithoutCommas = pathname.replace(/,/g, '');\n const pathParamsInPathname = new Path(pathInColonForm).test(\n pathWithoutCommas,\n ); // => one of: null, {}, {exampleParam: 'foo'}\n return Boolean(pathParamsInPathname);\n};\n\nconst doesOpenApiPathMatchPathname = (\n openApiPath: string,\n pathname: string,\n): boolean => {\n const pathInColonForm = convertOpenApiPathToColonForm(openApiPath);\n return doesColonPathMatchPathname(pathInColonForm, pathname);\n};\n\nexport const findOpenApiPathMatchingPossiblePathnames = (\n possiblePathnames: string[],\n OAPaths: string[],\n): string | undefined => {\n let openApiPath: string | undefined;\n // eslint-disable-next-line no-restricted-syntax\n for (const pathname of possiblePathnames) {\n // eslint-disable-next-line no-restricted-syntax\n for (const OAPath of OAPaths) {\n if (OAPath === pathname) {\n return OAPath;\n }\n if (doesOpenApiPathMatchPathname(OAPath, pathname)) {\n openApiPath = OAPath;\n }\n }\n }\n return openApiPath;\n};\n\nexport const defaultBasePath = '/';\n\nexport const getPathnameWithoutBasePath = (\n basePath: string,\n pathname: string,\n): string =>\n basePath === defaultBasePath ? pathname : pathname.replace(basePath, '');\n","import OpenAPIResponseValidator, {\n type OpenAPIResponseValidatorArgs,\n} from 'openapi-response-validator';\nimport type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';\nimport { getPathname } from '../utils/common.utils';\nimport type { ActualRequest, ActualResponse } from './AbstractResponse';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\ntype Document = OpenAPIV2.Document | OpenAPIV3.Document;\n\ntype Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;\n\ntype HttpMethods = OpenAPIV2.HttpMethods;\n\ntype PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;\n\nexport type ResponseObjectWithSchema =\n | (OpenAPIV2.ResponseObject & { schema: OpenAPIV2.Schema })\n | (OpenAPIV3.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3.MediaTypeObject & {\n schema: OpenAPIV3.SchemaObject;\n };\n };\n })\n | (OpenAPIV3_1.ResponseObject & {\n content: {\n [media: string]: OpenAPIV3_1.MediaTypeObject & {\n schema: OpenAPIV3_1.SchemaObject;\n };\n };\n });\n\nexport type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;\n\nexport default abstract class OpenApiSpec {\n protected abstract getSchemaObjects(): Record<string, Schema> | undefined;\n\n protected abstract findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined;\n\n protected abstract findOpenApiPathMatchingPathname(pathname: string): string;\n\n protected abstract getComponentDefinitionsProperty():\n | {\n definitions: OpenAPIV2.Document['definitions'];\n }\n | {\n components: OpenAPIV3.Document['components'];\n };\n\n constructor(protected spec: Document) {}\n\n pathsObject(): Document['paths'] {\n return this.spec.paths;\n }\n\n getPathItem(openApiPath: string): PathItemObject {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.pathsObject()[openApiPath]!;\n }\n\n paths(): string[] {\n return Object.keys(this.pathsObject());\n }\n\n getSchemaObject(schemaName: string): Schema | undefined {\n return this.getSchemaObjects()?.[schemaName];\n }\n\n getExpectedResponse(\n responseOperation: Operation,\n status: ActualResponse['status'],\n ): ResponseObjectWithSchema | undefined {\n const response = responseOperation.responses[status];\n if (!response) {\n return undefined;\n }\n if ('$ref' in response) {\n return this.findResponseDefinition(response.$ref);\n }\n return response as ResponseObjectWithSchema;\n }\n\n findExpectedResponse(\n actualResponse: ActualResponse,\n ): Record<string, ResponseObjectWithSchema> {\n const actualRequest = actualResponse.req;\n const expectedResponseOperation =\n this.findExpectedResponseOperation(actualRequest);\n if (!expectedResponseOperation) {\n throw new ValidationError(ErrorCode.MethodNotFound);\n }\n\n const { status } = actualResponse;\n const expectedResponse = this.getExpectedResponse(\n expectedResponseOperation,\n status,\n );\n if (!expectedResponse) {\n throw new ValidationError(ErrorCode.StatusNotFound);\n }\n\n return { [status]: expectedResponse };\n }\n\n findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n return openApiPath;\n }\n\n findExpectedPathItem(actualRequest: ActualRequest): PathItemObject {\n const actualPathname = getPathname(actualRequest);\n const openApiPath = this.findOpenApiPathMatchingPathname(actualPathname);\n const pathItemObject = this.getPathItem(openApiPath);\n return pathItemObject;\n }\n\n findExpectedResponseOperation(\n actualRequest: ActualRequest,\n ): Operation | undefined {\n const pathItemObject = this.findExpectedPathItem(actualRequest);\n const operationObject =\n pathItemObject[actualRequest.method.toLowerCase() as HttpMethods];\n return operationObject;\n }\n\n validateResponse(actualResponse: ActualResponse): ValidationError | null {\n let expectedResponse: Record<string, ResponseObjectWithSchema>;\n try {\n expectedResponse = this.findExpectedResponse(actualResponse);\n } catch (error) {\n if (error instanceof ValidationError) {\n return error;\n }\n throw error;\n }\n const validator = new OpenAPIResponseValidator({\n responses: expectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n } as OpenAPIResponseValidatorArgs);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const expectedResStatus = Object.keys(expectedResponse)[0]!;\n const validationError = validator.validateResponse(\n expectedResStatus,\n actualResponse.getBodyForValidation(),\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidBody,\n validationError.errors!\n .map(({ path, message }: { path?: string; message: string }) => `${path} ${message}`)\n .join(', '),\n )\n : null;\n }\n\n /*\n * For consistency and to save maintaining another dependency,\n * we validate objects using our response validator:\n * We put the object inside a mock response, then validate\n * the whole response against a mock expected response.\n * The 2 mock responses are identical except for the body,\n * thus validating the object against its schema.\n */\n validateObject(\n actualObject: unknown,\n schema: Schema,\n ): ValidationError | null {\n const mockResStatus = '200';\n const mockExpectedResponse = { [mockResStatus]: { schema } };\n const validator = new OpenAPIResponseValidator({\n responses: mockExpectedResponse as OpenAPIResponseValidatorArgs['responses'],\n ...this.getComponentDefinitionsProperty(),\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n errorTransformer: ({ path, message }: { path?: string; message: string; errorCode: string }) => ({\n message: `${path!.replace('response', 'object')} ${message}`,\n }),\n } as OpenAPIResponseValidatorArgs);\n const validationError = validator.validateResponse(\n mockResStatus,\n actualObject,\n );\n return validationError\n ? new ValidationError(\n ErrorCode.InvalidObject,\n validationError.errors!.map((error: { message: string }) => error.message).join(', '),\n )\n : null;\n }\n}\n","import type { OpenAPIV2 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n getPathnameWithoutBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n} from '../utils/common.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nconst basePathPropertyNotProvided = (spec: OpenAPIV2.Document): boolean =>\n !spec.basePath;\n\nexport default class OpenApi2Spec extends AbstractOpenApiSpec {\n public didUserDefineBasePath: boolean;\n\n constructor(public override spec: OpenAPIV2.Document) {\n super(spec);\n this.didUserDefineBasePath = !basePathPropertyNotProvided(spec);\n }\n\n /**\n * \"If the basePath property is not provided, the API is served directly under the host\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#fixed-fields\n */\n findOpenApiPathMatchingPathname(pathname: string): string {\n const { basePath } = this.spec;\n if (basePath && !pathname.startsWith(basePath)) {\n throw new ValidationError(ErrorCode.BasePathNotFound);\n }\n const pathnameWithoutBasePath = basePath\n ? getPathnameWithoutBasePath(basePath, pathname)\n : pathname;\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n [pathnameWithoutBasePath],\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split('#/responses/')[1]!;\n return this.spec.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n definitions: OpenAPIV2.Document['definitions'];\n } {\n return { definitions: this.spec.definitions };\n }\n\n getSchemaObjects(): OpenAPIV2.Document['definitions'] {\n return this.spec.definitions;\n }\n}\n","import generateCombinations from 'combos';\nimport type { OpenAPIV3 } from 'openapi-types';\nimport { defaultBasePath } from './common.utils';\n\ntype ServerVariables = OpenAPIV3.ServerObject['variables'];\n\nconst unique = <T>(array: T[]): T[] => [...new Set(array)];\n\nexport const serversPropertyNotProvidedOrIsEmptyArray = (\n spec: OpenAPIV3.Document,\n): boolean => !spec.servers || !spec.servers.length;\n\nconst getBasePath = (url: string): string => {\n const basePathStartIndex = url.replace('//', ' ').indexOf('/');\n return basePathStartIndex !== -1\n ? url.slice(basePathStartIndex)\n : defaultBasePath;\n};\n\nconst getPossibleValuesOfServerVariable = ({\n default: defaultValue,\n enum: enumMembers,\n}: OpenAPIV3.ServerVariableObject): string[] =>\n enumMembers ? unique([defaultValue].concat(enumMembers)) : [defaultValue];\n\nconst mapServerVariablesToPossibleValues = (\n serverVariables: NonNullable<ServerVariables>,\n): Record<string, string[]> =>\n Object.entries(serverVariables).reduce(\n (currentMap, [variableName, detailsOfPossibleValues]) => ({\n ...currentMap,\n [variableName]: getPossibleValuesOfServerVariable(\n detailsOfPossibleValues,\n ),\n }),\n {},\n );\n\nconst convertTemplateExpressionToConcreteExpression = (\n templateExpression: string,\n mapOfVariablesToValues: Record<string, string>,\n) =>\n Object.entries(mapOfVariablesToValues).reduce(\n (currentExpression, [variable, value]) =>\n currentExpression.replace(`{${variable}}`, value),\n templateExpression,\n );\n\nconst getPossibleConcreteBasePaths = (\n basePath: string,\n serverVariables: NonNullable<ServerVariables>,\n): string[] => {\n const mapOfServerVariablesToPossibleValues =\n mapServerVariablesToPossibleValues(serverVariables);\n const combinationsOfBasePathVariableValues = generateCombinations(\n mapOfServerVariablesToPossibleValues,\n );\n const possibleBasePaths = combinationsOfBasePathVariableValues.map(\n (mapOfVariablesToValues) =>\n convertTemplateExpressionToConcreteExpression(\n basePath,\n mapOfVariablesToValues,\n ),\n );\n return possibleBasePaths;\n};\n\nconst getPossibleBasePaths = (\n url: string,\n serverVariables: ServerVariables,\n): string[] => {\n const basePath = getBasePath(url);\n return serverVariables\n ? getPossibleConcreteBasePaths(basePath, serverVariables)\n : [basePath];\n};\n\nexport const getMatchingServerUrlsAndServerBasePaths = (\n servers: OpenAPIV3.ServerObject[],\n pathname: string,\n): { concreteUrl: string; matchingBasePath: string }[] => {\n const matchesPathname = (basePath: string): boolean =>\n pathname.startsWith(basePath);\n return servers\n .map(({ url: templatedUrl, variables }) => ({\n templatedUrl,\n possibleBasePaths: getPossibleBasePaths(templatedUrl, variables),\n }))\n .filter(({ possibleBasePaths }) => possibleBasePaths.some(matchesPathname))\n .map(({ templatedUrl, possibleBasePaths }) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const matchingBasePath = possibleBasePaths.find(matchesPathname)!;\n return {\n concreteUrl: templatedUrl.replace(\n getBasePath(templatedUrl),\n matchingBasePath,\n ),\n matchingBasePath,\n };\n });\n};\n","import type { OpenAPIV3 } from 'openapi-types';\nimport type { ResponseObjectWithSchema } from './AbstractOpenApiSpec';\nimport {\n defaultBasePath,\n findOpenApiPathMatchingPossiblePathnames,\n getPathnameWithoutBasePath,\n} from '../utils/common.utils';\nimport {\n serversPropertyNotProvidedOrIsEmptyArray,\n getMatchingServerUrlsAndServerBasePaths,\n} from '../utils/OpenApi3Spec.utils';\nimport AbstractOpenApiSpec from './AbstractOpenApiSpec';\nimport ValidationError, { ErrorCode } from './errors/ValidationError';\n\nexport default class OpenApi3Spec extends AbstractOpenApiSpec {\n public didUserDefineServers: boolean;\n\n constructor(protected override spec: OpenAPIV3.Document) {\n super(spec);\n this.didUserDefineServers = !serversPropertyNotProvidedOrIsEmptyArray(spec);\n this.ensureDefaultServer();\n }\n\n /**\n * \"If the servers property is not provided, or is an empty array, the default value would be a Server Object with a url value of '/'\"\n * @see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#fixed-fields\n */\n ensureDefaultServer(): void {\n if (serversPropertyNotProvidedOrIsEmptyArray(this.spec)) {\n this.spec.servers = [{ url: defaultBasePath }];\n }\n }\n\n servers(): OpenAPIV3.ServerObject[] {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return this.spec.servers!;\n }\n\n getServerUrls(): string[] {\n return this.servers().map((server) => server.url);\n }\n\n getMatchingServerUrls(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ concreteUrl }) => concreteUrl);\n }\n\n getMatchingServerBasePaths(pathname: string): string[] {\n return getMatchingServerUrlsAndServerBasePaths(\n this.servers(),\n pathname,\n ).map(({ matchingBasePath }) => matchingBasePath);\n }\n\n findOpenApiPathMatchingPathname(pathname: string): string {\n const matchingServerBasePaths = this.getMatchingServerBasePaths(pathname);\n if (!matchingServerBasePaths.length) {\n throw new ValidationError(ErrorCode.ServerNotFound);\n }\n const possiblePathnames = matchingServerBasePaths.map((basePath) =>\n getPathnameWithoutBasePath(basePath, pathname),\n );\n const openApiPath = findOpenApiPathMatchingPossiblePathnames(\n possiblePathnames,\n this.paths(),\n );\n if (!openApiPath) {\n throw new ValidationError(ErrorCode.PathNotFound);\n }\n return openApiPath;\n }\n\n findResponseDefinition(\n referenceString: string,\n ): ResponseObjectWithSchema | undefined {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const nameOfResponseDefinition = referenceString.split(\n '#/components/responses/',\n )[1]!;\n return this.spec.components?.responses?.[nameOfResponseDefinition] as\n | ResponseObjectWithSchema\n | undefined;\n }\n\n getComponentDefinitionsProperty(): {\n components: OpenAPIV3.Document['components'];\n } {\n return { components: this.spec.components };\n }\n\n getSchemaObjects(): OpenAPIV3.ComponentsObject['schemas'] {\n return this.spec.components?.schemas;\n }\n}\n","import { stringify } from '../utils/common.utils';\nimport type { RawAxiosResponse } from './AxiosResponse';\nimport type { RawSuperAgentResponse } from './SuperAgentResponse';\n\nexport type RawResponse =\n | RawAxiosResponse\n | RawSuperAgentResponse;\n\nexport default abstract class AbstractResponse {\n declare public status: number;\n\n declare public req: { method: string; path: string };\n\n public abstract getBodyForValidation(): unknown;\n\n protected body: unknown;\n\n declare protected bodyHasNoContent: boolean;\n\n constructor(protected res: RawResponse) {}\n\n summary(): { body: unknown } {\n return {\n body: this.body,\n };\n }\n\n toString(): string {\n return stringify(this.summary());\n }\n}\n\nexport type ActualResponse = AbstractResponse;\n\nexport type ActualRequest = AbstractResponse['req'];\n","import type { AxiosResponse as AxiosResponseType } from 'axios';\nimport AbstractResponse from './AbstractResponse';\n\nexport type RawAxiosResponse = AxiosResponseType;\n\nexport default class AxiosResponse extends AbstractResponse {\n constructor(protected override res: RawAxiosResponse) {\n super(res);\n this.status = res.status;\n this.body = res.data;\n this.req = res.request;\n this.bodyHasNoContent = this.body === '';\n }\n\n getBodyForValidation(): AxiosResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n return this.body;\n }\n}\n","import type { Response, SuperAgentRequest } from 'superagent';\nimport AbstractResponse from './AbstractResponse';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst isEmptyObj = (obj: any): obj is Record<string, never> =>\n !!obj && Object.entries(obj).length === 0 && obj.constructor === Object;\n\nexport type RawSuperAgentResponse = Response & {\n req: SuperAgentRequest & { path: string };\n};\n\nexport default class SuperAgentResponse extends AbstractResponse {\n private isResTextPopulatedInsteadOfResBody: boolean;\n\n constructor(protected override res: RawSuperAgentResponse) {\n super(res);\n this.status = res.status;\n this.body = res.body;\n this.req = res.req;\n this.isResTextPopulatedInsteadOfResBody =\n res.text !== '{}' && isEmptyObj(this.body);\n this.bodyHasNoContent = res.text === '';\n }\n\n getBodyForValidation(): SuperAgentResponse['body'] {\n if (this.bodyHasNoContent) {\n return null;\n }\n if (this.isResTextPopulatedInsteadOfResBody) {\n return this.res.text;\n }\n return this.body;\n }\n\n override summary(): ReturnType<AbstractResponse['summary']> & {\n text?: string;\n } {\n return {\n ...super.summary(),\n ...(this.isResTextPopulatedInsteadOfResBody && { text: this.res.text }),\n };\n }\n}\n","import { RawResponse } from './classes/AbstractResponse';\nimport AxiosResponse from './classes/AxiosResponse';\nimport SuperAgentResponse from './classes/SuperAgentResponse';\n\nexport default function makeResponse(\n res: RawResponse,\n): AxiosResponse | SuperAgentResponse {\n if ('data' in res) {\n return new AxiosResponse(res);\n }\n if ('status' in res) {\n return new SuperAgentResponse(res);\n }\n throw new Error(\n 'Unsupported response object: expected axios, supertest, superagent, or chai-http response shape.',\n );\n}\n"],"mappings":"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","names":["ErrorCode","path","url"]}
package/package.json CHANGED
@@ -1,20 +1,37 @@
1
1
  {
2
2
  "name": "@ehuelsmann/openapi-validator",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "Common code for jest-openapi and Chai OpenAPI Response Validator",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.js"
17
+ }
18
+ }
19
+ },
7
20
  "scripts": {
8
21
  "clean": "rimraf dist",
9
22
  "format": "prettier --write . --ignore-path ../../.prettierignore",
10
23
  "lint": "tsc --noEmit && eslint .",
11
24
  "lint:fix": "yarn lint --fix",
12
- "build": "tsc",
25
+ "build": "tsup",
13
26
  "test": "echo",
14
27
  "test:ci": "echo",
15
28
  "prepack": "yarn build"
16
29
  },
17
- "repository": "https://github.com/openapi-library/OpenAPIValidators/tree/master/packages/openapi-validator",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/ehuelsmann/OpenAPIValidators.git#master",
33
+ "directory": "packages/openapi-validator"
34
+ },
18
35
  "author": "OpenApiChai <openapichai@gmail.com>",
19
36
  "contributors": [
20
37
  "rwalle61 <richard.lh.waller@gmail.com>",
@@ -30,9 +47,9 @@
30
47
  "validate"
31
48
  ],
32
49
  "bugs": {
33
- "url": "https://github.com/openapi-library/OpenAPIValidators/issues"
50
+ "url": "https://github.com/ehuelsmann/OpenAPIValidators/issues"
34
51
  },
35
- "homepage": "https://github.com/openapi-library/OpenAPIValidators#openapi-validators",
52
+ "homepage": "https://github.com/ehuelsmann/OpenAPIValidators#openapi-validators",
36
53
  "publishConfig": {
37
54
  "access": "public"
38
55
  },
@@ -40,7 +57,6 @@
40
57
  "dist"
41
58
  ],
42
59
  "dependencies": {
43
- "@types/request": "^2.48.7",
44
60
  "@types/superagent": "^4.1.12",
45
61
  "axios": "^1.15.0",
46
62
  "combos": "^0.2.0",
@@ -55,6 +71,7 @@
55
71
  "@types/fs-extra": "^9.0.12",
56
72
  "@types/js-yaml": "^4.0.3",
57
73
  "@types/typeof": "^1.0.0",
58
- "openapi-types": "^12.1.3"
74
+ "openapi-types": "^12.1.3",
75
+ "tsup": "^8.5.1"
59
76
  }
60
77
  }
@@ -1,47 +0,0 @@
1
- import type { OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from 'openapi-types';
2
- import type { ActualRequest, ActualResponse } from './AbstractResponse';
3
- import ValidationError from './errors/ValidationError';
4
- type Document = OpenAPIV2.Document | OpenAPIV3.Document;
5
- type Operation = OpenAPIV2.OperationObject | OpenAPIV3.OperationObject;
6
- type PathItemObject = OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject;
7
- export type ResponseObjectWithSchema = (OpenAPIV2.ResponseObject & {
8
- schema: OpenAPIV2.Schema;
9
- }) | (OpenAPIV3.ResponseObject & {
10
- content: {
11
- [media: string]: OpenAPIV3.MediaTypeObject & {
12
- schema: OpenAPIV3.SchemaObject;
13
- };
14
- };
15
- }) | (OpenAPIV3_1.ResponseObject & {
16
- content: {
17
- [media: string]: OpenAPIV3_1.MediaTypeObject & {
18
- schema: OpenAPIV3_1.SchemaObject;
19
- };
20
- };
21
- });
22
- export type Schema = OpenAPIV2.Schema | OpenAPIV3.SchemaObject;
23
- export default abstract class OpenApiSpec {
24
- protected spec: Document;
25
- protected abstract getSchemaObjects(): Record<string, Schema> | undefined;
26
- protected abstract findResponseDefinition(referenceString: string): ResponseObjectWithSchema | undefined;
27
- protected abstract findOpenApiPathMatchingPathname(pathname: string): string;
28
- protected abstract getComponentDefinitionsProperty(): {
29
- definitions: OpenAPIV2.Document['definitions'];
30
- } | {
31
- components: OpenAPIV3.Document['components'];
32
- };
33
- constructor(spec: Document);
34
- pathsObject(): Document['paths'];
35
- getPathItem(openApiPath: string): PathItemObject;
36
- paths(): string[];
37
- getSchemaObject(schemaName: string): Schema | undefined;
38
- getExpectedResponse(responseOperation: Operation, status: ActualResponse['status']): ResponseObjectWithSchema | undefined;
39
- findExpectedResponse(actualResponse: ActualResponse): Record<string, ResponseObjectWithSchema>;
40
- findOpenApiPathMatchingRequest(actualRequest: ActualRequest): string;
41
- findExpectedPathItem(actualRequest: ActualRequest): PathItemObject;
42
- findExpectedResponseOperation(actualRequest: ActualRequest): Operation | undefined;
43
- validateResponse(actualResponse: ActualResponse): ValidationError | null;
44
- validateObject(actualObject: unknown, schema: Schema): ValidationError | null;
45
- }
46
- export {};
47
- //# sourceMappingURL=AbstractOpenApiSpec.d.ts.map