serverless-openapi-documenter 0.0.117-beta.1 → 0.0.118

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,9 +12,7 @@
12
12
  </a>
13
13
  </p>
14
14
 
15
- This will generate an [OpenAPI V3](https://spec.openapis.org/oas/v3.0.0.html) (up to v3.0.4) specification file for you from your serverless file. It can optionally generate a [Postman Collection V2](https://github.com/postmanlabs/openapi-to-postman) from the OpenAPI file for you too. This currently works for `http` and `httpApi` configurations.
16
-
17
- If you are using the beta of 0.0.115, it will now try and create [OpenAPI V3.1 (3.1.x)](https://spec.openapis.org/oas/v3.1.0.html) specification file for you, should you run the command `serverless openapi generate -o openapi.json -f json -a 3.1.1 -p postman.json`. Please see this [guide on migrating to V3.1](https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0). Whilst I perosnally use this plugin all the time, please do open and report bugs, and I will do my best to fix them.
15
+ This will generate an OpenAPI V3 (up to v3.0.4) file for you from your serverless file. It can optionally generate a [Postman Collection V2](https://github.com/postmanlabs/openapi-to-postman) from the OpenAPI file for you too. This currently works for `http` and `httpApi` configurations.
18
16
 
19
17
  Originally based off of: https://github.com/temando/serverless-openapi-documentation
20
18
 
@@ -932,7 +930,7 @@ The generator will interpret your settings for CORS and automatically add the re
932
930
 
933
931
  You can make use of the [OWASP Secure Headers](https://owasp.org/www-project-secure-headers/#x-permitted-cross-domain-policies) to generate response headers. These are a selection of response headers with default values that OWASP recommends returning with your response to help secure your application.
934
932
 
935
- The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations. If you do not allow outside connections, it will default to a version of recommendations from **2024-09-19 21:29:28 UTC**.
933
+ The OWASP Secure Headers Project contains a set of recommended headers to return with recommended values, when generating the documentation, the generator will attempt to get the latest version of this document and apply the latest recommendations. If you do not allow outside connections, it will default to a version of recommendations from **2025-08-17 15:23:47 UTC**.
936
934
 
937
935
  Like CORS, if you have already set any of the OWASP Secure headers via `responseHeaders`, it will not overwrite them.
938
936
 
@@ -982,6 +980,7 @@ The full list of OWASP Secure Headers you can set are:
982
980
  - xContentTypeOptions - X-Content-Type-Options,
983
981
  - xFrameOptions - X-Frame-Options,
984
982
  - xPermittedCrossDomainPolicies - X-Permitted-Cross-Domain-Policies
983
+ - xDNSPrefetchControl - X-DNS-Prefetch-Control
985
984
 
986
985
  You should note that `Pragma` has been [deprecated by owasp](https://owasp.org/www-project-secure-headers/#pragma), this plugin will issue a warning when you are still using Pragma and might drop support.
987
986
 
package/json/owasp.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "last_update_utc": "2024-09-19 21:29:28",
2
+ "last_update_utc": "2025-08-17 15:23:47",
3
3
  "headers": [
4
4
  {
5
5
  "name": "Cache-Control",
@@ -11,7 +11,7 @@
11
11
  },
12
12
  {
13
13
  "name": "Content-Security-Policy",
14
- "value": "default-src 'self'; form-action 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests; block-all-mixed-content"
14
+ "value": "default-src 'self'; form-action 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests"
15
15
  },
16
16
  {
17
17
  "name": "Cross-Origin-Embedder-Policy",
@@ -41,6 +41,10 @@
41
41
  "name": "X-Content-Type-Options",
42
42
  "value": "nosniff"
43
43
  },
44
+ {
45
+ "name": "X-DNS-Prefetch-Control",
46
+ "value": "off"
47
+ },
44
48
  {
45
49
  "name": "X-Frame-Options",
46
50
  "value": "deny"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-openapi-documenter",
3
- "version": "0.0.117-beta.1",
3
+ "version": "0.0.118",
4
4
  "description": "Generate OpenAPI v3 documentation and Postman Collections from your Serverless Config",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -46,11 +46,11 @@
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
48
  "@apidevtools/json-schema-ref-parser": "^9.1.0",
49
- "@redocly/openapi-core": "^1.34.5",
49
+ "@redocly/openapi-core": "^1.2.0",
50
50
  "chalk": "^4.1.2",
51
- "js-yaml": "^4.1.0",
51
+ "js-yaml": "^4.1.1",
52
52
  "json-schema-for-openapi": "^0.5.0",
53
- "openapi-to-postmanv2": "^5.3.0",
53
+ "openapi-to-postmanv2": "^5.4.1",
54
54
  "uuid": "^11.1.0"
55
55
  },
56
56
  "engines": {
package/src/owasp.js CHANGED
@@ -67,6 +67,10 @@ class OWASP {
67
67
  description:
68
68
  "A cross-domain policy file is an XML document that grants a web client, such as Adobe Flash Player or Adobe Acrobat (though not necessarily limited to these), permission to handle data across domains. When clients request content hosted on a particular source domain and that content makes requests directed towards a domain other than its own, the remote domain needs to host a cross-domain policy file that grants access to the source domain, allowing the client to continue the transaction. Normally a meta-policy is declared in the master policy file, but for those who can't write to the root directory, they can also declare a meta-policy using the X-Permitted-Cross-Domain-Policies HTTP response header. - [OWASP Link](https://owasp.org/www-project-secure-headers/#x-permitted-cross-domain-policies)",
69
69
  },
70
+ "X-DNS-Prefetch-Control": {
71
+ description:
72
+ "The HTTP X-DNS-Prefetch-Control response header controls DNS prefetching, a feature by which browsers proactively perform domain name resolution on links that the user may choose to follow as well as URLs for items referenced by the document, including images, CSS, JavaScript, and so forth. - [MDN Link](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-DNS-Prefetch-Control)",
73
+ },
70
74
  };
71
75
 
72
76
  this.headerMap = {
@@ -83,6 +87,7 @@ class OWASP {
83
87
  xContentTypeOptions: "X-Content-Type-Options",
84
88
  xFrameOptions: "X-Frame-Options",
85
89
  xPermittedCrossDomainPolicies: "X-Permitted-Cross-Domain-Policies",
90
+ xDNSPrefetchControl: "X-DNS-Prefetch-Control",
86
91
  };
87
92
  }
88
93
 
@@ -16,9 +16,6 @@ class SchemaHandler {
16
16
  this.documentation = serverless.service.custom.documentation;
17
17
  this.openAPI = openAPI;
18
18
 
19
- this.shouldConvert = true;
20
- if (/(3\.1\.\d)/g.test(this.openAPI.openapi)) this.shouldConvert = false;
21
-
22
19
  this.modelReferences = {};
23
20
 
24
21
  this.__standardiseModels();
@@ -160,30 +157,18 @@ class SchemaHandler {
160
157
  }
161
158
  );
162
159
 
163
- if (this.shouldConvert) {
164
- this.logger.verbose(
165
- `dereferenced model: ${JSON.stringify(dereferencedSchema)}`
166
- );
167
-
168
- this.logger.verbose(`converting model: ${name}`);
169
- const convertedSchemas = SchemaConvertor.convert(
170
- dereferencedSchema,
171
- name
172
- );
160
+ this.logger.verbose(
161
+ `dereferenced model: ${JSON.stringify(dereferencedSchema)}`
162
+ );
173
163
 
174
- this.logger.verbose(
175
- `converted schemas: ${JSON.stringify(convertedSchemas)}`
176
- );
177
- return convertedSchemas;
178
- }
164
+ this.logger.verbose(`converting model: ${name}`);
165
+ const convertedSchemas = SchemaConvertor.convert(dereferencedSchema, name);
179
166
 
180
167
  this.logger.verbose(
181
- `dereferenced model: ${JSON.stringify({
182
- schemas: { [name]: dereferencedSchema },
183
- })}`
168
+ `converted schemas: ${JSON.stringify(convertedSchemas)}`
184
169
  );
185
170
 
186
- return { schemas: { [name]: dereferencedSchema } };
171
+ return convertedSchemas;
187
172
  }
188
173
 
189
174
  async __dereferenceSchema(schema) {
@@ -38,7 +38,7 @@ describe("DefinitionGenerator", () => {
38
38
  expect(expected).to.be.an.instanceOf(DefinitionGenerator);
39
39
  });
40
40
 
41
- it("should default to version 3.0.0 of OpenAPI when OpenAPI version is not passed in", function () {
41
+ it("should default to version 3.0.0 of openAPI when openAPI version is not passed in", function () {
42
42
  const serverlessWithoutOpenAPIVersion = structuredClone(mockServerless);
43
43
  delete serverlessWithoutOpenAPIVersion.processedInput;
44
44
  let expected = new DefinitionGenerator(
@@ -105,7 +105,7 @@ describe("DefinitionGenerator", () => {
105
105
  expect(expected.version).to.be.equal("3.0.0");
106
106
  });
107
107
 
108
- it("should respect the version of OpenAPI when passed in", function () {
108
+ it("should respect the version of openAPI when passed in", function () {
109
109
  const serverlessWithOpenAPIVersion = structuredClone(mockServerless);
110
110
  serverlessWithOpenAPIVersion.processedInput.options.openApiVersion =
111
111
  "3.0.2";
@@ -157,7 +157,7 @@ describe("DefinitionGenerator", () => {
157
157
  });
158
158
 
159
159
  describe("createInfo", () => {
160
- it("should create OpenAPI info object correctly", function () {
160
+ it("should create openAPI info object correctly", function () {
161
161
  const definitionGenerator = new DefinitionGenerator(
162
162
  mockServerless,
163
163
  logger
@@ -918,15 +918,14 @@ describe("DefinitionGenerator", () => {
918
918
  definitionGenerator.openAPI.components.securitySchemes
919
919
  ).to.have.property("x_amazon_api_key");
920
920
  expect(
921
- definitionGenerator.openAPI.components.securitySchemes
922
- .x_amazon_api_key
921
+ definitionGenerator.openAPI.components.securitySchemes.x_amazon_api_key
923
922
  ).to.have.property("x-amazon-apigateway-authtype");
924
923
  });
925
924
  });
926
925
  });
927
926
 
928
927
  describe("createTags", () => {
929
- it("should add tags to the OpenAPI object correctly", function () {
928
+ it("should add tags to the openAPI object correctly", function () {
930
929
  mockServerless.service.custom.documentation.tags = [{ name: "tag1" }];
931
930
 
932
931
  const definitionGenerator = new DefinitionGenerator(
@@ -68,7 +68,7 @@ describe("OpenAPIGenerator", () => {
68
68
  });
69
69
 
70
70
  describe("generationAndValidation", () => {
71
- it("should correctly generate a valid OpenAPI document", async function () {
71
+ it("should correctly generate a valid openAPI document", async function () {
72
72
  const succSpy = sinon.spy(logOutput.log, "success");
73
73
  const errSpy = sinon.spy(logOutput.log, "error");
74
74
 
@@ -99,7 +99,7 @@ describe("OpenAPIGenerator", () => {
99
99
  getFuncStub.reset();
100
100
  });
101
101
 
102
- xit("should throw an error when trying to generate an invalid OpenAPI document", async function () {
102
+ xit("should throw an error when trying to generate an invalid openAPI document", async function () {
103
103
  const succSpy = sinon.spy(logOutput.log, "success");
104
104
  const errSpy = sinon.spy(logOutput.log, "error");
105
105
 
@@ -135,7 +135,7 @@ describe("OpenAPIGenerator", () => {
135
135
  getFuncStub.reset();
136
136
  });
137
137
 
138
- it("should correctly validate a valid OpenAPI document", async function () {
138
+ it("should correctly validate a valid openAPI document", async function () {
139
139
  const succSpy = sinon.spy(logOutput.log, "success");
140
140
  const errSpy = sinon.spy(logOutput.log, "error");
141
141
 
@@ -168,7 +168,7 @@ describe("OpenAPIGenerator", () => {
168
168
  getFuncStub.reset();
169
169
  });
170
170
 
171
- it("should throw an error when trying to validate an invalid OpenAPI document", async function () {
171
+ it("should throw an error when trying to validate an invalid openAPI document", async function () {
172
172
  const succSpy = sinon.spy(logOutput.log, "success");
173
173
  const errSpy = sinon.spy(logOutput.log, "error");
174
174
 
@@ -212,7 +212,7 @@ describe("OpenAPIGenerator", () => {
212
212
  });
213
213
 
214
214
  describe("createPostman", () => {
215
- it("should generate a postman collection when a valid OpenAPI file is generated", function () {
215
+ it("should generate a postman collection when a valid openAPI file is generated", function () {
216
216
  const fsStub = sinon.stub(fs, "writeFileSync").returns(true);
217
217
  const succSpy = sinon.spy(logOutput.log, "success");
218
218
  const errSpy = sinon.spy(logOutput.log, "error");
@@ -4,9 +4,7 @@ const fs = require("fs").promises;
4
4
  const path = require("path");
5
5
 
6
6
  const expect = require("chai").expect;
7
- const SchemaConvertor = require("json-schema-for-openapi");
8
7
  const nock = require("nock");
9
- const sinon = require("sinon");
10
8
 
11
9
  const modelsDocumentOG = require("../models/models/models.json");
12
10
  const modelsAltDocumentOG = require("../models/models/models-alt.json");
@@ -38,7 +36,7 @@ describe(`SchemaHandler`, function () {
38
36
  );
39
37
 
40
38
  const openAPISchema = {
41
- openapi: "3.0.3",
39
+ version: "3.0.3",
42
40
  components: {
43
41
  schemas: {},
44
42
  },
@@ -279,7 +277,7 @@ describe(`SchemaHandler`, function () {
279
277
 
280
278
  describe(`addModelsToOpenAPI`, function () {
281
279
  describe(`embedded simple schemas`, function () {
282
- it(`should add the model to the OpenAPI schema`, async function () {
280
+ it(`should add the model to the openAPI schema`, async function () {
283
281
  Object.assign(
284
282
  mockServerless.service.custom.documentation,
285
283
  modelsDocument
@@ -308,7 +306,7 @@ describe(`SchemaHandler`, function () {
308
306
  });
309
307
  });
310
308
 
311
- it(`should add a model with references to the OpenAPI schema`, async function () {
309
+ it(`should add a model with references to the openAPI schema`, async function () {
312
310
  Object.assign(
313
311
  mockServerless.service.custom.documentation,
314
312
  modelsDocument
@@ -381,7 +379,7 @@ describe(`SchemaHandler`, function () {
381
379
  });
382
380
  });
383
381
 
384
- it(`should add a model with poorly dereferenced references to the OpenAPI schema`, async function () {
382
+ it(`should add a model with poorly dereferenced references to the openAPI schema`, async function () {
385
383
  Object.assign(
386
384
  mockServerless.service.custom.documentation,
387
385
  modelsDocument
@@ -448,7 +446,7 @@ describe(`SchemaHandler`, function () {
448
446
  });
449
447
 
450
448
  describe(`component references`, function () {
451
- it(`should add schemas with component references to the OpenAPI schema`, async function () {
449
+ it(`should add schemas with component references to the openAPI schema`, async function () {
452
450
  Object.assign(
453
451
  mockServerless.service.custom.documentation,
454
452
  modelsDocument
@@ -519,86 +517,10 @@ describe(`SchemaHandler`, function () {
519
517
  type: "string",
520
518
  });
521
519
  });
522
-
523
- it(`should add schemas with component references to the OpenAPI schema using OpenAPI 3.1`, async function () {
524
- Object.assign(
525
- mockServerless.service.custom.documentation,
526
- modelsDocument
527
- );
528
-
529
- mockServerless.service.custom.documentation.models.push({
530
- name: "SuccessResponse",
531
- contentType: "application/json",
532
- schema: {
533
- type: "array",
534
- items: {
535
- $ref: "#/components/schemas/Agency",
536
- },
537
- },
538
- });
539
-
540
- mockServerless.service.custom.documentation.models.push({
541
- name: "Agency",
542
- contentType: "application/json",
543
- schema: {
544
- type: "string",
545
- },
546
- });
547
-
548
- openAPI.openapi = "3.1.0";
549
-
550
- const schemaHandler = new SchemaHandler(
551
- mockServerless,
552
- openAPI,
553
- logger
554
- );
555
-
556
- await schemaHandler.addModelsToOpenAPI();
557
-
558
- expect(schemaHandler.openAPI).to.have.property("components");
559
- expect(schemaHandler.openAPI.components).to.have.property("schemas");
560
- expect(schemaHandler.openAPI.components.schemas).to.have.property(
561
- "ErrorResponse"
562
- );
563
- expect(
564
- schemaHandler.openAPI.components.schemas.ErrorResponse
565
- ).to.be.an("object");
566
- expect(
567
- schemaHandler.openAPI.components.schemas.ErrorResponse
568
- ).to.be.eql({
569
- type: "object",
570
- properties: { error: { type: "string" } },
571
- });
572
-
573
- expect(schemaHandler.openAPI.components.schemas).to.have.property(
574
- "SuccessResponse"
575
- );
576
- expect(
577
- schemaHandler.openAPI.components.schemas.SuccessResponse
578
- ).to.be.an("object");
579
- expect(
580
- schemaHandler.openAPI.components.schemas.SuccessResponse
581
- ).to.be.eql({
582
- type: "array",
583
- items: {
584
- $ref: "#/components/schemas/Agency",
585
- },
586
- });
587
-
588
- expect(schemaHandler.openAPI.components.schemas).to.have.property(
589
- "Agency"
590
- );
591
- expect(schemaHandler.openAPI.components.schemas.Agency).to.be.an(
592
- "object"
593
- );
594
- expect(schemaHandler.openAPI.components.schemas.Agency).to.be.eql({
595
- type: "string",
596
- });
597
- });
598
520
  });
599
521
 
600
522
  describe(`other references`, function () {
601
- it(`should add a model that is a webUrl to the OpenAPI schema`, async function () {
523
+ it(`should add a model that is a webUrl to the openAPI schema`, async function () {
602
524
  Object.assign(
603
525
  mockServerless.service.custom.documentation,
604
526
  modelsDocument
@@ -667,7 +589,7 @@ describe(`SchemaHandler`, function () {
667
589
  });
668
590
  });
669
591
 
670
- it(`should add a complex model that is a webUrl to the OpenAPI schema`, async function () {
592
+ it(`should add a complex model that is a webUrl to the openAPI schema`, async function () {
671
593
  Object.assign(
672
594
  mockServerless.service.custom.documentation,
673
595
  modelsDocument
@@ -788,28 +710,6 @@ describe(`SchemaHandler`, function () {
788
710
  });
789
711
 
790
712
  describe(`createSchema`, function () {
791
- it(`does not convert schemas when using OpenAPI 3.1.x`, async function () {
792
- Object.assign(
793
- mockServerless.service.custom.documentation,
794
- modelsDocument
795
- );
796
-
797
- openAPI.openapi = "3.1.0";
798
-
799
- const schemaHandler = new SchemaHandler(mockServerless, openAPI, logger);
800
-
801
- const spy = sinon.spy(SchemaConvertor, "convert");
802
-
803
- await schemaHandler.addModelsToOpenAPI();
804
-
805
- const expected = await schemaHandler.createSchema("ErrorResponse");
806
-
807
- expect(expected).to.be.equal("#/components/schemas/ErrorResponse");
808
- expect(spy.calledOnce).to.be.false;
809
-
810
- spy.restore();
811
- });
812
-
813
713
  it(`returns a reference to the schema when the schema already exists in components and we don't pass through a schema`, async function () {
814
714
  Object.assign(
815
715
  mockServerless.service.custom.documentation,