swaggie 0.6.5 → 0.6.9-beta
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 +14 -2
- package/dist/cli.js +3 -3
- package/dist/gen/js/genTypes.js +25 -49
- package/dist/gen/js/support.js +2 -42
- package/dist/index.js +2 -2
- package/package.json +17 -33
- package/templates/axios/operation.ejs +1 -1
- package/templates/swr-axios/barrel.ejs +9 -0
- package/templates/swr-axios/baseClient.ejs +20 -0
- package/templates/swr-axios/client.ejs +19 -0
- package/templates/swr-axios/operation.ejs +58 -0
- package/templates/swr-axios/swrOperation.ejs +51 -0
- package/dist/spec/index.js +0 -6
- package/dist/spec/operations.js +0 -103
- package/dist/spec/spec.js +0 -130
package/README.md
CHANGED
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
# Swaggie
|
|
6
6
|
|
|
7
|
+

|
|
7
8
|

|
|
8
9
|
[](https://circleci.com/gh/yhnavein/swaggie)
|
|
9
|
-

|
|
10
10
|

|
|
11
11
|

|
|
12
|
-

|
|
13
12
|

|
|
14
13
|

|
|
15
14
|
|
|
15
|
+
<!--  -->
|
|
16
|
+
|
|
16
17
|
Generate ES6 or Typescript code from an OpenAPI 2.0 spec, so that accessing REST API resources from the client code is less error-prone, static-typed and just easier to use long-term.
|
|
17
18
|
|
|
18
19
|
You can take a look at the [Examples section](#example) down below.
|
|
@@ -88,6 +89,7 @@ The following templates are bundled with Swaggie:
|
|
|
88
89
|
|
|
89
90
|
```
|
|
90
91
|
axios Default template. Recommended for React / Vue / similar frameworks. Uses axios
|
|
92
|
+
swr-axios Template that embraces SRW for GET requests and as a fallback uses axios.
|
|
91
93
|
fetch Template similar to axios, but with fetch API instead. Recommended for React / Vue / similar frameworks
|
|
92
94
|
ng1 Template for Angular 1 (this is for the old one)
|
|
93
95
|
ng2 Template for Angular 2+ (uses HttpClient, InjectionTokens, etc)
|
|
@@ -177,6 +179,16 @@ If Petstore owners decide to remove method we use, then after running `swaggie`
|
|
|
177
179
|
|
|
178
180
|
Without this approach, the error would be spotted by our end-user and he/she would not appreciate it at all!
|
|
179
181
|
|
|
182
|
+
## Server config
|
|
183
|
+
|
|
184
|
+
You might wonder how to set up server to fully utilize Swaggie's features. For that I've added a `samples/` folder with sample configurations.
|
|
185
|
+
|
|
186
|
+
[ASP.NET Core + Nswag](./samples/dotnetcore/nswag/README.md)
|
|
187
|
+
|
|
188
|
+
[ASP.NET Core + Swashbuckle](./samples/dotnetcore/swashbuckle/README.md)
|
|
189
|
+
|
|
190
|
+
Server is not necessary to use Swaggie. Swaggie cares only about the JSON/yaml file with the Open API spec, but for your development purpose you might want to have a server that can serve this file automatically from the actual endpoints.
|
|
191
|
+
|
|
180
192
|
## Notes
|
|
181
193
|
|
|
182
194
|
If you are familiar with the client-code generators for the Swagger / OpenAPI standards then you might wonder why `swaggie` is better than existing tools. Currently the most popular alternative is an open-source `NSwag`.
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
2
|
+
"use strict";
|
|
3
3
|
var _commander = require('commander');
|
|
4
|
-
var
|
|
4
|
+
var _nanocolors = require('nanocolors');
|
|
5
5
|
|
|
6
6
|
var _index = require('./index');
|
|
7
7
|
|
|
@@ -52,6 +52,6 @@ function complete(spec) {
|
|
|
52
52
|
|
|
53
53
|
function error(e) {
|
|
54
54
|
const msg = e instanceof Error ? e.message : e;
|
|
55
|
-
console.error(
|
|
55
|
+
console.error(_nanocolors.red.call(void 0, msg));
|
|
56
56
|
process.exit(1);
|
|
57
57
|
}
|
package/dist/gen/js/genTypes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _lodash = require('lodash');
|
|
2
|
+
var _util = require('../util');
|
|
2
3
|
var _support = require('./support');
|
|
3
|
-
var _lodash = require('lodash');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
function genTypes(
|
|
@@ -56,10 +56,9 @@ function renderTsType(name, def, options, typeToBeGeneric) {
|
|
|
56
56
|
|
|
57
57
|
const lines = [];
|
|
58
58
|
if (def.description) {
|
|
59
|
-
lines.push(
|
|
60
|
-
lines.push(_support.DOC + def.description.trim().replace(/\n/g, `\n${_support.DOC}${_support.SP}`));
|
|
61
|
-
lines.push(` */`);
|
|
59
|
+
lines.push(renderComment(def.description));
|
|
62
60
|
}
|
|
61
|
+
|
|
63
62
|
if (!!def['x-enumNames']) {
|
|
64
63
|
lines.push(renderXEnumType(name, def));
|
|
65
64
|
return lines;
|
|
@@ -90,8 +89,7 @@ function renderTsType(name, def, options, typeToBeGeneric) {
|
|
|
90
89
|
_util.join.call(void 0, lines, requiredPropLines);
|
|
91
90
|
_util.join.call(void 0, lines, optionalPropLines);
|
|
92
91
|
}
|
|
93
|
-
lines.push('}');
|
|
94
|
-
lines.push('');
|
|
92
|
+
lines.push('}\n');
|
|
95
93
|
return lines;
|
|
96
94
|
}
|
|
97
95
|
|
|
@@ -178,10 +176,11 @@ function renderTsInheritance(name, allOf, options) {
|
|
|
178
176
|
const ref = allOf[0];
|
|
179
177
|
const parentName = ref.$ref.split('/').pop();
|
|
180
178
|
const lines = renderTsType(name, allOf[1], options);
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
const interfaceLineIndex = lines.findIndex((l) => l.indexOf('export interface') === 0);
|
|
180
|
+
if (interfaceLineIndex > -1) {
|
|
181
|
+
// Let's replace generic interface definition with more specific one with inheritance info
|
|
182
|
+
lines[interfaceLineIndex] = `export interface ${name} extends ${parentName} {`;
|
|
183
183
|
}
|
|
184
|
-
lines.unshift(`export interface ${name} extends ${parentName} {`);
|
|
185
184
|
return lines;
|
|
186
185
|
}
|
|
187
186
|
|
|
@@ -198,48 +197,11 @@ function renderTsTypeProp(
|
|
|
198
197
|
type = type.replace(typeToBeGeneric, 'T');
|
|
199
198
|
}
|
|
200
199
|
if (info.description) {
|
|
201
|
-
lines.push(
|
|
202
|
-
lines.push(
|
|
203
|
-
`${_support.SP}${_support.DOC}` + (info.description || '').trim().replace(/\n/g, `\n${_support.SP}${_support.DOC}${_support.SP}`)
|
|
204
|
-
);
|
|
205
|
-
lines.push(`${_support.SP} */`);
|
|
200
|
+
lines.push(renderComment(info.desciption));
|
|
206
201
|
}
|
|
207
202
|
const req = required ? '' : '?';
|
|
208
|
-
lines.push(
|
|
209
|
-
return lines;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function renderTypeDoc(name, def) {
|
|
213
|
-
if (def.allOf) {
|
|
214
|
-
return renderDocInheritance(name, def.allOf);
|
|
215
|
-
}
|
|
216
|
-
if (def.type !== 'object') {
|
|
217
|
-
console.warn(`Unable to render ${name} ${def.type}, skipping.`);
|
|
218
|
-
return [];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const lines = ['/**', `${_support.DOC}@typedef ${name}`];
|
|
222
|
-
const req = def.required || [];
|
|
223
|
-
const propLines = Object.keys(def.properties).map((prop) => {
|
|
224
|
-
const info = def.properties[prop];
|
|
225
|
-
const description = (info.description || '').trim().replace(/\n/g, `\n${_support.DOC}${_support.SP}`);
|
|
226
|
-
return `${_support.DOC}@property {${_support.getDocType.call(void 0, info)}} ${prop} ${description}`;
|
|
227
|
-
});
|
|
228
|
-
if (propLines.length) {
|
|
229
|
-
lines.push(`${_support.DOC}`);
|
|
230
|
-
}
|
|
231
|
-
_util.join.call(void 0, lines, propLines);
|
|
232
|
-
lines.push(' */');
|
|
233
|
-
lines.push('');
|
|
234
|
-
return lines;
|
|
235
|
-
}
|
|
203
|
+
lines.push(` ${prop}${req}: ${type};`);
|
|
236
204
|
|
|
237
|
-
function renderDocInheritance(name, allOf) {
|
|
238
|
-
verifyAllOf(name, allOf);
|
|
239
|
-
const ref = allOf[0];
|
|
240
|
-
const parentName = ref.$ref.split('/').pop();
|
|
241
|
-
const lines = renderTypeDoc(name, allOf[1]);
|
|
242
|
-
lines.splice(3, 0, `${_support.DOC}@extends ${parentName}`);
|
|
243
205
|
return lines;
|
|
244
206
|
}
|
|
245
207
|
|
|
@@ -277,3 +239,17 @@ function unwrapDefinitions(definitions) {
|
|
|
277
239
|
|
|
278
240
|
return result;
|
|
279
241
|
}
|
|
242
|
+
|
|
243
|
+
function renderComment(comment) {
|
|
244
|
+
if (!comment) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const commentLines = comment.split('\n');
|
|
249
|
+
|
|
250
|
+
if (commentLines.length === 1) {
|
|
251
|
+
return '// ' + comment.trim();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return ' /**\n' + commentLines.map((line) => ' * ' + line.trim()).join('\n') + '\n */';
|
|
255
|
+
} exports.renderComment = renderComment;
|
package/dist/gen/js/support.js
CHANGED
|
@@ -1,44 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
const DEFAULT_SP = ' '; exports.DEFAULT_SP = DEFAULT_SP;
|
|
3
|
-
let SP = exports.DEFAULT_SP; exports.SP = SP;
|
|
4
|
-
|
|
5
|
-
function formatDocDescription(description) {
|
|
6
|
-
return (description || '').trim().replace(/\n/g, `\n${exports.DOC}${exports.SP}`);
|
|
7
|
-
} exports.formatDocDescription = formatDocDescription;
|
|
8
|
-
|
|
9
|
-
function getDocType(param, options) {
|
|
10
|
-
if (!param) {
|
|
11
|
-
return 'object';
|
|
12
|
-
} else if (param.$ref) {
|
|
13
|
-
const type = param.$ref.split('/').pop();
|
|
14
|
-
return `module:${type}`;
|
|
15
|
-
} else if (param.schema) {
|
|
16
|
-
return getDocType(param.schema, options);
|
|
17
|
-
} else if (param['x-schema']) {
|
|
18
|
-
return getDocType(param['x-schema'], options);
|
|
19
|
-
} else if (param.type === 'array') {
|
|
20
|
-
if (param.items.type) {
|
|
21
|
-
return `${getDocType(param.items, options)}[]`;
|
|
22
|
-
} else if (param.items.$ref) {
|
|
23
|
-
const type = param.items.$ref.split('/').pop();
|
|
24
|
-
return `module:${type}[]`;
|
|
25
|
-
} else {
|
|
26
|
-
return 'object[]';
|
|
27
|
-
}
|
|
28
|
-
} else if (param.type === 'integer' || param.type === 'number') {
|
|
29
|
-
return 'number';
|
|
30
|
-
} else if (param.type === 'string' && (param.format === 'date-time' || param.format === 'date')) {
|
|
31
|
-
return options && options.dateFormat === 'string' ? 'string' : 'Date';
|
|
32
|
-
} else if (param.type === 'string') {
|
|
33
|
-
return 'string';
|
|
34
|
-
} else if (param.type === 'boolean') {
|
|
35
|
-
return 'boolean';
|
|
36
|
-
} else {
|
|
37
|
-
return 'object';
|
|
38
|
-
}
|
|
39
|
-
} exports.getDocType = getDocType;
|
|
40
|
-
|
|
41
|
-
function getTSParamType(param, options) {
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function getTSParamType(param, options) {
|
|
42
2
|
const unknownType = options.preferAny ? 'any' : 'unknown';
|
|
43
3
|
|
|
44
4
|
if (!param) {
|
|
@@ -63,7 +23,7 @@
|
|
|
63
23
|
if (param.items.enum) {
|
|
64
24
|
return `(${getTSParamType(param.items, options)})[]`;
|
|
65
25
|
} else {
|
|
66
|
-
return
|
|
26
|
+
return getTSParamType(param.items, options) + '[]';
|
|
67
27
|
}
|
|
68
28
|
} else if (param.items.$ref) {
|
|
69
29
|
const type = param.items.$ref.split('/').pop();
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
2
|
-
var
|
|
2
|
+
var _nanocolors = require('nanocolors');
|
|
3
3
|
|
|
4
4
|
var _js = require('./gen/js'); var _js2 = _interopRequireDefault(_js);
|
|
5
5
|
|
|
@@ -15,7 +15,7 @@ var _swagger = require('./swagger');
|
|
|
15
15
|
.then((spec) => gen(spec, options))
|
|
16
16
|
.then(() => {
|
|
17
17
|
console.info(
|
|
18
|
-
|
|
18
|
+
_nanocolors.cyan.call(void 0, `Api from ${_nanocolors.bold.call(void 0, options.src)} code generated into ${_nanocolors.bold.call(void 0, options.out)}`)
|
|
19
19
|
);
|
|
20
20
|
return true;
|
|
21
21
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swaggie",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9-beta",
|
|
4
4
|
"description": "Generate ES6 or TypeScript service integration code from an OpenAPI spec",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Piotr Dabrowski",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"url": "https://github.com/yhnavein/swaggie/issues"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
19
|
-
"node": ">=
|
|
19
|
+
"node": ">=12.0.0"
|
|
20
20
|
},
|
|
21
21
|
"main": "dist/index.js",
|
|
22
22
|
"bin": {
|
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
"scripts": {
|
|
26
26
|
"build": "sucrase ./src -d ./dist --transforms typescript,imports && npm run rm-tests",
|
|
27
27
|
"rm-tests": "find dist/ -name '*.spec.js' -type f -delete",
|
|
28
|
-
"test": "
|
|
29
|
-
"test:watch": "jest --watch"
|
|
28
|
+
"test": "mocha 'src/**/*.spec.ts'"
|
|
30
29
|
},
|
|
31
30
|
"files": [
|
|
32
31
|
"dist",
|
|
@@ -42,40 +41,25 @@
|
|
|
42
41
|
"codegen"
|
|
43
42
|
],
|
|
44
43
|
"dependencies": {
|
|
45
|
-
"
|
|
46
|
-
"commander": "^7.2.0",
|
|
44
|
+
"commander": "^8.3.0",
|
|
47
45
|
"ejs": "^3.1.6",
|
|
48
46
|
"js-yaml": "^4.1.0",
|
|
49
47
|
"lodash": "^4.17.21",
|
|
50
48
|
"mkdirp": "^1.0.3",
|
|
51
|
-
"
|
|
49
|
+
"nanocolors": "^0.2.0",
|
|
50
|
+
"node-fetch": "^2.6.3"
|
|
52
51
|
},
|
|
53
52
|
"devDependencies": {
|
|
54
|
-
"@
|
|
55
|
-
"@types/ejs": "3.0
|
|
56
|
-
"@types/
|
|
57
|
-
"@types/
|
|
58
|
-
"@types/
|
|
59
|
-
"@types/
|
|
60
|
-
"@types/node": "
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"sucrase": "3.
|
|
64
|
-
"typescript": "4.2
|
|
65
|
-
},
|
|
66
|
-
"jest": {
|
|
67
|
-
"testRegex": "\\.(test|spec)\\.tsx?$",
|
|
68
|
-
"transform": {
|
|
69
|
-
"^.+\\.tsx?$": "@sucrase/jest-plugin"
|
|
70
|
-
},
|
|
71
|
-
"testPathIgnorePatterns": [
|
|
72
|
-
"<rootDir>/node_modules/",
|
|
73
|
-
"<rootDir>/dist/"
|
|
74
|
-
],
|
|
75
|
-
"testEnvironment": "node",
|
|
76
|
-
"watchPathIgnorePatterns": [
|
|
77
|
-
"<rootDir>/node_modules/",
|
|
78
|
-
"<rootDir>/dist/"
|
|
79
|
-
]
|
|
53
|
+
"@types/chai": "4.2.22",
|
|
54
|
+
"@types/ejs": "3.1.0",
|
|
55
|
+
"@types/js-yaml": "4.0.5",
|
|
56
|
+
"@types/lodash": "4.14.177",
|
|
57
|
+
"@types/mkdirp": "^1.0.2",
|
|
58
|
+
"@types/mocha": "9.0.0",
|
|
59
|
+
"@types/node-fetch": "2.5.3",
|
|
60
|
+
"chai": "4.3.4",
|
|
61
|
+
"mocha": "9.1.3",
|
|
62
|
+
"sucrase": "3.20.3",
|
|
63
|
+
"typescript": "4.5.2"
|
|
80
64
|
}
|
|
81
65
|
}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<%_ if(parameter.original && parameter.original.type === 'array') { -%>
|
|
22
22
|
<%- parameter.name -%>.forEach((f: any) => formDataBody.append("<%- parameter.originalName -%>", f));
|
|
23
23
|
<%_ } else { %>
|
|
24
|
-
formDataBody.append("<%- parameter.originalName -%>", <%- parameter.name -%>);
|
|
24
|
+
formDataBody.append("<%- parameter.originalName -%>", <%- parameter.name -%><%- parameter.type !== 'string' && parameter.type !== 'File' && parameter.type !== 'Blob' ? '.toString()' : '' -%>);
|
|
25
25
|
<%_ } %>
|
|
26
26
|
}
|
|
27
27
|
<% });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
function serializeQueryParam(obj: any) {
|
|
3
|
+
if (obj === null || obj === undefined) return '';
|
|
4
|
+
if (obj instanceof Date) return obj.toJSON();
|
|
5
|
+
if (typeof obj !== 'object' || Array.isArray(obj)) return obj;
|
|
6
|
+
return Object.keys(obj)
|
|
7
|
+
.reduce((a: any, b) => a.push(b + '=' + obj[b]) && a, [])
|
|
8
|
+
.join('&');
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
//----------------------
|
|
4
|
+
// <auto-generated>
|
|
5
|
+
// Generated using Swaggie (https://github.com/yhnavein/swaggie)
|
|
6
|
+
// Please avoid doing any manual changes in this file
|
|
7
|
+
// </auto-generated>
|
|
8
|
+
//----------------------
|
|
9
|
+
// ReSharper disable InconsistentNaming
|
|
10
|
+
|
|
11
|
+
import Axios, { AxiosPromise, AxiosRequestConfig } from "axios";
|
|
12
|
+
import useSWR, { SWRConfiguration } from 'swr';
|
|
13
|
+
|
|
14
|
+
export const axios = Axios.create({
|
|
15
|
+
baseURL: '<%- baseUrl || '' -%>',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
interface SwrConfig extends SWRConfiguration {
|
|
19
|
+
axios?: AxiosRequestConfig;
|
|
20
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const <%- varName -%>Client = {
|
|
2
|
+
<% operations.forEach(function(operation) { %>
|
|
3
|
+
<%- include('operation', operation); %>
|
|
4
|
+
<% }); %>
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
<% var getOperations = operations.filter(function(o) { return o.method == 'GET'; });
|
|
8
|
+
if(getOperations.length > 0) { %>
|
|
9
|
+
<% getOperations.forEach(function(operation) {
|
|
10
|
+
var opName = operation.name;
|
|
11
|
+
if(opName.toLowerCase().startsWith("get")) {
|
|
12
|
+
opName = opName.substring(3);
|
|
13
|
+
}
|
|
14
|
+
opName[0] = opName[0].toUpperCase();
|
|
15
|
+
var customName = "use" + clientName + opName;
|
|
16
|
+
var swrOperation = Object.assign({ swrOpName: customName }, operation); %>
|
|
17
|
+
<%- include('swrOperation', swrOperation); %>
|
|
18
|
+
<% }); %>
|
|
19
|
+
<% } %>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**<% parameters.forEach(function(parameter) { %>
|
|
2
|
+
* @param <%- parameter.name -%> <%- parameter.optional ? '(optional)' : '' -%> <%- parameter.name != parameter.originalName ? `(API name: ${parameter.originalName})` : '' -%>
|
|
3
|
+
<% }); %>
|
|
4
|
+
*/
|
|
5
|
+
<%- name -%>(<% parameters.forEach(function(parameter) { -%>
|
|
6
|
+
<%- parameter.name -%>: <%- parameter.type -%> <%- parameter.optional ? ' | null | undefined' : '' -%>,
|
|
7
|
+
<% }); -%>
|
|
8
|
+
$config?: AxiosRequestConfig
|
|
9
|
+
): AxiosPromise<<%- returnType -%>> {
|
|
10
|
+
let url = '<%- url -%>';
|
|
11
|
+
|
|
12
|
+
<%_ if(pathParams && pathParams.length > 0) {
|
|
13
|
+
pathParams.forEach(function(parameter) { -%>
|
|
14
|
+
url = url.replace('{<%- parameter.name -%>}', encodeURIComponent("" + <%- parameter.name -%>));
|
|
15
|
+
<% });
|
|
16
|
+
} _%>
|
|
17
|
+
<%_ if(formData && formData.length > 0) { _%>
|
|
18
|
+
const formDataBody = new FormData();
|
|
19
|
+
<%_ formData.forEach(function(parameter) { -%>
|
|
20
|
+
if (!!<%- parameter.name -%>) {
|
|
21
|
+
<%_ if(parameter.original && parameter.original.type === 'array') { -%>
|
|
22
|
+
<%- parameter.name -%>.forEach((f: any) => formDataBody.append("<%- parameter.originalName -%>", f));
|
|
23
|
+
<%_ } else { %>
|
|
24
|
+
formDataBody.append("<%- parameter.originalName -%>", <%- parameter.name -%><%- parameter.type !== 'string' && parameter.type !== 'File' && parameter.type !== 'Blob' ? '.toString()' : '' -%>);
|
|
25
|
+
<%_ } %>
|
|
26
|
+
}
|
|
27
|
+
<% });
|
|
28
|
+
} _%>
|
|
29
|
+
|
|
30
|
+
return axios.request<<%- returnType -%>>({
|
|
31
|
+
url: url,
|
|
32
|
+
method: '<%- method -%>',
|
|
33
|
+
<%_ if(formData && formData.length > 0) { _%>
|
|
34
|
+
data: formDataBody,
|
|
35
|
+
<%_ } else if(body) { _%>
|
|
36
|
+
data: <%- body.name -%>,
|
|
37
|
+
<%_ } _%>
|
|
38
|
+
<%_ if(query && query.length > 0) { _%>
|
|
39
|
+
params: {
|
|
40
|
+
<% query.forEach(function(parameter) { -%>
|
|
41
|
+
'<%- parameter.originalName -%>': serializeQueryParam(<%- parameter.name -%>),
|
|
42
|
+
<% }); -%>
|
|
43
|
+
},
|
|
44
|
+
<%_ } _%>
|
|
45
|
+
<%_ if(headers && headers.length > 0) { _%>
|
|
46
|
+
headers: {
|
|
47
|
+
<% headers.forEach(function(parameter) { -%>
|
|
48
|
+
<%_ if (parameter.value) { _%>
|
|
49
|
+
'<%- parameter.originalName -%>': '<%- parameter.value -%>',
|
|
50
|
+
<%_ } else { _%>
|
|
51
|
+
'<%- parameter.originalName -%>': <%- parameter.name -%>,
|
|
52
|
+
<%_ } _%>
|
|
53
|
+
<% }); -%>
|
|
54
|
+
},
|
|
55
|
+
<%_ } _%>
|
|
56
|
+
...$config,
|
|
57
|
+
});
|
|
58
|
+
},
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**<% parameters.forEach(function(parameter) { %>
|
|
2
|
+
* @param <%- parameter.name -%> <%- parameter.optional ? '(optional)' : '' -%> <%- parameter.name != parameter.originalName ? `(API name: ${parameter.originalName})` : '' -%>
|
|
3
|
+
<% }); %>
|
|
4
|
+
*/
|
|
5
|
+
export function <%- swrOpName -%>(<% parameters.forEach(function(parameter) { -%>
|
|
6
|
+
<%- parameter.name -%>: <%- parameter.type -%> <%- parameter.optional ? ' | null | undefined' : '' -%>,
|
|
7
|
+
<% }); -%>
|
|
8
|
+
$config?: SwrConfig
|
|
9
|
+
) {
|
|
10
|
+
let url = '<%- url -%>';
|
|
11
|
+
const { axios: $axiosConf, ...config } = $config || {};
|
|
12
|
+
|
|
13
|
+
<%_ if(pathParams && pathParams.length > 0) {
|
|
14
|
+
pathParams.forEach(function(parameter) { -%>
|
|
15
|
+
url = url.replace('{<%- parameter.name -%>}', encodeURIComponent("" + <%- parameter.name -%>));
|
|
16
|
+
<% });
|
|
17
|
+
} _%>
|
|
18
|
+
|
|
19
|
+
const { data, error } = useSWR<<%- returnType -%>>(
|
|
20
|
+
url,
|
|
21
|
+
() => axios.request({
|
|
22
|
+
url: url,
|
|
23
|
+
method: '<%- method -%>',
|
|
24
|
+
<%_ if(query && query.length > 0) { _%>
|
|
25
|
+
params: {
|
|
26
|
+
<% query.forEach(function(parameter) { -%>
|
|
27
|
+
'<%- parameter.originalName -%>': serializeQueryParam(<%- parameter.name -%>),
|
|
28
|
+
<% }); -%>
|
|
29
|
+
},
|
|
30
|
+
<%_ } _%>
|
|
31
|
+
<%_ if(headers && headers.length > 0) { _%>
|
|
32
|
+
headers: {
|
|
33
|
+
<% headers.forEach(function(parameter) { -%>
|
|
34
|
+
<%_ if (parameter.value) { _%>
|
|
35
|
+
'<%- parameter.originalName -%>': '<%- parameter.value -%>',
|
|
36
|
+
<%_ } else { _%>
|
|
37
|
+
'<%- parameter.originalName -%>': <%- parameter.name -%>,
|
|
38
|
+
<%_ } _%>
|
|
39
|
+
<% }); -%>
|
|
40
|
+
},
|
|
41
|
+
<%_ } _%>
|
|
42
|
+
...$axiosConf})
|
|
43
|
+
.then((resp) => resp.data),
|
|
44
|
+
config);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
data,
|
|
48
|
+
isLoading: !error && !data,
|
|
49
|
+
error: error,
|
|
50
|
+
};
|
|
51
|
+
}
|
package/dist/spec/index.js
DELETED
package/dist/spec/operations.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const SUPPORTED_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch'];
|
|
4
|
-
/**
|
|
5
|
-
* This method converts dictionary-alike operation definition to operation array.
|
|
6
|
-
* Additionally some data inheritance from the specification is done as well
|
|
7
|
-
* @example
|
|
8
|
-
* {
|
|
9
|
-
* "paths": {
|
|
10
|
-
* "/api/heartbeat": {
|
|
11
|
-
* "get": { ... },
|
|
12
|
-
* "post": { ... }
|
|
13
|
-
* }
|
|
14
|
-
* }
|
|
15
|
-
* }
|
|
16
|
-
* @returns
|
|
17
|
-
* [
|
|
18
|
-
* { "method": "GET", "path": "/api/heartbeat", ... },
|
|
19
|
-
* { "method": "POST", "path": "/api/heartbeat", ... },
|
|
20
|
-
* ]
|
|
21
|
-
*/
|
|
22
|
-
function getOperations(spec) {
|
|
23
|
-
return getPaths(spec).reduce((ops, pathInfo) => ops.concat(getPathOperations(pathInfo, spec)), []);
|
|
24
|
-
}
|
|
25
|
-
exports.getOperations = getOperations;
|
|
26
|
-
function getPaths(spec) {
|
|
27
|
-
return Object.keys(spec.paths || {}).map((path) => Object.assign({ path }, spec.paths[path]));
|
|
28
|
-
}
|
|
29
|
-
function getPathOperations(pathInfo, spec) {
|
|
30
|
-
return Object.keys(pathInfo)
|
|
31
|
-
.filter((key) => !!~SUPPORTED_METHODS.indexOf(key))
|
|
32
|
-
.map((method) => getPathOperation(method, pathInfo, spec));
|
|
33
|
-
}
|
|
34
|
-
function inheritPathParams(op, spec, pathInfo) {
|
|
35
|
-
const pathParams = spec.paths[pathInfo.path].parameters;
|
|
36
|
-
if (pathParams) {
|
|
37
|
-
pathParams.forEach((pathParam) => {
|
|
38
|
-
if (!op.parameters.some((p) => p.name === pathParam.name && p.in === pathParam.in)) {
|
|
39
|
-
op.parameters.push(Object.assign({}, pathParam));
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function getPathOperation(method, pathInfo, spec) {
|
|
45
|
-
const op = Object.assign({ method, path: pathInfo.path, parameters: [] }, pathInfo[method]);
|
|
46
|
-
op.id = op.operationId;
|
|
47
|
-
// if there's no explicit operationId given, create one based on the method and path
|
|
48
|
-
if (!op.id) {
|
|
49
|
-
op.id = method + pathInfo.path;
|
|
50
|
-
op.id = op.id.replace(/[\/{(?\/{)\-]([^{.])/g, (_, m) => m.toUpperCase());
|
|
51
|
-
op.id = op.id.replace(/[\/}\-]/g, '');
|
|
52
|
-
}
|
|
53
|
-
inheritPathParams(op, spec, pathInfo);
|
|
54
|
-
op.group = getOperationGroupName(op);
|
|
55
|
-
delete op.operationId;
|
|
56
|
-
op.responses = getOperationResponses(op);
|
|
57
|
-
op.security = getOperationSecurity(op, spec);
|
|
58
|
-
const operation = op;
|
|
59
|
-
if (operation.consumes) {
|
|
60
|
-
operation.contentTypes = operation.consumes;
|
|
61
|
-
}
|
|
62
|
-
if (operation.produces) {
|
|
63
|
-
operation.accepts = operation.produces;
|
|
64
|
-
}
|
|
65
|
-
delete operation.consumes;
|
|
66
|
-
delete operation.produces;
|
|
67
|
-
if (!op.contentTypes || !op.contentTypes.length) {
|
|
68
|
-
op.contentTypes = spec.contentTypes.slice();
|
|
69
|
-
}
|
|
70
|
-
if (!op.accepts || !op.accepts.length) {
|
|
71
|
-
op.accepts = spec.accepts.slice();
|
|
72
|
-
}
|
|
73
|
-
return op;
|
|
74
|
-
}
|
|
75
|
-
function getOperationGroupName(op) {
|
|
76
|
-
let name = op.tags && op.tags.length ? op.tags[0] : 'default';
|
|
77
|
-
name = name.replace(/[^$_a-z0-9]+/gi, '');
|
|
78
|
-
return name.replace(/^[0-9]+/m, '');
|
|
79
|
-
}
|
|
80
|
-
function getOperationResponses(op) {
|
|
81
|
-
return Object.keys(op.responses || {}).map((code) => {
|
|
82
|
-
const info = op.responses[code];
|
|
83
|
-
info.code = code;
|
|
84
|
-
return info;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
function getOperationSecurity(op, spec) {
|
|
88
|
-
let security;
|
|
89
|
-
if (op.security && op.security.length) {
|
|
90
|
-
security = op.security;
|
|
91
|
-
}
|
|
92
|
-
else if (spec.security && spec.security.length) {
|
|
93
|
-
security = spec.security;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
return security.map((def) => {
|
|
99
|
-
const id = Object.keys(def)[0];
|
|
100
|
-
const scopes = def[id].length ? def[id] : undefined;
|
|
101
|
-
return { id, scopes };
|
|
102
|
-
});
|
|
103
|
-
}
|
package/dist/spec/spec.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
7
|
-
const got_1 = __importDefault(require("got"));
|
|
8
|
-
function resolveSpec(src, options) {
|
|
9
|
-
if (!options) {
|
|
10
|
-
options = {};
|
|
11
|
-
}
|
|
12
|
-
if (typeof src === 'string') {
|
|
13
|
-
return loadFile(src).then((spec) => formatSpec(spec, src, options));
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
return Promise.resolve(formatSpec(src, null, options));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.resolveSpec = resolveSpec;
|
|
20
|
-
function loadFile(src) {
|
|
21
|
-
if (/^https?:\/\//im.test(src)) {
|
|
22
|
-
return loadFromUrl(src);
|
|
23
|
-
}
|
|
24
|
-
else if (String(process) === '[object process]') {
|
|
25
|
-
return readLocalFile(src).then((contents) => parseFileContents(contents, src));
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
throw new Error(`Unable to load api at '${src}'`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function loadFromUrl(url) {
|
|
32
|
-
return got_1.default(url)
|
|
33
|
-
.then((resp) => resp.body)
|
|
34
|
-
.then((contents) => parseFileContents(contents, url));
|
|
35
|
-
}
|
|
36
|
-
function readLocalFile(filePath) {
|
|
37
|
-
return new Promise((res, rej) => require('fs').readFile(filePath, 'utf8', (err, contents) => (err ? rej(err) : res(contents))));
|
|
38
|
-
}
|
|
39
|
-
function parseFileContents(contents, path) {
|
|
40
|
-
return /.ya?ml$/i.test(path) ? js_yaml_1.default.safeLoad(contents) : JSON.parse(contents);
|
|
41
|
-
}
|
|
42
|
-
function formatSpec(spec, src, options) {
|
|
43
|
-
if (!spec.basePath) {
|
|
44
|
-
spec.basePath = '';
|
|
45
|
-
}
|
|
46
|
-
else if (spec.basePath.endsWith('/')) {
|
|
47
|
-
spec.basePath = spec.basePath.slice(0, -1);
|
|
48
|
-
}
|
|
49
|
-
if (src && /^https?:\/\//im.test(src)) {
|
|
50
|
-
const parts = src.split('/');
|
|
51
|
-
if (!spec.host) {
|
|
52
|
-
spec.host = parts[2];
|
|
53
|
-
}
|
|
54
|
-
if (!spec.schemes || !spec.schemes.length) {
|
|
55
|
-
spec.schemes = [parts[0].slice(0, -1)];
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
if (!spec.host) {
|
|
60
|
-
spec.host = 'localhost';
|
|
61
|
-
}
|
|
62
|
-
if (!spec.schemes || !spec.schemes.length) {
|
|
63
|
-
spec.schemes = ['http'];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const s = spec;
|
|
67
|
-
if (!s.produces || !s.produces.length) {
|
|
68
|
-
s.accepts = ['application/json']; // give sensible default
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
s.accepts = s.produces;
|
|
72
|
-
}
|
|
73
|
-
if (!s.consumes) {
|
|
74
|
-
s.contentTypes = [];
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
s.contentTypes = s.consumes;
|
|
78
|
-
}
|
|
79
|
-
delete s.consumes;
|
|
80
|
-
delete s.produces;
|
|
81
|
-
return expandRefs(spec, spec, options);
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Recursively expand internal references in the form `#/path/to/object`.
|
|
85
|
-
*
|
|
86
|
-
* @param {object} data the object to search for and update refs
|
|
87
|
-
* @param {object} lookup the object to clone refs from
|
|
88
|
-
* @param {regexp=} refMatch an optional regex to match specific refs to resolve
|
|
89
|
-
* @returns {object} the resolved data object
|
|
90
|
-
*/
|
|
91
|
-
function expandRefs(data, lookup, options) {
|
|
92
|
-
if (!data) {
|
|
93
|
-
return data;
|
|
94
|
-
}
|
|
95
|
-
if (Array.isArray(data)) {
|
|
96
|
-
return data.map((item) => expandRefs(item, lookup, options));
|
|
97
|
-
}
|
|
98
|
-
else if (typeof data === 'object') {
|
|
99
|
-
if (dataCache.has(data)) {
|
|
100
|
-
return data;
|
|
101
|
-
}
|
|
102
|
-
if (data.$ref && !(options.ignoreRefType && data.$ref.startsWith(options.ignoreRefType))) {
|
|
103
|
-
const resolved = expandRef(data.$ref, lookup);
|
|
104
|
-
delete data.$ref;
|
|
105
|
-
data = Object.assign({}, resolved, data);
|
|
106
|
-
}
|
|
107
|
-
dataCache.add(data);
|
|
108
|
-
// tslint:disable-next-line:forin prefer-const
|
|
109
|
-
for (let name in data) {
|
|
110
|
-
data[name] = expandRefs(data[name], lookup, options);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return data;
|
|
114
|
-
}
|
|
115
|
-
exports.expandRefs = expandRefs;
|
|
116
|
-
function expandRef(ref, lookup) {
|
|
117
|
-
const parts = ref.split('/');
|
|
118
|
-
if (parts.shift() !== '#' || !parts[0]) {
|
|
119
|
-
throw new Error(`Only support JSON Schema $refs in format '#/path/to/ref'`);
|
|
120
|
-
}
|
|
121
|
-
let value = lookup;
|
|
122
|
-
while (parts.length) {
|
|
123
|
-
value = value[parts.shift()];
|
|
124
|
-
if (!value) {
|
|
125
|
-
throw new Error(`Invalid schema reference: ${ref}`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return value;
|
|
129
|
-
}
|
|
130
|
-
const dataCache = new Set();
|