apib2swagger 1.15.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.github/workflows/nodejs.yml +1 -1
  2. package/.travis.yml +1 -1
  3. package/Dockerfile +1 -1
  4. package/README.md +1 -1
  5. package/package.json +1 -1
  6. package/src/mson_to_json_schema.js +1 -0
  7. package/src/requests.js +18 -3
  8. package/src/responses.js +7 -1
  9. package/test/input/Issue-#35.md +6 -0
  10. package/test/input/Issue-#72.md +43 -0
  11. package/test/output/01. Simplest API.json +2 -1
  12. package/test/output/01. Simplest API.ref.json +2 -1
  13. package/test/output/02. Resource and Actions.json +6 -2
  14. package/test/output/02. Resource and Actions.ref.json +6 -2
  15. package/test/output/03. Named Resource and Actions.json +6 -2
  16. package/test/output/03. Named Resource and Actions.ref.json +6 -2
  17. package/test/output/04. Grouping Resources.json +6 -2
  18. package/test/output/04. Grouping Resources.ref.json +6 -2
  19. package/test/output/05. Responses.json +17 -2
  20. package/test/output/05. Responses.ref.json +17 -2
  21. package/test/output/06. Requests.json +17 -1
  22. package/test/output/06. Requests.ref.json +17 -1
  23. package/test/output/07. Parameters.json +55 -2
  24. package/test/output/07. Parameters.ref.json +55 -2
  25. package/test/output/08. Attributes.json +2 -1
  26. package/test/output/08. Attributes.ref.json +2 -1
  27. package/test/output/09. Advanced Attributes.json +7 -2
  28. package/test/output/09. Advanced Attributes.ref.json +7 -2
  29. package/test/output/10. Data Structures.json +7 -2
  30. package/test/output/10. Data Structures.ref.json +7 -2
  31. package/test/output/11. Resource Model.json +6 -1
  32. package/test/output/11. Resource Model.ref.json +6 -1
  33. package/test/output/12. Advanced Action.json +69 -3
  34. package/test/output/12. Advanced Action.ref.json +69 -3
  35. package/test/output/13. Named Endpoints.json +6 -0
  36. package/test/output/13. Named Endpoints.ref.json +6 -0
  37. package/test/output/Attributes.json +3 -0
  38. package/test/output/Attributes.ref.json +3 -0
  39. package/test/output/Gist Fox API + Auth.json +76 -7
  40. package/test/output/Gist Fox API + Auth.ref.json +76 -7
  41. package/test/output/Issue-#15.json +6 -3
  42. package/test/output/Issue-#15.ref.json +6 -3
  43. package/test/output/Issue-#23.json +3 -0
  44. package/test/output/Issue-#23.ref.json +3 -0
  45. package/test/output/Issue-#26.json +5 -1
  46. package/test/output/Issue-#26.ref.json +5 -1
  47. package/test/output/Issue-#29.json +5 -1
  48. package/test/output/Issue-#29.ref.json +5 -1
  49. package/test/output/Issue-#33.json +2 -1
  50. package/test/output/Issue-#33.ref.json +2 -1
  51. package/test/output/Issue-#35.json +9 -0
  52. package/test/output/Issue-#35.ref.json +9 -0
  53. package/test/output/Issue-#36.json +2 -1
  54. package/test/output/Issue-#36.ref.json +2 -1
  55. package/test/output/Issue-#38.bearer.json +3 -0
  56. package/test/output/Issue-#38.json +3 -0
  57. package/test/output/Issue-#38.ref.json +3 -0
  58. package/test/output/Issue-#49.json +4 -2
  59. package/test/output/Issue-#49.ref.json +4 -2
  60. package/test/output/Issue-#57.json +3 -0
  61. package/test/output/Issue-#57.ref.json +3 -0
  62. package/test/output/Issue-#72.json +170 -0
  63. package/test/output/Issue-#72.ref.json +168 -0
  64. package/test/output/OpenAPI3_responses.json +240 -232
  65. package/test/output/OpenAPI3_responses.ref.json +231 -223
  66. package/test/output/Schema.json +20 -0
  67. package/test/output/Schema.ref.json +20 -0
  68. package/test/output/apiblueprint_uber.json +10 -5
  69. package/test/output/apiblueprint_uber.ref.json +10 -5
  70. package/test/output/apiblueprint_valid_simple.json +76 -7
  71. package/test/output/apiblueprint_valid_simple.ref.json +76 -7
  72. package/test/output/schema_without_body.json +52 -49
  73. package/test/output/schema_without_body.ref.json +52 -49
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- node-version: [12.x, 14.x, 16.x]
12
+ node-version: [18.x, 20.x]
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v1
package/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  language: node_js
2
2
  node_js:
3
+ - "18"
3
4
  - "16"
4
5
  - "14"
5
- - "12"
6
6
  after_success: npm run coverage
package/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM node:16-alpine
1
+ FROM node:18-alpine
2
2
 
3
3
  RUN npm install -g apib2swagger
4
4
 
package/README.md CHANGED
@@ -14,7 +14,7 @@ Supported versions:
14
14
  - [Include directive](https://github.com/danielgtaylor/aglio#including-files)
15
15
  - Swagger 2.0
16
16
  - OpenAPI 3.0.3
17
- - Node.js 12.x, 14.x, 16.x or higher
17
+ - Node.js 18.x, 20.x or higher
18
18
 
19
19
  ## Install
20
20
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apib2swagger",
3
- "version": "1.15.0",
3
+ "version": "1.17.0",
4
4
  "description": "Convert API Blueprint to Swagger.",
5
5
  "bin": "./bin/apib2swagger.js",
6
6
  "scripts": {
@@ -99,6 +99,7 @@ function convert(mson, options) {
99
99
  }
100
100
 
101
101
  function convertEnum(contents) {
102
+ if (!contents) return null
102
103
  var schema = { type: '', enum: [] };
103
104
  for (var i = 0; i < contents.length; i++) {
104
105
  var content = contents[i];
package/src/requests.js CHANGED
@@ -308,6 +308,8 @@ module.exports.processRequests = (operation, action, context) => {
308
308
 
309
309
  let bodyExamples = {}
310
310
 
311
+ if (!openApi3) operation.consumes = []
312
+
311
313
  for (var j = 0; j < action.examples.length; j++) {
312
314
  var example = action.examples[j];
313
315
  for (var l = 0; l < example.requests.length; l++) {
@@ -320,8 +322,14 @@ module.exports.processRequests = (operation, action, context) => {
320
322
  operation.parameters = mergeHeaders(headers, operation.parameters, options)
321
323
  }
322
324
 
325
+ var contentType = 'application/json'
323
326
  const contentTypeHeader = request.headers.find((h) => h.name === 'Content-Type')
324
- const contentType = contentTypeHeader ? contentTypeHeader.value : 'application/json'
327
+ if (contentTypeHeader) {
328
+ contentType = contentTypeHeader.value
329
+ if (!openApi3 && !operation.consumes.includes(contentType)) {
330
+ operation.consumes.push(contentType)
331
+ }
332
+ }
325
333
 
326
334
  if (request.body && openApi3) {
327
335
  bodyExamples = buildBodyExamples(request.body, bodyExamples, contentType)
@@ -346,12 +354,19 @@ module.exports.processRequests = (operation, action, context) => {
346
354
  }
347
355
  }
348
356
  }
349
- if (openApi3 && (schema.length || Object.keys(bodyExamples).length)){
357
+ if (openApi3 && (schema.length || Object.keys(bodyExamples).length)) {
350
358
  operation.requestBody = { content: {} }
351
359
  if (Object.keys(bodyExamples).length) {
352
360
  operation.requestBody.content = bodyExamples
353
361
  }
354
362
  }
355
-
363
+ if (!openApi3) {
364
+ for (var s of schema) {
365
+ if (!operation.consumes.includes(s.contentType)) {
366
+ operation.consumes.push(s.contentType)
367
+ }
368
+ }
369
+ }
370
+
356
371
  return openApi3 ? setOpenApiRequestSchema(operation, schema) : setSwaggerRequestSchema(operation, schema)
357
372
  }
package/src/responses.js CHANGED
@@ -1,4 +1,4 @@
1
- const { fixArraySchema, hasFileRef, getRefFromInclude, searchDataStructure } = require('./util')
1
+ const { fixArraySchema, hasFileRef, getRefFromInclude, searchDataStructure, generateSchemaFromExample } = require('./util')
2
2
  const escapeJSONPointer = require('./escape_json_pointer')
3
3
  const isEqual = require('lodash.isequal')
4
4
  const http = require('http')
@@ -58,6 +58,12 @@ const getResponseSchema = (response, options) => {
58
58
  };
59
59
  }
60
60
  }
61
+ for (let content of response.content) {
62
+ const schema = generateSchemaFromExample(response.headers, content.content, options)
63
+ if (schema) {
64
+ return schema
65
+ }
66
+ }
61
67
  }
62
68
 
63
69
  const setResponseSchema = (responses, response, schema, options) => {
@@ -6,3 +6,9 @@ FORMAT: 1A
6
6
  ## Config
7
7
  + alice (string, required) - information about alice
8
8
  + bob (string, required) - information about bob
9
+
10
+ ## Filter
11
+ + status (array[enum])
12
+ + Members
13
+ + option1
14
+ + option2
@@ -0,0 +1,43 @@
1
+ ### Create a user [POST /api/scim/v2/Users]
2
+
3
+ + Request
4
+ + Headers
5
+
6
+ Content-Type: application/scim+json
7
+ Authorization: Bearer token
8
+
9
+ + Body
10
+
11
+ {
12
+ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
13
+ "userName": "fredsmith",
14
+ "name": {
15
+ "givenName": "Fred",
16
+ "familyName": "Smith"
17
+ },
18
+ "emails": [
19
+ {"primary": true, "value": "fred@example.com", "type": "work"}
20
+ ],
21
+ "displayName": "Fred Smith",
22
+ "externalId": "fred-external-id",
23
+ "active": true
24
+ }
25
+
26
+ + Response 201 (application/scim+json)
27
+
28
+ + Attributes (ExistingUser)
29
+
30
+ ### Create a user 2 [POST /api2/scim/v2/Users]
31
+
32
+ + Request
33
+ + Headers
34
+
35
+ Content-Type: application/scim+json
36
+ Authorization: Bearer token
37
+
38
+ + Response 201 (application/scim+json)
39
+
40
+ + Attributes (ExistingUser)
41
+
42
+ # Data Structures
43
+ ## ExistingUser
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  }
29
30
  }
30
31
  },
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  }
29
30
  }
30
31
  },
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  },
29
30
  "put": {
30
31
  "responses": {
@@ -38,7 +39,10 @@
38
39
  "operationId": "",
39
40
  "description": "OK, let's add another action. This time to put new data to our resource (essentially an update action). We will need to send something in a [request](http://www.w3.org/TR/di-gloss/#def-http-request) and then send a response back confirming the posting was a success (HTTP Status Code 204 ~ Resource updated successfully, no content is returned).",
40
41
  "tags": [],
41
- "parameters": []
42
+ "parameters": [],
43
+ "consumes": [
44
+ "text/plain"
45
+ ]
42
46
  }
43
47
  }
44
48
  },
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  },
29
30
  "put": {
30
31
  "responses": {
@@ -38,7 +39,10 @@
38
39
  "operationId": "",
39
40
  "description": "OK, let's add another action. This time to put new data to our resource (essentially an update action). We will need to send something in a [request](http://www.w3.org/TR/di-gloss/#def-http-request) and then send a response back confirming the posting was a success (HTTP Status Code 204 ~ Resource updated successfully, no content is returned).",
40
41
  "tags": [],
41
- "parameters": []
42
+ "parameters": [],
43
+ "consumes": [
44
+ "text/plain"
45
+ ]
42
46
  }
43
47
  }
44
48
  },
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  },
29
30
  "put": {
30
31
  "responses": {
@@ -38,7 +39,10 @@
38
39
  "operationId": "Update a Message",
39
40
  "description": "`Update a message` - nice and simple naming is the best way to go.",
40
41
  "tags": [],
41
- "parameters": []
42
+ "parameters": [],
43
+ "consumes": [
44
+ "text/plain"
45
+ ]
42
46
  }
43
47
  }
44
48
  },
@@ -24,7 +24,8 @@
24
24
  "parameters": [],
25
25
  "produces": [
26
26
  "text/plain"
27
- ]
27
+ ],
28
+ "consumes": []
28
29
  },
29
30
  "put": {
30
31
  "responses": {
@@ -38,7 +39,10 @@
38
39
  "operationId": "Update a Message",
39
40
  "description": "`Update a message` - nice and simple naming is the best way to go.",
40
41
  "tags": [],
41
- "parameters": []
42
+ "parameters": [],
43
+ "consumes": [
44
+ "text/plain"
45
+ ]
42
46
  }
43
47
  }
44
48
  },
@@ -26,7 +26,8 @@
26
26
  "parameters": [],
27
27
  "produces": [
28
28
  "text/plain"
29
- ]
29
+ ],
30
+ "consumes": []
30
31
  },
31
32
  "put": {
32
33
  "responses": {
@@ -42,7 +43,10 @@
42
43
  "tags": [
43
44
  "Messages"
44
45
  ],
45
- "parameters": []
46
+ "parameters": [],
47
+ "consumes": [
48
+ "text/plain"
49
+ ]
46
50
  }
47
51
  }
48
52
  },
@@ -26,7 +26,8 @@
26
26
  "parameters": [],
27
27
  "produces": [
28
28
  "text/plain"
29
- ]
29
+ ],
30
+ "consumes": []
30
31
  },
31
32
  "put": {
32
33
  "responses": {
@@ -42,7 +43,10 @@
42
43
  "tags": [
43
44
  "Messages"
44
45
  ],
45
- "parameters": []
46
+ "parameters": [],
47
+ "consumes": [
48
+ "text/plain"
49
+ ]
46
50
  }
47
51
  }
48
52
  },
@@ -20,6 +20,17 @@
20
20
  "application/json": {
21
21
  "message": "Hello World!"
22
22
  }
23
+ },
24
+ "schema": {
25
+ "type": "object",
26
+ "properties": {
27
+ "message": {
28
+ "type": "string"
29
+ }
30
+ },
31
+ "example": {
32
+ "message": "Hello World!"
33
+ }
23
34
  }
24
35
  }
25
36
  },
@@ -32,7 +43,8 @@
32
43
  "parameters": [],
33
44
  "produces": [
34
45
  "application/json"
35
- ]
46
+ ],
47
+ "consumes": []
36
48
  },
37
49
  "put": {
38
50
  "responses": {
@@ -48,7 +60,10 @@
48
60
  "tags": [
49
61
  "Messages"
50
62
  ],
51
- "parameters": []
63
+ "parameters": [],
64
+ "consumes": [
65
+ "text/plain"
66
+ ]
52
67
  }
53
68
  }
54
69
  },
@@ -20,6 +20,17 @@
20
20
  "application/json": {
21
21
  "message": "Hello World!"
22
22
  }
23
+ },
24
+ "schema": {
25
+ "type": "object",
26
+ "properties": {
27
+ "message": {
28
+ "type": "string"
29
+ }
30
+ },
31
+ "example": {
32
+ "message": "Hello World!"
33
+ }
23
34
  }
24
35
  }
25
36
  },
@@ -32,7 +43,8 @@
32
43
  "parameters": [],
33
44
  "produces": [
34
45
  "application/json"
35
- ]
46
+ ],
47
+ "consumes": []
36
48
  },
37
49
  "put": {
38
50
  "responses": {
@@ -48,7 +60,10 @@
48
60
  "tags": [
49
61
  "Messages"
50
62
  ],
51
- "parameters": []
63
+ "parameters": [],
64
+ "consumes": [
65
+ "text/plain"
66
+ ]
52
67
  }
53
68
  }
54
69
  },
@@ -20,6 +20,17 @@
20
20
  "application/json": {
21
21
  "message": "Hello World!"
22
22
  }
23
+ },
24
+ "schema": {
25
+ "type": "object",
26
+ "properties": {
27
+ "message": {
28
+ "type": "string"
29
+ }
30
+ },
31
+ "example": {
32
+ "message": "Hello World!"
33
+ }
23
34
  }
24
35
  }
25
36
  },
@@ -41,7 +52,8 @@
41
52
  ],
42
53
  "produces": [
43
54
  "application/json"
44
- ]
55
+ ],
56
+ "consumes": []
45
57
  },
46
58
  "put": {
47
59
  "responses": {
@@ -73,6 +85,10 @@
73
85
  }
74
86
  }
75
87
  }
88
+ ],
89
+ "consumes": [
90
+ "text/plain",
91
+ "application/json"
76
92
  ]
77
93
  }
78
94
  }
@@ -20,6 +20,17 @@
20
20
  "application/json": {
21
21
  "message": "Hello World!"
22
22
  }
23
+ },
24
+ "schema": {
25
+ "type": "object",
26
+ "properties": {
27
+ "message": {
28
+ "type": "string"
29
+ }
30
+ },
31
+ "example": {
32
+ "message": "Hello World!"
33
+ }
23
34
  }
24
35
  }
25
36
  },
@@ -41,7 +52,8 @@
41
52
  ],
42
53
  "produces": [
43
54
  "application/json"
44
- ]
55
+ ],
56
+ "consumes": []
45
57
  },
46
58
  "put": {
47
59
  "responses": {
@@ -73,6 +85,10 @@
73
85
  }
74
86
  }
75
87
  }
88
+ ],
89
+ "consumes": [
90
+ "text/plain",
91
+ "application/json"
76
92
  ]
77
93
  }
78
94
  }
@@ -21,6 +21,21 @@
21
21
  "id": 1,
22
22
  "message": "Hello World!"
23
23
  }
24
+ },
25
+ "schema": {
26
+ "type": "object",
27
+ "properties": {
28
+ "id": {
29
+ "type": "number"
30
+ },
31
+ "message": {
32
+ "type": "string"
33
+ }
34
+ },
35
+ "example": {
36
+ "id": 1,
37
+ "message": "Hello World!"
38
+ }
24
39
  }
25
40
  }
26
41
  },
@@ -50,7 +65,8 @@
50
65
  ],
51
66
  "produces": [
52
67
  "application/json"
53
- ]
68
+ ],
69
+ "consumes": []
54
70
  },
55
71
  "put": {
56
72
  "responses": {
@@ -90,6 +106,10 @@
90
106
  }
91
107
  }
92
108
  }
109
+ ],
110
+ "consumes": [
111
+ "text/plain",
112
+ "application/json"
93
113
  ]
94
114
  }
95
115
  },
@@ -114,6 +134,38 @@
114
134
  "message": "So long, and thanks for all the fish."
115
135
  }
116
136
  ]
137
+ },
138
+ "schema": {
139
+ "type": "array",
140
+ "items": {
141
+ "type": "object",
142
+ "properties": {
143
+ "id": {
144
+ "type": "number"
145
+ },
146
+ "message": {
147
+ "type": "string"
148
+ }
149
+ },
150
+ "required": [
151
+ "id",
152
+ "message"
153
+ ]
154
+ },
155
+ "example": [
156
+ {
157
+ "id": 1,
158
+ "message": "Hello World!"
159
+ },
160
+ {
161
+ "id": 2,
162
+ "message": "Time is an illusion. Lunchtime doubly so."
163
+ },
164
+ {
165
+ "id": 3,
166
+ "message": "So long, and thanks for all the fish."
167
+ }
168
+ ]
117
169
  }
118
170
  }
119
171
  },
@@ -135,7 +187,8 @@
135
187
  ],
136
188
  "produces": [
137
189
  "application/json"
138
- ]
190
+ ],
191
+ "consumes": []
139
192
  }
140
193
  }
141
194
  },
@@ -21,6 +21,21 @@
21
21
  "id": 1,
22
22
  "message": "Hello World!"
23
23
  }
24
+ },
25
+ "schema": {
26
+ "type": "object",
27
+ "properties": {
28
+ "id": {
29
+ "type": "number"
30
+ },
31
+ "message": {
32
+ "type": "string"
33
+ }
34
+ },
35
+ "example": {
36
+ "id": 1,
37
+ "message": "Hello World!"
38
+ }
24
39
  }
25
40
  }
26
41
  },
@@ -50,7 +65,8 @@
50
65
  ],
51
66
  "produces": [
52
67
  "application/json"
53
- ]
68
+ ],
69
+ "consumes": []
54
70
  },
55
71
  "put": {
56
72
  "responses": {
@@ -90,6 +106,10 @@
90
106
  }
91
107
  }
92
108
  }
109
+ ],
110
+ "consumes": [
111
+ "text/plain",
112
+ "application/json"
93
113
  ]
94
114
  }
95
115
  },
@@ -114,6 +134,38 @@
114
134
  "message": "So long, and thanks for all the fish."
115
135
  }
116
136
  ]
137
+ },
138
+ "schema": {
139
+ "type": "array",
140
+ "items": {
141
+ "type": "object",
142
+ "properties": {
143
+ "id": {
144
+ "type": "number"
145
+ },
146
+ "message": {
147
+ "type": "string"
148
+ }
149
+ },
150
+ "required": [
151
+ "id",
152
+ "message"
153
+ ]
154
+ },
155
+ "example": [
156
+ {
157
+ "id": 1,
158
+ "message": "Hello World!"
159
+ },
160
+ {
161
+ "id": 2,
162
+ "message": "Time is an illusion. Lunchtime doubly so."
163
+ },
164
+ {
165
+ "id": 3,
166
+ "message": "So long, and thanks for all the fish."
167
+ }
168
+ ]
117
169
  }
118
170
  }
119
171
  },
@@ -135,7 +187,8 @@
135
187
  ],
136
188
  "produces": [
137
189
  "application/json"
138
- ]
190
+ ],
191
+ "consumes": []
139
192
  }
140
193
  }
141
194
  },
@@ -41,7 +41,8 @@
41
41
  "tags": [
42
42
  "Coupons"
43
43
  ],
44
- "parameters": []
44
+ "parameters": [],
45
+ "consumes": []
45
46
  }
46
47
  }
47
48
  },