@scalar/oas-utils 0.1.17 → 0.2.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 (158) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/entities/index.d.ts +2 -0
  3. package/dist/entities/index.d.ts.map +1 -0
  4. package/dist/entities/index.js +1 -0
  5. package/dist/entities/workspace/collection/collection.d.ts +314 -0
  6. package/dist/entities/workspace/collection/collection.d.ts.map +1 -0
  7. package/dist/entities/workspace/collection/collection.js +112 -0
  8. package/dist/entities/workspace/collection/index.d.ts +2 -0
  9. package/dist/entities/workspace/collection/index.d.ts.map +1 -0
  10. package/dist/entities/workspace/collection/index.js +1 -0
  11. package/dist/entities/workspace/cookie/cookie.d.ts +84 -0
  12. package/dist/entities/workspace/cookie/cookie.d.ts.map +1 -0
  13. package/dist/entities/workspace/cookie/cookie.js +44 -0
  14. package/dist/entities/workspace/cookie/index.d.ts +2 -0
  15. package/dist/entities/workspace/cookie/index.d.ts.map +1 -0
  16. package/dist/entities/workspace/cookie/index.js +1 -0
  17. package/dist/entities/workspace/environment/environment.d.ts +55 -0
  18. package/dist/entities/workspace/environment/environment.d.ts.map +1 -0
  19. package/dist/entities/workspace/environment/environment.js +23 -0
  20. package/dist/entities/workspace/environment/index.d.ts +2 -0
  21. package/dist/entities/workspace/environment/index.d.ts.map +1 -0
  22. package/dist/entities/workspace/environment/index.js +1 -0
  23. package/dist/entities/workspace/folder/folder.d.ts +36 -0
  24. package/dist/entities/workspace/folder/folder.d.ts.map +1 -0
  25. package/dist/entities/workspace/folder/folder.js +21 -0
  26. package/dist/entities/workspace/folder/index.d.ts +2 -0
  27. package/dist/entities/workspace/folder/index.d.ts.map +1 -0
  28. package/dist/entities/workspace/folder/index.js +1 -0
  29. package/dist/entities/workspace/index.d.ts +2 -0
  30. package/dist/entities/workspace/index.d.ts.map +1 -0
  31. package/dist/entities/workspace/index.js +1 -0
  32. package/dist/entities/workspace/security-schemes/index.d.ts +2 -0
  33. package/dist/entities/workspace/security-schemes/index.d.ts.map +1 -0
  34. package/dist/entities/workspace/security-schemes/index.js +1 -0
  35. package/dist/entities/workspace/security-schemes/security-schemes.d.ts +19 -0
  36. package/dist/entities/workspace/security-schemes/security-schemes.d.ts.map +1 -0
  37. package/dist/entities/workspace/security-schemes/security-schemes.js +15 -0
  38. package/dist/entities/workspace/server/index.d.ts +2 -0
  39. package/dist/entities/workspace/server/index.d.ts.map +1 -0
  40. package/dist/entities/workspace/server/index.js +1 -0
  41. package/dist/entities/workspace/server/server.d.ts +84 -0
  42. package/dist/entities/workspace/server/server.d.ts.map +1 -0
  43. package/dist/entities/workspace/server/server.js +46 -0
  44. package/dist/entities/workspace/shared/index.d.ts +2 -0
  45. package/dist/entities/workspace/shared/index.d.ts.map +1 -0
  46. package/dist/entities/workspace/shared/index.js +1 -0
  47. package/dist/entities/workspace/shared/utility.d.ts +6 -0
  48. package/dist/entities/workspace/shared/utility.d.ts.map +1 -0
  49. package/dist/entities/workspace/shared/utility.js +11 -0
  50. package/dist/entities/workspace/spec/components.d.ts +3 -0
  51. package/dist/entities/workspace/spec/components.d.ts.map +1 -0
  52. package/dist/entities/workspace/spec/index.d.ts +5 -0
  53. package/dist/entities/workspace/spec/index.d.ts.map +1 -0
  54. package/dist/entities/workspace/spec/index.js +2 -0
  55. package/dist/entities/workspace/spec/parameters.d.ts +16 -0
  56. package/dist/entities/workspace/spec/parameters.d.ts.map +1 -0
  57. package/dist/entities/workspace/spec/refs.d.ts +30 -0
  58. package/dist/entities/workspace/spec/refs.d.ts.map +1 -0
  59. package/dist/entities/workspace/spec/refs.js +9 -0
  60. package/dist/entities/workspace/spec/request-examples.d.ts +479 -0
  61. package/dist/entities/workspace/spec/request-examples.d.ts.map +1 -0
  62. package/dist/entities/workspace/spec/request-examples.js +68 -0
  63. package/dist/entities/workspace/spec/requests.d.ts +149 -0
  64. package/dist/entities/workspace/spec/requests.d.ts.map +1 -0
  65. package/dist/entities/workspace/spec/requests.js +52 -0
  66. package/dist/entities/workspace/spec/spec.d.ts +18 -0
  67. package/dist/entities/workspace/spec/spec.d.ts.map +1 -0
  68. package/dist/entities/workspace/spec/spec.js +8 -0
  69. package/dist/entities/workspace/workspace.d.ts +45 -0
  70. package/dist/entities/workspace/workspace.d.ts.map +1 -0
  71. package/dist/entities/workspace/workspace.js +20 -0
  72. package/dist/helpers/createHash.d.ts.map +1 -0
  73. package/dist/helpers/createHash.js +20 -0
  74. package/dist/helpers/deepMerge.d.ts +7 -0
  75. package/dist/helpers/deepMerge.d.ts.map +1 -0
  76. package/dist/helpers/deepMerge.js +28 -0
  77. package/dist/helpers/fetchSpecFromUrl.d.ts.map +1 -0
  78. package/dist/helpers/fetchSpecFromUrl.js +31 -0
  79. package/dist/helpers/httpMethods.d.ts +93 -0
  80. package/dist/helpers/httpMethods.d.ts.map +1 -0
  81. package/dist/helpers/httpMethods.js +64 -0
  82. package/dist/helpers/httpStatusCodes.d.ts.map +1 -0
  83. package/dist/helpers/httpStatusCodes.js +252 -0
  84. package/dist/helpers/index.d.ts +14 -0
  85. package/dist/helpers/index.d.ts.map +1 -0
  86. package/dist/helpers/index.js +13 -0
  87. package/dist/helpers/iterateTitle.d.ts +5 -0
  88. package/dist/helpers/iterateTitle.d.ts.map +1 -0
  89. package/dist/helpers/iterateTitle.js +15 -0
  90. package/dist/helpers/json2xml.d.ts.map +1 -0
  91. package/dist/helpers/json2xml.js +51 -0
  92. package/dist/{normalizeMimeType.d.ts → helpers/normalizeMimeType.d.ts} +1 -1
  93. package/dist/helpers/normalizeMimeType.d.ts.map +1 -0
  94. package/dist/helpers/normalizeMimeType.js +20 -0
  95. package/dist/{normalizeMimeTypeObject.d.ts → helpers/normalizeMimeTypeObject.d.ts} +1 -1
  96. package/dist/helpers/normalizeMimeTypeObject.d.ts.map +1 -0
  97. package/dist/helpers/normalizeMimeTypeObject.js +34 -0
  98. package/dist/helpers/objectMerge.d.ts +5 -0
  99. package/dist/helpers/objectMerge.d.ts.map +1 -0
  100. package/dist/helpers/objectMerge.js +16 -0
  101. package/dist/{parse.d.ts → helpers/parse.d.ts} +1 -1
  102. package/dist/helpers/parse.d.ts.map +1 -0
  103. package/dist/helpers/parse.js +89 -0
  104. package/dist/helpers/prettyPrintJson.d.ts.map +1 -0
  105. package/dist/helpers/prettyPrintJson.js +19 -0
  106. package/dist/helpers/schema-model.d.ts +5 -0
  107. package/dist/helpers/schema-model.d.ts.map +1 -0
  108. package/dist/helpers/schema-model.js +21 -0
  109. package/dist/{ssrState.d.ts → helpers/ssrState.d.ts} +1 -1
  110. package/dist/helpers/ssrState.d.ts.map +1 -0
  111. package/dist/helpers/ssrState.js +9 -0
  112. package/dist/index.d.ts +0 -15
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +0 -914
  115. package/dist/spec-getters/getExampleFromSchema.d.ts.map +1 -0
  116. package/dist/spec-getters/getExampleFromSchema.js +246 -0
  117. package/dist/{getParametersFromOperation.d.ts → spec-getters/getParametersFromOperation.d.ts} +1 -1
  118. package/dist/spec-getters/getParametersFromOperation.d.ts.map +1 -0
  119. package/dist/spec-getters/getParametersFromOperation.js +44 -0
  120. package/dist/{getRequestBodyFromOperation.d.ts → spec-getters/getRequestBodyFromOperation.d.ts} +1 -1
  121. package/dist/spec-getters/getRequestBodyFromOperation.d.ts.map +1 -0
  122. package/dist/spec-getters/getRequestBodyFromOperation.js +199 -0
  123. package/dist/{getRequestFromOperation.d.ts → spec-getters/getRequestFromOperation.d.ts} +5 -1
  124. package/dist/spec-getters/getRequestFromOperation.d.ts.map +1 -0
  125. package/dist/spec-getters/getRequestFromOperation.js +49 -0
  126. package/dist/spec-getters/index.d.ts +5 -0
  127. package/dist/spec-getters/index.d.ts.map +1 -0
  128. package/dist/spec-getters/index.js +4 -0
  129. package/dist/transforms/import-spec.d.ts +67 -0
  130. package/dist/transforms/import-spec.d.ts.map +1 -0
  131. package/dist/transforms/import-spec.js +136 -0
  132. package/dist/transforms/index.d.ts +2 -0
  133. package/dist/transforms/index.d.ts.map +1 -0
  134. package/dist/transforms/index.js +1 -0
  135. package/dist/types.d.ts +43 -2
  136. package/dist/types.d.ts.map +1 -1
  137. package/package.json +63 -14
  138. package/dist/createHash.d.ts.map +0 -1
  139. package/dist/fetchSpecFromUrl.d.ts.map +0 -1
  140. package/dist/getExampleFromSchema.d.ts.map +0 -1
  141. package/dist/getHarRequest.d.ts +0 -4
  142. package/dist/getHarRequest.d.ts.map +0 -1
  143. package/dist/getParametersFromOperation.d.ts.map +0 -1
  144. package/dist/getRequestBodyFromOperation.d.ts.map +0 -1
  145. package/dist/getRequestFromOperation.d.ts.map +0 -1
  146. package/dist/httpStatusCodes.d.ts.map +0 -1
  147. package/dist/json2xml.d.ts.map +0 -1
  148. package/dist/normalizeMimeType.d.ts.map +0 -1
  149. package/dist/normalizeMimeTypeObject.d.ts.map +0 -1
  150. package/dist/parse.d.ts.map +0 -1
  151. package/dist/prettyPrintJson.d.ts.map +0 -1
  152. package/dist/ssrState.d.ts.map +0 -1
  153. /package/dist/{createHash.d.ts → helpers/createHash.d.ts} +0 -0
  154. /package/dist/{fetchSpecFromUrl.d.ts → helpers/fetchSpecFromUrl.d.ts} +0 -0
  155. /package/dist/{httpStatusCodes.d.ts → helpers/httpStatusCodes.d.ts} +0 -0
  156. /package/dist/{json2xml.d.ts → helpers/json2xml.d.ts} +0 -0
  157. /package/dist/{prettyPrintJson.d.ts → helpers/prettyPrintJson.d.ts} +0 -0
  158. /package/dist/{getExampleFromSchema.d.ts → spec-getters/getExampleFromSchema.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getExampleFromSchema.d.ts","sourceRoot":"","sources":["../../src/spec-getters/getExampleFromSchema.ts"],"names":[],"mappings":"AAsCA;;GAEG;AACH,eAAO,MAAM,oBAAoB,WACvB,OAAO,MAAM,EAAE,GAAG,CAAC,YACjB;IACR;;;QAGI;IACJ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAA;IAC/B;;OAEG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAA;CACzC,UACM,MAAM,iBACE,OAAO,MAAM,EAAE,GAAG,CAAC,SAC3B,MAAM,KACZ,GAkSF,CAAA"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * We can use the `format` to generate some random values.
3
+ */
4
+ function guessFromFormat(schema, fallback = '') {
5
+ const exampleValues = {
6
+ // 'date-time': '1970-01-01T00:00:00Z',
7
+ 'date-time': new Date().toISOString(),
8
+ // 'date': '1970-01-01',
9
+ 'date': new Date().toISOString().split('T')[0],
10
+ 'email': 'hello@example.com',
11
+ 'hostname': 'example.com',
12
+ // https://tools.ietf.org/html/rfc6531#section-3.3
13
+ 'idn-email': 'jane.doe@example.com',
14
+ // https://tools.ietf.org/html/rfc5890#section-2.3.2.3
15
+ 'idn-hostname': 'example.com',
16
+ 'ipv4': '127.0.0.1',
17
+ 'ipv6': '51d4:7fab:bfbf:b7d7:b2cb:d4b4:3dad:d998',
18
+ 'iri-reference': '/entitiy/1',
19
+ // https://tools.ietf.org/html/rfc3987
20
+ 'iri': 'https://example.com/entity/123',
21
+ 'json-pointer': '/nested/objects',
22
+ 'password': 'super-secret',
23
+ 'regex': '/[a-z]/',
24
+ // https://tools.ietf.org/html/draft-handrews-relative-json-pointer-01
25
+ 'relative-json-pointer': '1/nested/objects',
26
+ // full-time in https://tools.ietf.org/html/rfc3339#section-5.6
27
+ // 'time': '00:00:00Z',
28
+ 'time': new Date().toISOString().split('T')[1].split('.')[0],
29
+ // either a URI or relative-reference https://tools.ietf.org/html/rfc3986#section-4.1
30
+ 'uri-reference': '../folder',
31
+ 'uri-template': 'https://example.com/{id}',
32
+ 'uri': 'https://example.com',
33
+ 'uuid': '123e4567-e89b-12d3-a456-426614174000',
34
+ };
35
+ return exampleValues[schema.format] ?? fallback;
36
+ }
37
+ /**
38
+ * This function takes a properties object and generates an example response content.
39
+ */
40
+ const getExampleFromSchema = (schema, options, level = 0, parentSchema, name) => {
41
+ // Break an infinite loop
42
+ if (level > 5) {
43
+ return null;
44
+ }
45
+ // Sometimes, we just want the structure and no values.
46
+ // But if `emptyString` is set, we do want to see some values.
47
+ const makeUpRandomData = !!options?.emptyString;
48
+ // Check if the property is read-only
49
+ if (options?.mode === 'write' && schema.readOnly) {
50
+ return undefined;
51
+ }
52
+ // Check if the property is write-only
53
+ if (options?.mode === 'read' && schema.writeOnly) {
54
+ return undefined;
55
+ }
56
+ // Use given variables as values
57
+ if (schema['x-variable']) {
58
+ const value = options?.variables?.[schema['x-variable']];
59
+ // Return the value if it’s defined
60
+ if (value !== undefined) {
61
+ // Type-casting
62
+ if (schema.type === 'number' || schema.type === 'integer') {
63
+ return parseInt(value, 10);
64
+ }
65
+ return value;
66
+ }
67
+ }
68
+ // Use the first example, if there’s an array
69
+ if (Array.isArray(schema.examples) && schema.examples.length > 0) {
70
+ return schema.examples[0];
71
+ }
72
+ // Use an example, if there’s one
73
+ if (schema.example !== undefined) {
74
+ return schema.example;
75
+ }
76
+ // Use a default value, if there’s one
77
+ if (schema.default !== undefined) {
78
+ return schema.default;
79
+ }
80
+ // enum: [ 'available', 'pending', 'sold' ]
81
+ if (schema.enum !== undefined) {
82
+ return schema.enum[0];
83
+ }
84
+ // Check if the property is required
85
+ const isObjectOrArray = schema.type === 'object' || schema.type === 'array';
86
+ if (!isObjectOrArray && options?.omitEmptyAndOptionalProperties === true) {
87
+ const isRequired = schema.required === true ||
88
+ parentSchema?.required === true ||
89
+ parentSchema?.required?.includes(name ?? schema.name);
90
+ if (!isRequired) {
91
+ return undefined;
92
+ }
93
+ }
94
+ // Object
95
+ if (schema.type === 'object' || schema.properties !== undefined) {
96
+ const response = {};
97
+ // Regular properties
98
+ if (schema.properties !== undefined) {
99
+ Object.keys(schema.properties).forEach((propertyName) => {
100
+ const property = schema.properties[propertyName];
101
+ const propertyXmlTagName = options?.xml ? property.xml?.name : undefined;
102
+ response[propertyXmlTagName ?? propertyName] = getExampleFromSchema(property, options, level + 1, schema, propertyName);
103
+ if (typeof response[propertyXmlTagName ?? propertyName] === 'undefined') {
104
+ delete response[propertyXmlTagName ?? propertyName];
105
+ }
106
+ });
107
+ }
108
+ if (schema.anyOf !== undefined) {
109
+ Object.assign(response, getExampleFromSchema(schema.anyOf[0]), options, level + 1);
110
+ }
111
+ else if (schema.oneOf !== undefined) {
112
+ Object.assign(response, getExampleFromSchema(schema.oneOf[0]), options, level + 1);
113
+ }
114
+ else if (schema.allOf !== undefined) {
115
+ Object.assign(response, ...schema.allOf
116
+ .map((item) => getExampleFromSchema(item, options, level + 1, schema))
117
+ .filter((item) => item !== undefined));
118
+ }
119
+ // Merge additionalProperties
120
+ if (schema.additionalProperties !== undefined &&
121
+ schema.additionalProperties !== false) {
122
+ const additionalSchema = getExampleFromSchema(schema.additionalProperties, options, level + 1);
123
+ // Merge objects, but not arrays
124
+ if (additionalSchema &&
125
+ typeof additionalSchema === 'object' &&
126
+ !Array.isArray(additionalSchema)) {
127
+ return {
128
+ ...response,
129
+ ...getExampleFromSchema(schema.additionalProperties, options, level + 1),
130
+ };
131
+ }
132
+ // Add an example for nullable properties
133
+ if (additionalSchema === null) {
134
+ return null;
135
+ }
136
+ // Otherwise, add an example of key-value pair
137
+ const additionalProperties = getExampleFromSchema(schema.additionalProperties, {
138
+ ...options,
139
+ // Let’s just add the additionalProperties, even if they are optional.
140
+ omitEmptyAndOptionalProperties: false,
141
+ }, level + 1);
142
+ return {
143
+ ...response,
144
+ ...(additionalProperties === undefined
145
+ ? {}
146
+ : { '{{key}}': additionalProperties }),
147
+ };
148
+ }
149
+ return response;
150
+ }
151
+ // Array
152
+ if (schema.type === 'array' || schema.items !== undefined) {
153
+ const itemsXmlTagName = schema?.items?.xml?.name;
154
+ const wrapItems = !!(options?.xml && schema.xml?.wrapped && itemsXmlTagName);
155
+ if (schema.example !== undefined) {
156
+ return wrapItems ? { [itemsXmlTagName]: schema.example } : schema.example;
157
+ }
158
+ // Check whether the array has a anyOf, oneOf, or allOf rule
159
+ if (schema.items) {
160
+ // Check for all those rules
161
+ const rules = ['anyOf', 'oneOf', 'allOf'];
162
+ for (const rule of rules) {
163
+ // Skip early if the rule is not defined
164
+ if (!schema.items[rule]) {
165
+ continue;
166
+ }
167
+ // Otherwise generate examples for the rule
168
+ const schemas = ['anyOf', 'oneOf'].includes(rule)
169
+ ? // Use the first item only
170
+ schema.items[rule].slice(0, 1)
171
+ : // Use all items
172
+ schema.items[rule];
173
+ const exampleFromRule = schemas
174
+ .map((item) => getExampleFromSchema(item, options, level + 1, schema))
175
+ .filter((item) => item !== undefined);
176
+ return wrapItems
177
+ ? [{ [itemsXmlTagName]: exampleFromRule }]
178
+ : exampleFromRule;
179
+ }
180
+ }
181
+ if (schema.items?.type) {
182
+ const exampleFromSchema = getExampleFromSchema(schema.items, options, level + 1);
183
+ return wrapItems
184
+ ? [{ [itemsXmlTagName]: exampleFromSchema }]
185
+ : [exampleFromSchema];
186
+ }
187
+ return [];
188
+ }
189
+ const exampleValues = {
190
+ string: makeUpRandomData
191
+ ? guessFromFormat(schema, options?.emptyString)
192
+ : '',
193
+ boolean: true,
194
+ integer: schema.min ?? 1,
195
+ number: schema.min ?? 1,
196
+ array: [],
197
+ };
198
+ if (schema.type !== undefined && exampleValues[schema.type] !== undefined) {
199
+ return exampleValues[schema.type];
200
+ }
201
+ // Check if property has the `oneOf` key
202
+ if (Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
203
+ // Get the first item from the `oneOf` array
204
+ const firstOneOfItem = schema.oneOf[0];
205
+ // Return an example for the first item
206
+ return getExampleFromSchema(firstOneOfItem, options, level + 1);
207
+ }
208
+ // Check if schema has the `allOf` key
209
+ if (Array.isArray(schema.allOf)) {
210
+ let example = null;
211
+ // Loop through all `allOf` schemas
212
+ schema.allOf.forEach((allOfItem) => {
213
+ // Return an example from the schema
214
+ const newExample = getExampleFromSchema(allOfItem, options, level + 1);
215
+ // Merge or overwrite the example
216
+ example =
217
+ typeof newExample === 'object' && typeof example === 'object'
218
+ ? {
219
+ ...(example ?? {}),
220
+ ...newExample,
221
+ }
222
+ : Array.isArray(newExample) && Array.isArray(example)
223
+ ? [...(example ?? {}), ...newExample]
224
+ : newExample;
225
+ });
226
+ return example;
227
+ }
228
+ // Check if schema is a union type
229
+ if (Array.isArray(schema.type)) {
230
+ // Return null if the type is nullable
231
+ if (schema.type.includes('null')) {
232
+ return null;
233
+ }
234
+ // Return an example for the first type in the union
235
+ const exampleValue = exampleValues[schema.type[0]];
236
+ if (exampleValue !== undefined) {
237
+ return exampleValue;
238
+ }
239
+ }
240
+ // Warn if the type is unknown …
241
+ console.warn(`[getExampleFromSchema] Unknown property type "${schema.type}".`);
242
+ // … and just return null for now.
243
+ return null;
244
+ };
245
+
246
+ export { getExampleFromSchema };
@@ -1,4 +1,4 @@
1
- import type { BaseParameter, TransformedOperation } from './types';
1
+ import type { BaseParameter, TransformedOperation } from '../types';
2
2
  /**
3
3
  * Get the query parameters from an operation.
4
4
  *
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getParametersFromOperation.d.ts","sourceRoot":"","sources":["../../src/spec-getters/getParametersFromOperation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAGnE;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,oBAAoB,EAC/B,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,EACnE,YAAY,GAAE,OAAc,GAC3B,aAAa,EAAE,CAkCjB"}
@@ -0,0 +1,44 @@
1
+ import { getExampleFromSchema } from './getExampleFromSchema.js';
2
+
3
+ /**
4
+ * Get the query parameters from an operation.
5
+ *
6
+ * Example: [ { name: 'foobar', value: '' } ]
7
+ *
8
+ * - OpenAPI 3.x: Possible values are “query”, “header”, “path” or “cookie”.
9
+ * - Swagger 2.0: Possible values are "query", "header", "path", "formData" or "body".
10
+ */
11
+ function getParametersFromOperation(operation, where, requiredOnly = true) {
12
+ const parameters = [
13
+ ...(operation.pathParameters || []),
14
+ ...(operation.information?.parameters || []),
15
+ ];
16
+ const params = parameters
17
+ // query, path, header, cookie?
18
+ .filter((parameter) => parameter.in === where)
19
+ // don’t add optional parameters
20
+ .filter((parameter) => (requiredOnly && parameter.required) || !requiredOnly)
21
+ // transform them
22
+ .map((parameter) => ({
23
+ name: parameter.name,
24
+ description: parameter.description ?? null,
25
+ value: parameter.example
26
+ ? parameter.example
27
+ : parameter.schema
28
+ ? getExampleFromSchema(parameter.schema, { mode: 'write' })
29
+ : '',
30
+ required: parameter.required ?? false,
31
+ enabled: parameter.required ?? false,
32
+ }));
33
+ return params.sort((a, b) => {
34
+ if (a.required && !b.required) {
35
+ return -1; // Move a up if a is required and b is not
36
+ }
37
+ else if (!a.required && b.required) {
38
+ return 1; // Move b up if b is required and a is not
39
+ }
40
+ return 0; // Keep original order if both have the same required status
41
+ });
42
+ }
43
+
44
+ export { getParametersFromOperation };
@@ -1,4 +1,4 @@
1
- import type { ContentType, TransformedOperation } from './types';
1
+ import type { ContentType, TransformedOperation } from '../types';
2
2
  /**
3
3
  * Get the request body from the operation.
4
4
  */
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRequestBodyFromOperation.d.ts","sourceRoot":"","sources":["../../src/spec-getters/getRequestBodyFromOperation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAIjE;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,oBAAoB,EAC/B,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA6NrC"}
@@ -0,0 +1,199 @@
1
+ import { json2xml } from '../helpers/json2xml.js';
2
+ import { normalizeMimeTypeObject } from '../helpers/normalizeMimeTypeObject.js';
3
+ import { prettyPrintJson } from '../helpers/prettyPrintJson.js';
4
+ import { getExampleFromSchema } from './getExampleFromSchema.js';
5
+ import { getParametersFromOperation } from './getParametersFromOperation.js';
6
+
7
+ /**
8
+ * Get the request body from the operation.
9
+ */
10
+ function getRequestBodyFromOperation(operation, selectedExampleKey) {
11
+ // Define all supported mime types
12
+ const mimeTypes = [
13
+ 'application/json',
14
+ 'application/octet-stream',
15
+ 'application/x-www-form-urlencoded',
16
+ 'application/xml',
17
+ 'multipart/form-data',
18
+ 'text/plain',
19
+ ];
20
+ // Get the content object from the operation
21
+ const originalContent = operation.information?.requestBody?.content;
22
+ const content = normalizeMimeTypeObject(originalContent);
23
+ // Find the first mime type that is supported
24
+ const mimeType = mimeTypes.find((currentMimeType) => !!content?.[currentMimeType]);
25
+ /** Examples */
26
+ const examples = content?.['application/json']?.examples;
27
+ // Let’s use the first example
28
+ const selectedExample = (examples ?? {})?.[selectedExampleKey ?? Object.keys(examples ?? {})[0]];
29
+ if (selectedExample) {
30
+ return {
31
+ postData: {
32
+ mimeType: 'application/json',
33
+ text: prettyPrintJson(selectedExample?.value),
34
+ },
35
+ };
36
+ }
37
+ /**
38
+ * Body Parameters (Swagger 2.0)
39
+ *
40
+ * ”The payload that's appended to the HTTP request. Since there can only be one payload, there can only
41
+ * be one body parameter. The name of the body parameter has no effect on the parameter itself and is used
42
+ * for documentation purposes only. Since Form parameters are also in the payload, body and form
43
+ * parameters cannot exist together for the same operation.”
44
+ */
45
+ const bodyParameters = getParametersFromOperation(operation, 'body', false);
46
+ if (bodyParameters.length > 0) {
47
+ return {
48
+ postData: {
49
+ mimeType: 'application/json',
50
+ text: prettyPrintJson(bodyParameters[0].value),
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * FormData Parameters (Swagger 2.0)
56
+ *
57
+ * “Form - Used to describe the payload of an HTTP request when either application/x-www-form-urlencoded,
58
+ * multipart/form-data or both are used as the content type of the request (in Swagger's definition, the
59
+ * consumes property of an operation). This is the only parameter type that can be used to send files,
60
+ * thus supporting the file type. Since form parameters are sent in the payload, they cannot be declared
61
+ * together with a body parameter for the same operation. Form parameters have a different format based on
62
+ * the content-type used (for further details, consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4):
63
+ * - application/x-www-form-urlencoded - Similar to the format of Query parameters but as a payload.
64
+ * For example, foo=1&bar=swagger - both foo and bar are form parameters. This is normally used for simple
65
+ * parameters that are being transferred.
66
+ * - multipart/form-data - each parameter takes a section in the payload with an internal header.
67
+ * For example, for the header Content-Disposition: form-data; name="submit-name" the name of the parameter is
68
+ * submit-name. This type of form parameters is more commonly used for file transfers.”
69
+ */
70
+ const formDataParameters = getParametersFromOperation(operation, 'formData', false);
71
+ if (formDataParameters.length > 0) {
72
+ return {
73
+ postData: {
74
+ mimeType: 'application/x-www-form-urlencoded',
75
+ params: formDataParameters.map((parameter) => ({
76
+ name: parameter.name,
77
+ value: parameter.value,
78
+ })),
79
+ },
80
+ };
81
+ }
82
+ // If no mime type is supported, exit early
83
+ if (!mimeType) {
84
+ return {
85
+ postData: undefined,
86
+ };
87
+ }
88
+ // Get the request body object for the mime type
89
+ const requestBodyObject = content?.[mimeType];
90
+ // Define the appropriate Content-Type headers
91
+ const headers = [
92
+ {
93
+ name: 'Content-Type',
94
+ value: mimeType,
95
+ },
96
+ ];
97
+ // Get example from operation
98
+ const example = requestBodyObject?.example
99
+ ? requestBodyObject?.example
100
+ : undefined;
101
+ // JSON
102
+ if (mimeType === 'application/json') {
103
+ const exampleFromSchema = requestBodyObject?.schema
104
+ ? getExampleFromSchema(requestBodyObject?.schema, {
105
+ mode: 'write',
106
+ omitEmptyAndOptionalProperties: true,
107
+ })
108
+ : null;
109
+ const body = example ?? exampleFromSchema;
110
+ return {
111
+ headers,
112
+ postData: {
113
+ mimeType: mimeType,
114
+ text: typeof body === 'string' ? body : JSON.stringify(body, null, 2),
115
+ },
116
+ };
117
+ }
118
+ // XML
119
+ if (mimeType === 'application/xml') {
120
+ const exampleFromSchema = requestBodyObject?.schema
121
+ ? getExampleFromSchema(requestBodyObject?.schema, {
122
+ xml: true,
123
+ mode: 'write',
124
+ omitEmptyAndOptionalProperties: true,
125
+ })
126
+ : null;
127
+ return {
128
+ headers,
129
+ postData: {
130
+ mimeType: mimeType,
131
+ text: example ?? json2xml(exampleFromSchema, ' '),
132
+ },
133
+ };
134
+ }
135
+ // Binary data
136
+ if (mimeType === 'application/octet-stream') {
137
+ return {
138
+ headers,
139
+ postData: {
140
+ mimeType: mimeType,
141
+ text: 'BINARY',
142
+ },
143
+ };
144
+ }
145
+ // Plain text
146
+ if (mimeType === 'text/plain') {
147
+ const exampleFromSchema = requestBodyObject?.schema
148
+ ? getExampleFromSchema(requestBodyObject?.schema, {
149
+ xml: true,
150
+ mode: 'write',
151
+ omitEmptyAndOptionalProperties: true,
152
+ })
153
+ : null;
154
+ return {
155
+ headers,
156
+ postData: {
157
+ mimeType: mimeType,
158
+ text: example ?? exampleFromSchema ?? '',
159
+ },
160
+ };
161
+ }
162
+ // URL encoded data
163
+ if (mimeType === 'application/x-www-form-urlencoded') {
164
+ return {
165
+ headers,
166
+ postData: {
167
+ mimeType: mimeType,
168
+ // TODO: We have an object, but how do we get that kind of array from the object?
169
+ // Don’t forget to include nested properties … :|
170
+ // params: [
171
+ // {
172
+ // name: 'foo',
173
+ // value: 'bar',
174
+ // },
175
+ // ],
176
+ },
177
+ };
178
+ }
179
+ // URL encoded data
180
+ if (mimeType === 'multipart/form-data') {
181
+ return {
182
+ headers,
183
+ postData: {
184
+ mimeType: mimeType,
185
+ // TODO: We have an object, but how do we get that kind of array from the object?
186
+ // Don’t forget to include nested properties … :|
187
+ // params: [
188
+ // {
189
+ // name: 'foo',
190
+ // value: 'bar',
191
+ // },
192
+ // ],
193
+ },
194
+ };
195
+ }
196
+ return undefined;
197
+ }
198
+
199
+ export { getRequestBodyFromOperation };
@@ -1,5 +1,9 @@
1
- import type { HarRequestWithPath, TransformedOperation } from './types';
1
+ import type { HarRequestWithPath, TransformedOperation } from '../types';
2
2
  export declare const getRequestFromOperation: (operation: TransformedOperation, options?: {
3
+ /**
4
+ * If the path will be URL encoded, you may want to replace {curlyBrackets} with __UNDERSCORES__ to indicate an
5
+ * variable.
6
+ */
3
7
  replaceVariables?: boolean;
4
8
  requiredOnly?: boolean;
5
9
  }, selectedExampleKey?: string | number) => Partial<HarRequestWithPath>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRequestFromOperation.d.ts","sourceRoot":"","sources":["../../src/spec-getters/getRequestFromOperation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAGlB,oBAAoB,EACrB,MAAM,UAAU,CAAA;AAIjB,eAAO,MAAM,uBAAuB,cACvB,oBAAoB,YACrB;IACR;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,uBACoB,MAAM,GAAG,MAAM,KACnC,QAAQ,kBAAkB,CA8D5B,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { getParametersFromOperation } from './getParametersFromOperation.js';
2
+ import { getRequestBodyFromOperation } from './getRequestBodyFromOperation.js';
3
+
4
+ const getRequestFromOperation = (operation, options, selectedExampleKey) => {
5
+ // Replace all variables of the format {something} with the uppercase variable name without the brackets
6
+ let path = operation.path;
7
+ // {id} -> 123
8
+ const pathParameters = getParametersFromOperation(operation, 'path', false);
9
+ if (pathParameters.length) {
10
+ const pathVariables = path.match(/{(.*?)}/g);
11
+ if (pathVariables) {
12
+ pathVariables.forEach((variable) => {
13
+ const variableName = variable.replace(/{|}/g, '');
14
+ if (pathParameters) {
15
+ const parameter = pathParameters.find((param) => param.name === variableName);
16
+ if (parameter?.value) {
17
+ path = path.replace(variable, parameter.value.toString());
18
+ }
19
+ }
20
+ });
21
+ }
22
+ }
23
+ // {id} -> __ID__
24
+ if (options?.replaceVariables === true) {
25
+ const pathVariables = path.match(/{(.*?)}/g);
26
+ if (pathVariables) {
27
+ pathVariables.forEach((variable) => {
28
+ const variableName = variable.replace(/{|}/g, '');
29
+ path = path.replace(variable, `__${variableName.toUpperCase()}__`);
30
+ });
31
+ }
32
+ }
33
+ const requestBody = getRequestBodyFromOperation(operation, selectedExampleKey);
34
+ return {
35
+ method: operation.httpVerb.toUpperCase(),
36
+ path,
37
+ headers: [
38
+ ...getParametersFromOperation(operation, 'header', options?.requiredOnly),
39
+ ...(requestBody?.headers ?? []),
40
+ ],
41
+ // TODO: Sorry, something is off here and I don’t get it.
42
+ // @ts-ignore
43
+ postData: requestBody?.postData,
44
+ queryString: getParametersFromOperation(operation, 'query', options?.requiredOnly),
45
+ cookies: getParametersFromOperation(operation, 'cookie', options?.requiredOnly),
46
+ };
47
+ };
48
+
49
+ export { getRequestFromOperation };
@@ -0,0 +1,5 @@
1
+ export * from './getExampleFromSchema.js';
2
+ export * from './getParametersFromOperation.js';
3
+ export * from './getRequestBodyFromOperation.js';
4
+ export * from './getRequestFromOperation.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/spec-getters/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAA;AACtC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,2BAA2B,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { getExampleFromSchema } from './getExampleFromSchema.js';
2
+ export { getParametersFromOperation } from './getParametersFromOperation.js';
3
+ export { getRequestBodyFromOperation } from './getRequestBodyFromOperation.js';
4
+ export { getRequestFromOperation } from './getRequestFromOperation.js';
@@ -0,0 +1,67 @@
1
+ import { type Request } from '../entities/workspace/spec/index.js';
2
+ import type { AnyObject } from '../types';
3
+ /** Import an OpenAPI spec file and convert it to workspace entities */
4
+ export declare const importSpecToWorkspace: (spec: string | AnyObject) => Promise<{
5
+ tags: {
6
+ name: string;
7
+ description?: string | undefined;
8
+ }[];
9
+ folders: {
10
+ name: string;
11
+ uid: string;
12
+ childUids: string[];
13
+ description?: string | undefined;
14
+ }[];
15
+ servers: {
16
+ url: string;
17
+ uid: string;
18
+ description?: string | undefined;
19
+ variables?: Record<string, {
20
+ default: string;
21
+ uid: string;
22
+ enum?: string[] | undefined;
23
+ description?: string | undefined;
24
+ }> | null | undefined;
25
+ }[];
26
+ requests: Request[];
27
+ collection: {
28
+ uid: string;
29
+ spec: {
30
+ openapi: string;
31
+ serverUids: string[];
32
+ tags: {
33
+ name: string;
34
+ description?: string | undefined;
35
+ externalDocs?: {
36
+ url: string;
37
+ description?: string | undefined;
38
+ } | undefined;
39
+ }[];
40
+ info?: {
41
+ title: string;
42
+ version: string;
43
+ summary?: string | undefined;
44
+ description?: string | undefined;
45
+ termsOfService?: string | undefined;
46
+ contact?: {
47
+ name?: string | undefined;
48
+ url?: string | undefined;
49
+ email?: string | undefined;
50
+ } | undefined;
51
+ license?: {
52
+ name: string;
53
+ identifier?: string | undefined;
54
+ url?: string | undefined;
55
+ } | undefined;
56
+ } | undefined;
57
+ externalDocs?: {
58
+ url: string;
59
+ description?: string | undefined;
60
+ } | undefined;
61
+ };
62
+ selectedServerUid: string;
63
+ childUids: string[];
64
+ };
65
+ components: any;
66
+ }>;
67
+ //# sourceMappingURL=import-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-spec.d.ts","sourceRoot":"","sources":["../../src/transforms/import-spec.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,2BAA2B,CAAA;AAKvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAWxC,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,SAAgB,MAAM,GAAG,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmJnE,CAAA"}