api 4.5.1 → 5.0.0-beta.2
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/LICENSE +1 -1
- package/README.md +32 -162
- package/bin/api +2 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +91 -0
- package/dist/cache.d.ts +30 -0
- package/dist/cache.js +217 -0
- package/dist/cli/codegen/index.d.ts +4 -0
- package/dist/cli/codegen/index.js +23 -0
- package/dist/cli/codegen/language.d.ts +27 -0
- package/dist/cli/codegen/language.js +19 -0
- package/dist/cli/codegen/languages/typescript.d.ts +99 -0
- package/dist/cli/codegen/languages/typescript.js +769 -0
- package/dist/cli/commands/index.d.ts +4 -0
- package/dist/cli/commands/index.js +9 -0
- package/dist/cli/commands/install.d.ts +3 -0
- package/dist/cli/commands/install.js +230 -0
- package/dist/cli/lib/prompt.d.ts +9 -0
- package/dist/cli/lib/prompt.js +81 -0
- package/dist/cli/logger.d.ts +1 -0
- package/dist/cli/logger.js +16 -0
- package/dist/cli/storage.d.ts +105 -0
- package/dist/cli/storage.js +264 -0
- package/dist/core/getJSONSchemaDefaults.d.ts +15 -0
- package/dist/core/getJSONSchemaDefaults.js +62 -0
- package/dist/core/index.d.ts +32 -0
- package/dist/core/index.js +143 -0
- package/dist/core/parseResponse.d.ts +1 -0
- package/dist/core/parseResponse.js +65 -0
- package/dist/core/prepareAuth.d.ts +5 -0
- package/dist/core/prepareAuth.js +55 -0
- package/dist/core/prepareParams.d.ts +24 -0
- package/dist/core/prepareParams.js +351 -0
- package/dist/core/prepareServer.d.ts +13 -0
- package/dist/core/prepareServer.js +50 -0
- package/dist/fetcher.d.ts +54 -0
- package/dist/fetcher.js +165 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +276 -0
- package/dist/packageInfo.d.ts +2 -0
- package/dist/packageInfo.js +6 -0
- package/package.json +67 -28
- package/src/.sink.d.ts +1 -0
- package/src/bin.ts +20 -0
- package/src/cache.ts +212 -0
- package/src/cli/codegen/index.ts +31 -0
- package/src/cli/codegen/language.ts +47 -0
- package/src/cli/codegen/languages/typescript.ts +807 -0
- package/src/cli/commands/index.ts +5 -0
- package/src/cli/commands/install.ts +196 -0
- package/src/cli/lib/prompt.ts +29 -0
- package/src/cli/logger.ts +10 -0
- package/src/cli/storage.ts +297 -0
- package/src/core/getJSONSchemaDefaults.ts +74 -0
- package/src/core/index.ts +108 -0
- package/src/{lib/parseResponse.js → core/parseResponse.ts} +5 -7
- package/src/core/prepareAuth.ts +85 -0
- package/src/core/prepareParams.ts +338 -0
- package/src/{lib/prepareServer.js → core/prepareServer.ts} +13 -12
- package/src/fetcher.ts +141 -0
- package/src/index.ts +212 -0
- package/src/packageInfo.ts +3 -0
- package/src/typings.d.ts +3 -0
- package/tsconfig.json +24 -0
- package/src/cache.js +0 -225
- package/src/index.js +0 -177
- package/src/lib/getSchema.js +0 -34
- package/src/lib/index.js +0 -11
- package/src/lib/prepareAuth.js +0 -69
- package/src/lib/prepareParams.js +0 -198
|
@@ -0,0 +1,769 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
28
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
38
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
39
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
40
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
41
|
+
function step(op) {
|
|
42
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
43
|
+
while (_) try {
|
|
44
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
45
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
46
|
+
switch (op[0]) {
|
|
47
|
+
case 0: case 1: t = op; break;
|
|
48
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
49
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
50
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
51
|
+
default:
|
|
52
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
53
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
54
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
55
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
56
|
+
if (t[2]) _.ops.pop();
|
|
57
|
+
_.trys.pop(); continue;
|
|
58
|
+
}
|
|
59
|
+
op = body.call(thisArg, _);
|
|
60
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
61
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
65
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
66
|
+
if (ar || !(i in from)) {
|
|
67
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
68
|
+
ar[i] = from[i];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
|
+
};
|
|
73
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
74
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
75
|
+
};
|
|
76
|
+
exports.__esModule = true;
|
|
77
|
+
var fs_1 = __importDefault(require("fs"));
|
|
78
|
+
var path_1 = __importDefault(require("path"));
|
|
79
|
+
var language_1 = __importDefault(require("../language"));
|
|
80
|
+
var logger_1 = __importDefault(require("../../logger"));
|
|
81
|
+
var object_hash_1 = __importDefault(require("object-hash"));
|
|
82
|
+
var ts_morph_1 = require("ts-morph");
|
|
83
|
+
var json_schema_to_typescript_1 = require("json-schema-to-typescript");
|
|
84
|
+
var formatter_1 = require("json-schema-to-typescript/dist/src/formatter");
|
|
85
|
+
var execa_1 = __importDefault(require("execa"));
|
|
86
|
+
// https://www.30secondsofcode.org/js/s/word-wrap
|
|
87
|
+
function wordWrap(str, max) {
|
|
88
|
+
if (max === void 0) { max = 88; }
|
|
89
|
+
return str.replace(new RegExp("(?![^\\n]{1,".concat(max, "}$)([^\\n]{1,").concat(max, "})\\s"), 'g'), '$1\n');
|
|
90
|
+
}
|
|
91
|
+
var TSGenerator = /** @class */ (function (_super) {
|
|
92
|
+
__extends(TSGenerator, _super);
|
|
93
|
+
function TSGenerator(spec, specPath, identifier, opts) {
|
|
94
|
+
if (opts === void 0) { opts = {}; }
|
|
95
|
+
var _this = this;
|
|
96
|
+
var options = __assign({ outputJS: false, compilerTarget: 'cjs' }, opts);
|
|
97
|
+
if (!options.outputJS) {
|
|
98
|
+
// TypeScript compilation will always target towards ESM-like imports and exports.
|
|
99
|
+
options.compilerTarget = 'esm';
|
|
100
|
+
}
|
|
101
|
+
_this = _super.call(this, spec, specPath, identifier) || this;
|
|
102
|
+
_this.requiredPackages = {
|
|
103
|
+
'api@beta': {
|
|
104
|
+
reason: "Required for the `api/dist/core` library that the codegen'd SDK uses for making requests.",
|
|
105
|
+
url: 'https://npm.im/api'
|
|
106
|
+
},
|
|
107
|
+
oas: {
|
|
108
|
+
reason: 'Used within `api/dist/core` and is also loaded for TypeScript types.',
|
|
109
|
+
url: 'https://npm.im/oas'
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
_this.project = new ts_morph_1.Project({
|
|
113
|
+
manipulationSettings: {
|
|
114
|
+
indentationText: ts_morph_1.IndentationText.TwoSpaces,
|
|
115
|
+
quoteKind: ts_morph_1.QuoteKind.Single
|
|
116
|
+
},
|
|
117
|
+
compilerOptions: __assign({ declaration: true, resolveJsonModule: true, target: options.compilerTarget === 'cjs' ? ts_morph_1.ScriptTarget.ES5 : ts_morph_1.ScriptTarget.ES2020, outDir: 'dist' }, (options.compilerTarget === 'cjs' ? { esModuleInterop: true } : {}))
|
|
118
|
+
});
|
|
119
|
+
_this.compilerTarget = options.compilerTarget;
|
|
120
|
+
_this.outputJS = options.outputJS;
|
|
121
|
+
_this.types = new Map();
|
|
122
|
+
_this.methodGenerics = new Map();
|
|
123
|
+
_this.schemas = new Map();
|
|
124
|
+
return _this;
|
|
125
|
+
}
|
|
126
|
+
TSGenerator.formatter = function (content) {
|
|
127
|
+
return (0, formatter_1.format)(content, {
|
|
128
|
+
format: true,
|
|
129
|
+
style: {
|
|
130
|
+
printWidth: 120,
|
|
131
|
+
singleQuote: true
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
TSGenerator.prototype.installer = function (storage, opts) {
|
|
136
|
+
if (opts === void 0) { opts = {}; }
|
|
137
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
138
|
+
var installDir, pkg, npmInstall;
|
|
139
|
+
return __generator(this, function (_a) {
|
|
140
|
+
switch (_a.label) {
|
|
141
|
+
case 0:
|
|
142
|
+
installDir = storage.getIdentifierStorageDir();
|
|
143
|
+
pkg = {
|
|
144
|
+
name: "@api/".concat(storage.identifier),
|
|
145
|
+
main: "./index.".concat(this.outputJS ? 'js' : 'ts'),
|
|
146
|
+
types: './index.d.ts'
|
|
147
|
+
};
|
|
148
|
+
fs_1["default"].writeFileSync(path_1["default"].join(installDir, 'package.json'), JSON.stringify(pkg, null, 2));
|
|
149
|
+
npmInstall = ['install', '--save', opts.dryRun ? '--dry-run' : ''].filter(Boolean);
|
|
150
|
+
// This will install packages required for the SDK within its installed directory in `.apis/`.
|
|
151
|
+
return [4 /*yield*/, (0, execa_1["default"])('npm', __spreadArray(__spreadArray([], npmInstall, true), Object.keys(this.requiredPackages), true).filter(Boolean), {
|
|
152
|
+
cwd: installDir
|
|
153
|
+
}).then(function (res) {
|
|
154
|
+
if (opts.dryRun) {
|
|
155
|
+
(opts.logger ? opts.logger : logger_1["default"])(res.command);
|
|
156
|
+
(opts.logger ? opts.logger : logger_1["default"])(res.stdout);
|
|
157
|
+
}
|
|
158
|
+
})];
|
|
159
|
+
case 1:
|
|
160
|
+
// This will install packages required for the SDK within its installed directory in `.apis/`.
|
|
161
|
+
_a.sent();
|
|
162
|
+
// This will install the installed SDK as a dependency within the current working directory,
|
|
163
|
+
// adding `@api/<sdk identifier>` as a dependency there so you can load it with
|
|
164
|
+
// `require('@api/<sdk identifier>)`.
|
|
165
|
+
return [2 /*return*/, (0, execa_1["default"])('npm', __spreadArray(__spreadArray([], npmInstall, true), [storage.getIdentifierStorageDir()], false).filter(Boolean)).then(function (res) {
|
|
166
|
+
if (opts.dryRun) {
|
|
167
|
+
(opts.logger ? opts.logger : logger_1["default"])(res.command);
|
|
168
|
+
(opts.logger ? opts.logger : logger_1["default"])(res.stdout);
|
|
169
|
+
}
|
|
170
|
+
})];
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Compile the current OpenAPI definition into a TypeScript library.
|
|
177
|
+
*
|
|
178
|
+
*/
|
|
179
|
+
TSGenerator.prototype.generator = function () {
|
|
180
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
181
|
+
var _a, operations, methods, sdkSource;
|
|
182
|
+
var _this = this;
|
|
183
|
+
return __generator(this, function (_b) {
|
|
184
|
+
switch (_b.label) {
|
|
185
|
+
case 0: return [4 /*yield*/, this.loadOperationsAndMethods()];
|
|
186
|
+
case 1:
|
|
187
|
+
_a = _b.sent(), operations = _a.operations, methods = _a.methods;
|
|
188
|
+
sdkSource = this.project.createSourceFile('index.ts', '');
|
|
189
|
+
sdkSource.addImportDeclarations([
|
|
190
|
+
{ defaultImport: 'Oas', moduleSpecifier: 'oas' },
|
|
191
|
+
{ defaultImport: 'APICore', moduleSpecifier: 'api/dist/core' },
|
|
192
|
+
{ defaultImport: 'definition', moduleSpecifier: this.specPath },
|
|
193
|
+
]);
|
|
194
|
+
// @todo add TOS, License, info.* to a docblock at the top of the SDK.
|
|
195
|
+
this.sdk = sdkSource.addClass({
|
|
196
|
+
name: 'SDK'
|
|
197
|
+
});
|
|
198
|
+
// There's an annoying quirk with `ts-morph` where if we set the SDK class to be the default
|
|
199
|
+
// export with `isDefaultExport` then when we compile it to an ES5 target for CJS environments
|
|
200
|
+
// it'll be exported as `export.default = SDK`, which when you try to load it you'll need to
|
|
201
|
+
// run `require('@api/sdk').default`.
|
|
202
|
+
//
|
|
203
|
+
// Instead here by plainly creating the SDK class in the source file and then setting this
|
|
204
|
+
// export assignment it'll export the SDK class as `module.exports = SDK` so people can cleanly
|
|
205
|
+
// load the SDK with `require('@api/sdk)`.
|
|
206
|
+
//
|
|
207
|
+
// A whole lot of debugging went into here to let people not have to worry about `.default`
|
|
208
|
+
// messes. I hope it's worth it!
|
|
209
|
+
if (this.compilerTarget === 'cjs') {
|
|
210
|
+
sdkSource.addExportAssignment({
|
|
211
|
+
expression: 'SDK'
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
this.sdk.setIsDefaultExport(true);
|
|
216
|
+
}
|
|
217
|
+
this.sdk.addProperties([
|
|
218
|
+
{ name: 'spec', type: 'Oas' },
|
|
219
|
+
{ name: 'core', type: 'APICore' },
|
|
220
|
+
{ name: 'authKeys', type: '(number | string)[][]', initializer: '[]' },
|
|
221
|
+
]);
|
|
222
|
+
this.sdk.addConstructor({
|
|
223
|
+
statements: function (writer) {
|
|
224
|
+
writer.writeLine('this.spec = Oas.init(definition);');
|
|
225
|
+
writer.write('this.core = new APICore(this.spec, ').quote(_this.userAgent).write(');');
|
|
226
|
+
return writer;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
// Add our core API methods for controlling auth, servers, and various configurable abilities.
|
|
230
|
+
sdkSource.addInterface({
|
|
231
|
+
name: 'ConfigOptions',
|
|
232
|
+
properties: [
|
|
233
|
+
{
|
|
234
|
+
name: 'parseResponse',
|
|
235
|
+
type: 'boolean',
|
|
236
|
+
docs: [
|
|
237
|
+
wordWrap('By default we parse the response based on the `Content-Type` header of the request. You can disable this functionality by negating this option.'),
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
]
|
|
241
|
+
});
|
|
242
|
+
this.sdk.addMethods([
|
|
243
|
+
{
|
|
244
|
+
name: 'config',
|
|
245
|
+
parameters: [{ name: 'config', type: 'ConfigOptions' }],
|
|
246
|
+
statements: function (writer) { return writer.writeLine('this.core.setConfig(config);'); },
|
|
247
|
+
docs: [
|
|
248
|
+
{
|
|
249
|
+
description: function (writer) {
|
|
250
|
+
return writer.writeLine(wordWrap('Optionally configure various options, such as response parsing, that the SDK allows.'));
|
|
251
|
+
},
|
|
252
|
+
tags: [
|
|
253
|
+
{ tagName: 'param', text: 'config Object of supported SDK options and toggles.' },
|
|
254
|
+
{
|
|
255
|
+
tagName: 'param',
|
|
256
|
+
text: 'config.parseResponse If responses are parsed according to its `Content-Type` header.'
|
|
257
|
+
},
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: 'auth',
|
|
264
|
+
parameters: [{ name: '...values', type: 'string[] | number[]' }],
|
|
265
|
+
statements: function (writer) {
|
|
266
|
+
writer.writeLine('this.core.setAuth(...values);');
|
|
267
|
+
writer.writeLine('return this;');
|
|
268
|
+
return writer;
|
|
269
|
+
},
|
|
270
|
+
docs: [
|
|
271
|
+
{
|
|
272
|
+
description: function (writer) {
|
|
273
|
+
return writer.writeLine(wordWrap("If the API you're using requires authentication you can supply the required credentials through this method and the library will magically determine how they should be used within your API request.\n\nWith the exception of OpenID and MutualTLS, it supports all forms of authentication supported by the OpenAPI specification.\n\n@example <caption>HTTP Basic auth</caption>\nsdk.auth('username', 'password');\n\n@example <caption>Bearer tokens (HTTP or OAuth 2)</caption>\nsdk.auth('myBearerToken');\n\n@example <caption>API Keys</caption>\nsdk.auth('myApiKey');"));
|
|
274
|
+
},
|
|
275
|
+
tags: [
|
|
276
|
+
{ tagName: 'see', text: '{@link https://spec.openapis.org/oas/v3.0.3#fixed-fields-22}' },
|
|
277
|
+
{ tagName: 'see', text: '{@link https://spec.openapis.org/oas/v3.1.0#fixed-fields-22}' },
|
|
278
|
+
{
|
|
279
|
+
tagName: 'param',
|
|
280
|
+
text: 'values Your auth credentials for the API; can specify up to two strings or numbers.'
|
|
281
|
+
},
|
|
282
|
+
]
|
|
283
|
+
},
|
|
284
|
+
]
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: 'server',
|
|
288
|
+
parameters: [
|
|
289
|
+
{ name: 'url', type: 'string' },
|
|
290
|
+
{ name: 'variables', initializer: '{}' },
|
|
291
|
+
],
|
|
292
|
+
statements: function (writer) { return writer.writeLine('this.core.setServer(url, variables);'); },
|
|
293
|
+
docs: [
|
|
294
|
+
{
|
|
295
|
+
description: function (writer) {
|
|
296
|
+
return writer.writeLine(wordWrap("If the API you're using offers alternate server URLs, and server variables, you can tell the SDK which one to use with this method. To use it you can supply either one of the server URLs that are contained within the OpenAPI definition (along with any server variables), or you can pass it a fully qualified URL to use (that may or may not exist within the OpenAPI definition).\n\n@example <caption>Server URL with server variables</caption>\nsdk.server('https://{region}.api.example.com/{basePath}', {\n name: 'eu',\n basePath: 'v14',\n});\n\n@example <caption>Fully qualified server URL</caption>\nsdk.server('https://eu.api.example.com/v14');"));
|
|
297
|
+
},
|
|
298
|
+
tags: [
|
|
299
|
+
{ tagName: 'param', text: 'url Server URL' },
|
|
300
|
+
{ tagName: 'param', text: 'variables An object of variables to replace into the server URL.' },
|
|
301
|
+
]
|
|
302
|
+
},
|
|
303
|
+
]
|
|
304
|
+
},
|
|
305
|
+
]);
|
|
306
|
+
// Add all common method accessors into the SDK.
|
|
307
|
+
Array.from(methods).forEach(function (method) { return _this.createGenericMethodAccessor(method); });
|
|
308
|
+
// Add all available operation ID accessors into the SDK.
|
|
309
|
+
Object.entries(operations).forEach(function (_a) {
|
|
310
|
+
var operationId = _a[0], data = _a[1];
|
|
311
|
+
_this.createOperationAccessor(data.operation, operationId, data.types.params, data.types.responses);
|
|
312
|
+
});
|
|
313
|
+
// @todo should all of these isolated into their own file outside of the main sdk class file?
|
|
314
|
+
// Add all known types that we're using into the SDK.
|
|
315
|
+
Array.from(this.types.values()).forEach(function (exp) {
|
|
316
|
+
sdkSource.addStatements(exp);
|
|
317
|
+
});
|
|
318
|
+
if (this.outputJS) {
|
|
319
|
+
return [2 /*return*/, this.project
|
|
320
|
+
.emitToMemory()
|
|
321
|
+
.getFiles()
|
|
322
|
+
.map(function (sourceFile) {
|
|
323
|
+
var _a;
|
|
324
|
+
return (_a = {},
|
|
325
|
+
_a[path_1["default"].basename(sourceFile.filePath)] = TSGenerator.formatter(sourceFile.text),
|
|
326
|
+
_a);
|
|
327
|
+
})
|
|
328
|
+
.reduce(function (prev, next) { return Object.assign(prev, next); })];
|
|
329
|
+
}
|
|
330
|
+
return [2 /*return*/, __spreadArray(__spreadArray([], this.project.getSourceFiles().map(function (sourceFile) {
|
|
331
|
+
var _a;
|
|
332
|
+
return (_a = {},
|
|
333
|
+
_a[sourceFile.getBaseName()] = TSGenerator.formatter(sourceFile.getFullText()),
|
|
334
|
+
_a);
|
|
335
|
+
}), true), this.project
|
|
336
|
+
.emitToMemory({ emitOnlyDtsFiles: true })
|
|
337
|
+
.getFiles()
|
|
338
|
+
.map(function (sourceFile) {
|
|
339
|
+
var _a;
|
|
340
|
+
return (_a = {},
|
|
341
|
+
_a[path_1["default"].basename(sourceFile.filePath)] = TSGenerator.formatter(sourceFile.text),
|
|
342
|
+
_a);
|
|
343
|
+
}), true).reduce(function (prev, next) { return Object.assign(prev, next); })];
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
};
|
|
348
|
+
/**
|
|
349
|
+
* Create a generic HTTP method accessor on the SDK.
|
|
350
|
+
*
|
|
351
|
+
* @param method
|
|
352
|
+
*/
|
|
353
|
+
TSGenerator.prototype.createGenericMethodAccessor = function (method) {
|
|
354
|
+
var parameters = [{ name: 'path', type: 'string' }];
|
|
355
|
+
var docblock = {
|
|
356
|
+
description: function (writer) {
|
|
357
|
+
writer.writeLine("Access any ".concat(method.toUpperCase(), " endpoint on your API."));
|
|
358
|
+
return writer;
|
|
359
|
+
},
|
|
360
|
+
tags: [{ tagName: 'param', text: 'path API path to make a request against.' }]
|
|
361
|
+
};
|
|
362
|
+
// Method generic body + metadata parameters are always optional.
|
|
363
|
+
if (method !== 'get') {
|
|
364
|
+
parameters.push({ name: 'body', type: 'unknown', hasQuestionToken: true });
|
|
365
|
+
docblock.tags.push({ tagName: 'param', text: 'body Request body payload data.' });
|
|
366
|
+
}
|
|
367
|
+
parameters.push({ name: 'metadata', type: 'Record<string, unknown>', hasQuestionToken: true });
|
|
368
|
+
docblock.tags.push({
|
|
369
|
+
tagName: 'param',
|
|
370
|
+
text: 'metadata Object containing all path, query, header, and cookie parameters to supply.'
|
|
371
|
+
});
|
|
372
|
+
this.methodGenerics.set(method, this.sdk.addMethod({
|
|
373
|
+
name: method,
|
|
374
|
+
returnType: 'Promise<T>',
|
|
375
|
+
parameters: parameters,
|
|
376
|
+
typeParameters: ['T = unknown'],
|
|
377
|
+
docs: [docblock],
|
|
378
|
+
statements: function (writer) {
|
|
379
|
+
/**
|
|
380
|
+
* @example return this.core.fetch(path, 'get', body, metadata);
|
|
381
|
+
* @example return this.core.fetch(path, 'get', metadata);
|
|
382
|
+
*/
|
|
383
|
+
var fetchStmt = writer.write('return this.core.fetch(path, ').quote(method).write(', ');
|
|
384
|
+
var fetchArgs = parameters.slice(1).map(function (p) { return p.name; });
|
|
385
|
+
fetchArgs.forEach(function (arg, i) {
|
|
386
|
+
fetchStmt.write(arg);
|
|
387
|
+
if (fetchArgs.length > 1 && i !== fetchArgs.length) {
|
|
388
|
+
fetchStmt.write(', ');
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
fetchStmt.write(');');
|
|
392
|
+
return fetchStmt;
|
|
393
|
+
}
|
|
394
|
+
}));
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Create operation accessors on the SDK.
|
|
398
|
+
*
|
|
399
|
+
* @param operation
|
|
400
|
+
* @param operationId
|
|
401
|
+
* @param paramTypes
|
|
402
|
+
* @param responseTypes
|
|
403
|
+
*/
|
|
404
|
+
TSGenerator.prototype.createOperationAccessor = function (operation, operationId, paramTypes, responseTypes) {
|
|
405
|
+
var _this = this;
|
|
406
|
+
var docblock = { tags: [] };
|
|
407
|
+
var summary = operation.getSummary();
|
|
408
|
+
var description = operation.getDescription();
|
|
409
|
+
if (summary || description) {
|
|
410
|
+
// To keep our generated docblocks clean we should only add the `@summary` tag if we've
|
|
411
|
+
// got both a summary and a description present on the operation, otherwise we can alternate
|
|
412
|
+
// what we surface the main docblock description.
|
|
413
|
+
docblock.description = function (writer) {
|
|
414
|
+
if (description) {
|
|
415
|
+
writer.writeLine(description);
|
|
416
|
+
}
|
|
417
|
+
else if (summary) {
|
|
418
|
+
writer.writeLine(summary);
|
|
419
|
+
}
|
|
420
|
+
writer.newLineIfLastNot();
|
|
421
|
+
return writer;
|
|
422
|
+
};
|
|
423
|
+
if (summary && description) {
|
|
424
|
+
docblock.tags.push({ tagName: 'summary', text: summary });
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
var hasOptionalBody = false;
|
|
428
|
+
var hasOptionalMetadata = false;
|
|
429
|
+
var parameters = {};
|
|
430
|
+
if (paramTypes) {
|
|
431
|
+
// If an operation has a request body payload it will only ever have `body` or `formData`,
|
|
432
|
+
// never both, as these are determined upon the media type that's in use.
|
|
433
|
+
if (paramTypes.body || paramTypes.formData) {
|
|
434
|
+
hasOptionalBody = !operation.hasRequiredRequestBody();
|
|
435
|
+
parameters.body = {
|
|
436
|
+
name: 'body',
|
|
437
|
+
type: paramTypes.body
|
|
438
|
+
? this.schemas.get(paramTypes.body).tsType
|
|
439
|
+
: this.schemas.get(paramTypes.formData).tsType,
|
|
440
|
+
hasQuestionToken: hasOptionalBody
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
if (paramTypes.metadata) {
|
|
444
|
+
hasOptionalMetadata = !operation.hasRequiredParameters();
|
|
445
|
+
parameters.metadata = {
|
|
446
|
+
name: 'metadata',
|
|
447
|
+
type: this.schemas.get(paramTypes.metadata).tsType,
|
|
448
|
+
hasQuestionToken: hasOptionalMetadata
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
var returnType = 'Promise<T>';
|
|
453
|
+
var typeParameters = null;
|
|
454
|
+
if (responseTypes) {
|
|
455
|
+
returnType = "Promise<".concat(Object.values(responseTypes)
|
|
456
|
+
.map(function (hash) { return _this.schemas.get(hash).tsType; })
|
|
457
|
+
.join(' | '), ">");
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
// We should only add the `<T>` method typing if we don't have any response types present.
|
|
461
|
+
typeParameters = ['T = unknown'];
|
|
462
|
+
}
|
|
463
|
+
var operationIdAccessor = this.sdk.addMethod({
|
|
464
|
+
name: operationId,
|
|
465
|
+
typeParameters: typeParameters,
|
|
466
|
+
returnType: returnType,
|
|
467
|
+
docs: docblock ? [docblock] : null,
|
|
468
|
+
statements: function (writer) {
|
|
469
|
+
/**
|
|
470
|
+
* @example return this.core.fetch('/pet/findByStatus', 'get', body, metadata);
|
|
471
|
+
* @example return this.core.fetch('/pet/findByStatus', 'get', metadata);
|
|
472
|
+
*/
|
|
473
|
+
var fetchStmt = writer
|
|
474
|
+
.write('return this.core.fetch(')
|
|
475
|
+
.quote(operation.path)
|
|
476
|
+
.write(', ')
|
|
477
|
+
.quote(operation.method);
|
|
478
|
+
var totalParams = Object.keys(parameters).length;
|
|
479
|
+
if (totalParams) {
|
|
480
|
+
Object.values(parameters).forEach(function (arg, i) {
|
|
481
|
+
if (i === 0) {
|
|
482
|
+
fetchStmt.write(', ');
|
|
483
|
+
}
|
|
484
|
+
fetchStmt.write(arg.name);
|
|
485
|
+
if (totalParams > 1 && i !== totalParams) {
|
|
486
|
+
fetchStmt.write(', ');
|
|
487
|
+
}
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
fetchStmt.write(');');
|
|
491
|
+
return fetchStmt;
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
// If we have both body and metadata parameters but only body is optional we need to create
|
|
495
|
+
// a couple function overloads as Typescript doesn't let us have an optional method parameter
|
|
496
|
+
// come before one that's required.
|
|
497
|
+
//
|
|
498
|
+
// None of these accessor overloads will receive a docblock because the original will have
|
|
499
|
+
// that covered.
|
|
500
|
+
var shouldAddAltTypedOverloads = Object.keys(parameters).length === 2 && hasOptionalBody && !hasOptionalMetadata;
|
|
501
|
+
if (shouldAddAltTypedOverloads) {
|
|
502
|
+
// Create an overload that has both `body` and `metadata` parameters as required.
|
|
503
|
+
operationIdAccessor.addOverload({
|
|
504
|
+
typeParameters: typeParameters,
|
|
505
|
+
parameters: [
|
|
506
|
+
__assign(__assign({}, parameters.body), { hasQuestionToken: false }),
|
|
507
|
+
__assign(__assign({}, parameters.metadata), { hasQuestionToken: false }),
|
|
508
|
+
],
|
|
509
|
+
returnType: returnType,
|
|
510
|
+
docs: docblock ? [docblock] : null
|
|
511
|
+
});
|
|
512
|
+
// Create an overload that just has a single `metadata` parameter.
|
|
513
|
+
operationIdAccessor.addOverload({
|
|
514
|
+
typeParameters: typeParameters,
|
|
515
|
+
parameters: [__assign({}, parameters.metadata)],
|
|
516
|
+
returnType: returnType,
|
|
517
|
+
docs: docblock ? [docblock] : null
|
|
518
|
+
});
|
|
519
|
+
// Create an overload that has both `body` and `metadata` parameters as optional. Even though
|
|
520
|
+
// our `metadata` parameter is actually required for this operation this is the only way we're
|
|
521
|
+
// able to have an optional `body` parameter be present before `metadata`.
|
|
522
|
+
//
|
|
523
|
+
// Thankfully our core fetch work in `api/dist/core` is able to do the proper determination to
|
|
524
|
+
// see if what the user is supplying is `metadata` or `body` content when they supply one or
|
|
525
|
+
// both.
|
|
526
|
+
operationIdAccessor.addParameters([
|
|
527
|
+
__assign(__assign({}, parameters.body), { hasQuestionToken: true }),
|
|
528
|
+
__assign(__assign({}, parameters.metadata), { hasQuestionToken: true }),
|
|
529
|
+
]);
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
operationIdAccessor.addParameters(Object.values(parameters));
|
|
533
|
+
}
|
|
534
|
+
// Add a typed generic HTTP method overload for this operation.
|
|
535
|
+
if (this.methodGenerics.has(operation.method)) {
|
|
536
|
+
// If we created alternate overloads for the operation accessor then we need to do the same
|
|
537
|
+
// for its generic HTTP counterpart.
|
|
538
|
+
if (shouldAddAltTypedOverloads) {
|
|
539
|
+
// Create an overload that has both `body` and `metadata` parameters as required.
|
|
540
|
+
this.methodGenerics.get(operation.method).addOverload({
|
|
541
|
+
typeParameters: typeParameters,
|
|
542
|
+
parameters: [
|
|
543
|
+
{ name: 'path', type: "'".concat(operation.path, "'") },
|
|
544
|
+
__assign(__assign({}, parameters.body), { hasQuestionToken: false }),
|
|
545
|
+
__assign(__assign({}, parameters.metadata), { hasQuestionToken: false }),
|
|
546
|
+
],
|
|
547
|
+
returnType: returnType,
|
|
548
|
+
docs: docblock ? [docblock] : null
|
|
549
|
+
});
|
|
550
|
+
// Create an overload that just has a single `metadata` parameter.
|
|
551
|
+
this.methodGenerics.get(operation.method).addOverload({
|
|
552
|
+
typeParameters: typeParameters,
|
|
553
|
+
parameters: [{ name: 'path', type: "'".concat(operation.path, "'") }, parameters.metadata],
|
|
554
|
+
returnType: returnType,
|
|
555
|
+
docs: docblock ? [docblock] : null
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
this.methodGenerics.get(operation.method).addOverload({
|
|
560
|
+
typeParameters: responseTypes ? null : ['T = unknown'],
|
|
561
|
+
parameters: __spreadArray([{ name: 'path', type: "'".concat(operation.path, "'") }], Object.values(parameters), true),
|
|
562
|
+
returnType: returnType,
|
|
563
|
+
docs: docblock ? [docblock] : null
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* Convert a JSON Schema object into a readily available TypeScript type or interface along with
|
|
570
|
+
* any `$ref` pointers that are in use and turn those into TS types too.
|
|
571
|
+
*
|
|
572
|
+
* Under the hood this uses https://npm.im/json-schema-to-typescript for all composition and
|
|
573
|
+
* conversion.
|
|
574
|
+
*
|
|
575
|
+
* @param schema
|
|
576
|
+
* @param name
|
|
577
|
+
*/
|
|
578
|
+
TSGenerator.prototype.convertJSONSchemaToTypescript = function (schema, name) {
|
|
579
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
580
|
+
var ts, primaryType, tempProject, declarations;
|
|
581
|
+
var _this = this;
|
|
582
|
+
return __generator(this, function (_a) {
|
|
583
|
+
switch (_a.label) {
|
|
584
|
+
case 0: return [4 /*yield*/, (0, json_schema_to_typescript_1.compile)(schema, name, {
|
|
585
|
+
bannerComment: '',
|
|
586
|
+
// Running Prettier here for every JSON Schema object we're generating is way too slow so
|
|
587
|
+
// we're instead running it at the very end after we've constructed the SDK.
|
|
588
|
+
format: false
|
|
589
|
+
})];
|
|
590
|
+
case 1:
|
|
591
|
+
ts = _a.sent();
|
|
592
|
+
tempProject = this.project.createSourceFile("".concat(name, ".types.tmp.ts"), ts);
|
|
593
|
+
declarations = tempProject.getExportedDeclarations();
|
|
594
|
+
Array.from(declarations.keys()).forEach(function (declarationName) {
|
|
595
|
+
if (!primaryType) {
|
|
596
|
+
primaryType = declarationName;
|
|
597
|
+
}
|
|
598
|
+
declarations.get(declarationName).forEach(function (declaration) {
|
|
599
|
+
_this.types.set(declarationName, declaration.getText());
|
|
600
|
+
});
|
|
601
|
+
});
|
|
602
|
+
this.project.removeSourceFile(tempProject);
|
|
603
|
+
return [2 /*return*/, {
|
|
604
|
+
primaryType: primaryType
|
|
605
|
+
}];
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
});
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* Scour through the current OpenAPI definition and compile a store of every operation, along
|
|
612
|
+
* with every HTTP method that's in use, and their available TypeScript types that we can use,
|
|
613
|
+
* along with every HTTP method that's in use.
|
|
614
|
+
*
|
|
615
|
+
*/
|
|
616
|
+
TSGenerator.prototype.loadOperationsAndMethods = function () {
|
|
617
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
618
|
+
var operations, methods;
|
|
619
|
+
var _this = this;
|
|
620
|
+
return __generator(this, function (_a) {
|
|
621
|
+
switch (_a.label) {
|
|
622
|
+
case 0:
|
|
623
|
+
operations = {};
|
|
624
|
+
methods = new Set();
|
|
625
|
+
// Prepare all of the schemas that we need to process for every operation within this API
|
|
626
|
+
// definition.
|
|
627
|
+
Object.entries(this.spec.getPaths()).forEach(function (_a) {
|
|
628
|
+
var ops = _a[1];
|
|
629
|
+
Object.entries(ops).forEach(function (_a) {
|
|
630
|
+
var method = _a[0], operation = _a[1];
|
|
631
|
+
methods.add(method);
|
|
632
|
+
var operationId = operation.getOperationId({
|
|
633
|
+
// This `camelCase` option will clean up any weird characters that might be present in
|
|
634
|
+
// the `operationId` so as we don't break TS compilation with an invalid method accessor.
|
|
635
|
+
camelCase: true
|
|
636
|
+
});
|
|
637
|
+
var params = _this.prepareParameterTypesForOperation(operation, operationId);
|
|
638
|
+
var responses = _this.prepareResponseTypesForOperation(operation, operationId);
|
|
639
|
+
if (operation.hasOperationId()) {
|
|
640
|
+
operations[operationId] = {
|
|
641
|
+
types: {
|
|
642
|
+
params: params,
|
|
643
|
+
responses: responses
|
|
644
|
+
},
|
|
645
|
+
operation: operation
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
// Run through and convert every schema we need to use into TS types.
|
|
651
|
+
return [4 /*yield*/, Promise.all(Array.from(this.schemas.entries()).map(function (_a) {
|
|
652
|
+
var hash = _a[0], _b = _a[1], schema = _b.schema, schemaName = _b.name;
|
|
653
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
654
|
+
var ts;
|
|
655
|
+
return __generator(this, function (_c) {
|
|
656
|
+
switch (_c.label) {
|
|
657
|
+
case 0: return [4 /*yield*/, this.convertJSONSchemaToTypescript(schema, schemaName)];
|
|
658
|
+
case 1:
|
|
659
|
+
ts = _c.sent();
|
|
660
|
+
this.schemas.set(hash, __assign(__assign({}, this.schemas.get(hash)), { tsType: ts.primaryType }));
|
|
661
|
+
return [2 /*return*/];
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
}))];
|
|
666
|
+
case 1:
|
|
667
|
+
// Run through and convert every schema we need to use into TS types.
|
|
668
|
+
_a.sent();
|
|
669
|
+
return [2 /*return*/, {
|
|
670
|
+
operations: operations,
|
|
671
|
+
methods: methods
|
|
672
|
+
}];
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
});
|
|
676
|
+
};
|
|
677
|
+
/**
|
|
678
|
+
* Compile the parameter (path, query, cookie, and header) schemas for an API operation into
|
|
679
|
+
* usable TypeScript types.
|
|
680
|
+
*
|
|
681
|
+
* @param operation
|
|
682
|
+
* @param operationId
|
|
683
|
+
*/
|
|
684
|
+
TSGenerator.prototype.prepareParameterTypesForOperation = function (operation, operationId) {
|
|
685
|
+
var _this = this;
|
|
686
|
+
var schemas = operation.getParametersAsJsonSchema({
|
|
687
|
+
mergeIntoBodyAndMetadata: true,
|
|
688
|
+
retainDeprecatedProperties: true
|
|
689
|
+
});
|
|
690
|
+
if (!schemas || !schemas.length) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
var res = schemas
|
|
694
|
+
.map(function (param) {
|
|
695
|
+
var _a;
|
|
696
|
+
return (_a = {}, _a[param.type] = param.schema, _a);
|
|
697
|
+
})
|
|
698
|
+
.reduce(function (prev, next) { return Object.assign(prev, next); });
|
|
699
|
+
return Object.entries(res)
|
|
700
|
+
.map(function (_a) {
|
|
701
|
+
var _b;
|
|
702
|
+
var paramType = _a[0], schema = _a[1];
|
|
703
|
+
var schemaName = schema['x-readme-ref-name'] || "".concat(operationId, "_").concat(paramType, "_param");
|
|
704
|
+
var hash = (0, object_hash_1["default"])({
|
|
705
|
+
name: schemaName,
|
|
706
|
+
schema: schema
|
|
707
|
+
});
|
|
708
|
+
if (!_this.schemas.has(hash)) {
|
|
709
|
+
_this.schemas.set(hash, {
|
|
710
|
+
schema: schema,
|
|
711
|
+
name: schemaName
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
return _b = {},
|
|
715
|
+
_b[paramType] = hash,
|
|
716
|
+
_b;
|
|
717
|
+
})
|
|
718
|
+
.reduce(function (prev, next) { return Object.assign(prev, next); }, {});
|
|
719
|
+
};
|
|
720
|
+
/**
|
|
721
|
+
* Compile the response schemas for an API operation into usable TypeScript types.
|
|
722
|
+
*
|
|
723
|
+
* @todo what does this do for a spec that has no responses?
|
|
724
|
+
* @param operation
|
|
725
|
+
* @param operationId
|
|
726
|
+
*/
|
|
727
|
+
TSGenerator.prototype.prepareResponseTypesForOperation = function (operation, operationId) {
|
|
728
|
+
var _this = this;
|
|
729
|
+
var responseStatusCodes = operation.getResponseStatusCodes();
|
|
730
|
+
if (!responseStatusCodes.length) {
|
|
731
|
+
return undefined;
|
|
732
|
+
}
|
|
733
|
+
var schemas = responseStatusCodes
|
|
734
|
+
.map(function (status) {
|
|
735
|
+
var _a;
|
|
736
|
+
var schema = operation.getResponseAsJsonSchema(status);
|
|
737
|
+
if (!schema) {
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
return _a = {},
|
|
741
|
+
_a[status] = schema.shift(),
|
|
742
|
+
_a;
|
|
743
|
+
})
|
|
744
|
+
.reduce(function (prev, next) { return Object.assign(prev, next); });
|
|
745
|
+
var res = Object.entries(schemas)
|
|
746
|
+
.map(function (_a) {
|
|
747
|
+
var _b;
|
|
748
|
+
var status = _a[0], schema = _a[1].schema;
|
|
749
|
+
var schemaName = schema['x-readme-ref-name'] || "".concat(operationId, "_Response_").concat(status);
|
|
750
|
+
var hash = (0, object_hash_1["default"])({
|
|
751
|
+
name: schemaName,
|
|
752
|
+
schema: schema
|
|
753
|
+
});
|
|
754
|
+
if (!_this.schemas.has(hash)) {
|
|
755
|
+
_this.schemas.set(hash, {
|
|
756
|
+
schema: schema,
|
|
757
|
+
name: schemaName
|
|
758
|
+
});
|
|
759
|
+
}
|
|
760
|
+
return _b = {},
|
|
761
|
+
_b[status] = hash,
|
|
762
|
+
_b;
|
|
763
|
+
})
|
|
764
|
+
.reduce(function (prev, next) { return Object.assign(prev, next); }, {});
|
|
765
|
+
return Object.keys(res).length ? res : undefined;
|
|
766
|
+
};
|
|
767
|
+
return TSGenerator;
|
|
768
|
+
}(language_1["default"]));
|
|
769
|
+
exports["default"] = TSGenerator;
|