serverless-openapi-documenter 0.0.111 → 0.0.113

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-openapi-documenter",
3
- "version": "0.0.111",
3
+ "version": "0.0.113",
4
4
  "description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -50,7 +50,6 @@
50
50
  "chalk": "^4.1.2",
51
51
  "js-yaml": "^4.1.0",
52
52
  "json-schema-for-openapi": "^0.5.0",
53
- "lodash.isequal": "^4.5.0",
54
53
  "openapi-to-postmanv2": "^5.0.0",
55
54
  "uuid": "^11.1.0"
56
55
  },
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ const isEqual = require("node:util").isDeepStrictEqual;
3
4
  const path = require("path");
4
5
 
5
6
  const {
@@ -8,7 +9,6 @@ const {
8
9
  stringifyYaml,
9
10
  createConfig,
10
11
  } = require("@redocly/openapi-core");
11
- const isEqual = require("lodash.isequal");
12
12
  const { v4: uuid } = require("uuid");
13
13
 
14
14
  const SchemaHandler = require("./schemaHandler");
@@ -39,7 +39,11 @@ class DefinitionGenerator {
39
39
  },
40
40
  };
41
41
 
42
- this.schemaHandler = new SchemaHandler(serverless, this.openAPI);
42
+ this.schemaHandler = new SchemaHandler(
43
+ serverless,
44
+ this.openAPI,
45
+ this.logger
46
+ );
43
47
 
44
48
  this.operationIdMap = {};
45
49
  this.functionMap = {};
@@ -620,7 +624,7 @@ class DefinitionGenerator {
620
624
  continue;
621
625
  }
622
626
 
623
- const obj = JSON.parse(JSON.stringify(this.DEFAULT_CORS_HEADERS[key]));
627
+ const obj = structuredClone(this.DEFAULT_CORS_HEADERS[key]);
624
628
 
625
629
  if (key === "Access-Control-Allow-Origin") {
626
630
  if (
@@ -241,7 +241,7 @@ class OpenAPIGenerator {
241
241
  };
242
242
 
243
243
  PostmanGenerator.convert(
244
- { type: "json", data: JSON.parse(JSON.stringify(openAPI)) },
244
+ { type: "json", data: structuredClone(openAPI) },
245
245
  {},
246
246
  postmanGeneration
247
247
  );
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ const isEqual = require("node:util").isDeepStrictEqual;
3
4
  const path = require("path");
4
5
 
5
6
  const $RefParser = require("@apidevtools/json-schema-ref-parser");
6
7
  const SchemaConvertor = require("json-schema-for-openapi");
7
- const isEqual = require("lodash.isequal");
8
8
  const { v4: uuid } = require("uuid");
9
9
 
10
10
  class SchemaHandler {
11
- constructor(serverless, openAPI) {
11
+ constructor(serverless, openAPI, logger) {
12
+ this.logger = logger;
13
+
12
14
  this.apiGatewayModels =
13
15
  serverless.service?.provider?.apiGateway?.request?.schemas || {};
14
16
  this.documentation = serverless.service.custom.documentation;
@@ -19,6 +21,12 @@ class SchemaHandler {
19
21
  this.__standardiseModels();
20
22
 
21
23
  try {
24
+ this.logger.verbose(
25
+ `Trying to resolve Ref-Parser config from: ${path.resolve(
26
+ "options",
27
+ "ref-parser.js"
28
+ )}`
29
+ );
22
30
  this.refParserOptions = require(path.resolve("options", "ref-parser.js"));
23
31
  } catch (err) {
24
32
  this.refParserOptions = {};
@@ -63,24 +71,15 @@ class SchemaHandler {
63
71
  const modelName = model.name;
64
72
  const modelSchema = model.schema;
65
73
 
66
- const dereferencedSchema = await this.__dereferenceSchema(
67
- modelSchema
74
+ const convertedSchemas = await this.__dereferenceAndConvert(
75
+ modelSchema,
76
+ modelName,
77
+ model
68
78
  ).catch((err) => {
69
- if (err.errors) {
70
- for (const error of err?.errors) {
71
- this.__HTTPError(error, model);
72
- }
73
- } else {
74
- this.__HTTPError(err, model);
75
- }
76
- return modelSchema;
79
+ if (err instanceof Error) throw err;
80
+ else return err;
77
81
  });
78
82
 
79
- const convertedSchemas = SchemaConvertor.convert(
80
- dereferencedSchema,
81
- modelName
82
- );
83
-
84
83
  if (
85
84
  typeof convertedSchemas.schemas === "object" &&
86
85
  !Array.isArray(convertedSchemas.schemas) &&
@@ -119,13 +118,12 @@ class SchemaHandler {
119
118
  return this.modelReferences[name];
120
119
  }
121
120
 
122
- const dereferencedSchema = await this.__dereferenceSchema(schema).catch(
123
- (err) => {
124
- throw err;
125
- }
126
- );
127
-
128
- const convertedSchemas = SchemaConvertor.convert(dereferencedSchema, name);
121
+ const convertedSchemas = await this.__dereferenceAndConvert(schema, name, {
122
+ name,
123
+ schema,
124
+ }).catch((err) => {
125
+ throw err;
126
+ });
129
127
 
130
128
  for (const [schemaName, schemaValue] of Object.entries(
131
129
  convertedSchemas.schemas
@@ -147,6 +145,32 @@ class SchemaHandler {
147
145
  return `#/components/schemas/${finalName}`;
148
146
  }
149
147
 
148
+ async __dereferenceAndConvert(schema, name, model) {
149
+ this.logger.verbose(`dereferencing model: ${name}`);
150
+ const dereferencedSchema = await this.__dereferenceSchema(schema).catch(
151
+ (err) => {
152
+ this.__checkForHTTPErrorsAndThrow(err, model);
153
+
154
+ this.__checkForMissingPathAndThrow(err);
155
+
156
+ return schema;
157
+ }
158
+ );
159
+
160
+ this.logger.verbose(
161
+ `dereferenced model: ${JSON.stringify(dereferencedSchema)}`
162
+ );
163
+
164
+ this.logger.verbose(`converting model: ${name}`);
165
+ const convertedSchemas = SchemaConvertor.convert(dereferencedSchema, name);
166
+
167
+ this.logger.verbose(
168
+ `converted schemas: ${JSON.stringify(convertedSchemas)}`
169
+ );
170
+
171
+ return convertedSchemas;
172
+ }
173
+
150
174
  async __dereferenceSchema(schema) {
151
175
  const bundledSchema = await $RefParser
152
176
  .bundle(schema, this.refParserOptions)
@@ -228,9 +252,23 @@ class SchemaHandler {
228
252
  }
229
253
  }
230
254
 
255
+ __checkForMissingPathAndThrow(error) {
256
+ if (error.message === "Expected a file path, URL, or object. Got undefined")
257
+ throw error;
258
+ }
259
+
260
+ __checkForHTTPErrorsAndThrow(error, model) {
261
+ if (error.errors) {
262
+ for (const err of error?.errors) {
263
+ this.__HTTPError(err, model);
264
+ }
265
+ } else {
266
+ this.__HTTPError(error, model);
267
+ }
268
+ }
269
+
231
270
  __HTTPError(error, model) {
232
271
  if (error.message.includes("HTTP ERROR")) {
233
- // throw err;
234
272
  throw new Error(
235
273
  `There was an error dereferencing ${
236
274
  model.name
@@ -23,7 +23,7 @@ describe("DefinitionGenerator", () => {
23
23
  );
24
24
 
25
25
  beforeEach(function () {
26
- mockServerless = JSON.parse(JSON.stringify(serverlessMock));
26
+ mockServerless = structuredClone(serverlessMock);
27
27
  Object.assign(mockServerless.service.custom.documentation, modelsDocument);
28
28
  });
29
29
 
@@ -39,9 +39,7 @@ describe("DefinitionGenerator", () => {
39
39
  });
40
40
 
41
41
  it("should default to version 3.0.0 of openAPI when openAPI version is not passed in", function () {
42
- const serverlessWithoutOpenAPIVersion = JSON.parse(
43
- JSON.stringify(mockServerless)
44
- );
42
+ const serverlessWithoutOpenAPIVersion = structuredClone(mockServerless);
45
43
  delete serverlessWithoutOpenAPIVersion.processedInput;
46
44
  let expected = new DefinitionGenerator(
47
45
  serverlessWithoutOpenAPIVersion,
@@ -108,9 +106,7 @@ describe("DefinitionGenerator", () => {
108
106
  });
109
107
 
110
108
  it("should respect the version of openAPI when passed in", function () {
111
- const serverlessWithOpenAPIVersion = JSON.parse(
112
- JSON.stringify(mockServerless)
113
- );
109
+ const serverlessWithOpenAPIVersion = structuredClone(mockServerless);
114
110
  serverlessWithOpenAPIVersion.processedInput.options.openApiVersion =
115
111
  "3.0.2";
116
112
  let expected = new DefinitionGenerator(
@@ -57,6 +57,7 @@ describe("OpenAPIGenerator", () => {
57
57
  notice: (str) => {},
58
58
  error: (str) => {},
59
59
  success: (str) => {},
60
+ verbose: (str) => {},
60
61
  },
61
62
  };
62
63
  });
@@ -106,9 +107,7 @@ describe("OpenAPIGenerator", () => {
106
107
  const getAllFuncsStub = sinon
107
108
  .stub(sls.service, "getAllFunctions")
108
109
  .returns(["createUser"]);
109
- const basicInvalidFunction = JSON.parse(
110
- JSON.stringify(basicValidFunction)
111
- );
110
+ const basicInvalidFunction = structuredClone(basicValidFunction);
112
111
 
113
112
  delete basicInvalidFunction.createUser.events[0].http.documentation
114
113
  .methodResponses[0].responseModels;
@@ -144,9 +143,7 @@ describe("OpenAPIGenerator", () => {
144
143
  const getAllFuncsStub = sinon
145
144
  .stub(sls.service, "getAllFunctions")
146
145
  .returns(["createUser"]);
147
- const basicInvalidFunction = JSON.parse(
148
- JSON.stringify(basicValidFunction)
149
- );
146
+ const basicInvalidFunction = structuredClone(basicValidFunction);
150
147
 
151
148
  const getFuncStub = sinon
152
149
  .stub(sls.service, "getFunction")
@@ -181,9 +178,7 @@ describe("OpenAPIGenerator", () => {
181
178
  .stub(sls.service, "getAllFunctions")
182
179
  .returns(["createUser"]);
183
180
 
184
- const basicInvalidFunction = JSON.parse(
185
- JSON.stringify(basicValidFunction)
186
- );
181
+ const basicInvalidFunction = structuredClone(basicValidFunction);
187
182
 
188
183
  delete basicInvalidFunction.createUser.events[0].http.documentation
189
184
  .pathParams;
@@ -56,7 +56,7 @@ describe(`owasp`, function () {
56
56
  });
57
57
 
58
58
  it(`adds any properties contained in a new release`, async function () {
59
- const newOWASPJSONAdded = JSON.parse(JSON.stringify(newOWASPJSON));
59
+ const newOWASPJSONAdded = structuredClone(newOWASPJSON);
60
60
  newOWASPJSONAdded.headers.push({ name: "x-added", value: "true" });
61
61
 
62
62
  nock("https://owasp.org")