@sdk-it/typescript 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.js +700 -2281
- package/dist/index.js.map +4 -4
- package/dist/lib/emitters/interface.d.ts +3 -17
- package/dist/lib/emitters/interface.d.ts.map +1 -1
- package/dist/lib/emitters/zod.d.ts +0 -7
- package/dist/lib/emitters/zod.d.ts.map +1 -1
- package/dist/lib/generate.d.ts +4 -5
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/generator.d.ts +3 -4
- package/dist/lib/generator.d.ts.map +1 -1
- package/dist/lib/sdk.d.ts +4 -5
- package/dist/lib/sdk.d.ts.map +1 -1
- package/dist/lib/status-map.d.ts +3 -0
- package/dist/lib/status-map.d.ts.map +1 -0
- package/dist/lib/statusMap.d.ts +2 -0
- package/dist/lib/statusMap.d.ts.map +1 -0
- package/dist/lib/typescript-snippet.d.ts +8 -5
- package/dist/lib/typescript-snippet.d.ts.map +1 -1
- package/package.json +4 -5
package/dist/index.js
CHANGED
|
@@ -1,1590 +1,22 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
-
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined")
|
|
11
|
-
return require.apply(this, arguments);
|
|
12
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
-
});
|
|
14
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
15
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
|
-
};
|
|
17
|
-
var __copyProps = (to, from, except, desc) => {
|
|
18
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
-
for (let key of __getOwnPropNames(from))
|
|
20
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
-
}
|
|
23
|
-
return to;
|
|
24
|
-
};
|
|
25
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
-
mod
|
|
32
|
-
));
|
|
33
|
-
|
|
34
|
-
// node_modules/pluralize/pluralize.js
|
|
35
|
-
var require_pluralize = __commonJS({
|
|
36
|
-
"node_modules/pluralize/pluralize.js"(exports, module) {
|
|
37
|
-
"use strict";
|
|
38
|
-
(function(root, pluralize3) {
|
|
39
|
-
if (typeof __require === "function" && typeof exports === "object" && typeof module === "object") {
|
|
40
|
-
module.exports = pluralize3();
|
|
41
|
-
} else if (typeof define === "function" && define.amd) {
|
|
42
|
-
define(function() {
|
|
43
|
-
return pluralize3();
|
|
44
|
-
});
|
|
45
|
-
} else {
|
|
46
|
-
root.pluralize = pluralize3();
|
|
47
|
-
}
|
|
48
|
-
})(exports, function() {
|
|
49
|
-
var pluralRules = [];
|
|
50
|
-
var singularRules = [];
|
|
51
|
-
var uncountables = {};
|
|
52
|
-
var irregularPlurals = {};
|
|
53
|
-
var irregularSingles = {};
|
|
54
|
-
function sanitizeRule(rule) {
|
|
55
|
-
if (typeof rule === "string") {
|
|
56
|
-
return new RegExp("^" + rule + "$", "i");
|
|
57
|
-
}
|
|
58
|
-
return rule;
|
|
59
|
-
}
|
|
60
|
-
function restoreCase(word, token) {
|
|
61
|
-
if (word === token)
|
|
62
|
-
return token;
|
|
63
|
-
if (word === word.toLowerCase())
|
|
64
|
-
return token.toLowerCase();
|
|
65
|
-
if (word === word.toUpperCase())
|
|
66
|
-
return token.toUpperCase();
|
|
67
|
-
if (word[0] === word[0].toUpperCase()) {
|
|
68
|
-
return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
|
|
69
|
-
}
|
|
70
|
-
return token.toLowerCase();
|
|
71
|
-
}
|
|
72
|
-
function interpolate(str, args) {
|
|
73
|
-
return str.replace(/\$(\d{1,2})/g, function(match, index) {
|
|
74
|
-
return args[index] || "";
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
function replace(word, rule) {
|
|
78
|
-
return word.replace(rule[0], function(match, index) {
|
|
79
|
-
var result = interpolate(rule[1], arguments);
|
|
80
|
-
if (match === "") {
|
|
81
|
-
return restoreCase(word[index - 1], result);
|
|
82
|
-
}
|
|
83
|
-
return restoreCase(match, result);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
function sanitizeWord(token, word, rules) {
|
|
87
|
-
if (!token.length || uncountables.hasOwnProperty(token)) {
|
|
88
|
-
return word;
|
|
89
|
-
}
|
|
90
|
-
var len = rules.length;
|
|
91
|
-
while (len--) {
|
|
92
|
-
var rule = rules[len];
|
|
93
|
-
if (rule[0].test(word))
|
|
94
|
-
return replace(word, rule);
|
|
95
|
-
}
|
|
96
|
-
return word;
|
|
97
|
-
}
|
|
98
|
-
function replaceWord(replaceMap, keepMap, rules) {
|
|
99
|
-
return function(word) {
|
|
100
|
-
var token = word.toLowerCase();
|
|
101
|
-
if (keepMap.hasOwnProperty(token)) {
|
|
102
|
-
return restoreCase(word, token);
|
|
103
|
-
}
|
|
104
|
-
if (replaceMap.hasOwnProperty(token)) {
|
|
105
|
-
return restoreCase(word, replaceMap[token]);
|
|
106
|
-
}
|
|
107
|
-
return sanitizeWord(token, word, rules);
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
function checkWord(replaceMap, keepMap, rules, bool) {
|
|
111
|
-
return function(word) {
|
|
112
|
-
var token = word.toLowerCase();
|
|
113
|
-
if (keepMap.hasOwnProperty(token))
|
|
114
|
-
return true;
|
|
115
|
-
if (replaceMap.hasOwnProperty(token))
|
|
116
|
-
return false;
|
|
117
|
-
return sanitizeWord(token, token, rules) === token;
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function pluralize3(word, count, inclusive) {
|
|
121
|
-
var pluralized = count === 1 ? pluralize3.singular(word) : pluralize3.plural(word);
|
|
122
|
-
return (inclusive ? count + " " : "") + pluralized;
|
|
123
|
-
}
|
|
124
|
-
pluralize3.plural = replaceWord(
|
|
125
|
-
irregularSingles,
|
|
126
|
-
irregularPlurals,
|
|
127
|
-
pluralRules
|
|
128
|
-
);
|
|
129
|
-
pluralize3.isPlural = checkWord(
|
|
130
|
-
irregularSingles,
|
|
131
|
-
irregularPlurals,
|
|
132
|
-
pluralRules
|
|
133
|
-
);
|
|
134
|
-
pluralize3.singular = replaceWord(
|
|
135
|
-
irregularPlurals,
|
|
136
|
-
irregularSingles,
|
|
137
|
-
singularRules
|
|
138
|
-
);
|
|
139
|
-
pluralize3.isSingular = checkWord(
|
|
140
|
-
irregularPlurals,
|
|
141
|
-
irregularSingles,
|
|
142
|
-
singularRules
|
|
143
|
-
);
|
|
144
|
-
pluralize3.addPluralRule = function(rule, replacement) {
|
|
145
|
-
pluralRules.push([sanitizeRule(rule), replacement]);
|
|
146
|
-
};
|
|
147
|
-
pluralize3.addSingularRule = function(rule, replacement) {
|
|
148
|
-
singularRules.push([sanitizeRule(rule), replacement]);
|
|
149
|
-
};
|
|
150
|
-
pluralize3.addUncountableRule = function(word) {
|
|
151
|
-
if (typeof word === "string") {
|
|
152
|
-
uncountables[word.toLowerCase()] = true;
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
pluralize3.addPluralRule(word, "$0");
|
|
156
|
-
pluralize3.addSingularRule(word, "$0");
|
|
157
|
-
};
|
|
158
|
-
pluralize3.addIrregularRule = function(single, plural) {
|
|
159
|
-
plural = plural.toLowerCase();
|
|
160
|
-
single = single.toLowerCase();
|
|
161
|
-
irregularSingles[single] = plural;
|
|
162
|
-
irregularPlurals[plural] = single;
|
|
163
|
-
};
|
|
164
|
-
[
|
|
165
|
-
// Pronouns.
|
|
166
|
-
["I", "we"],
|
|
167
|
-
["me", "us"],
|
|
168
|
-
["he", "they"],
|
|
169
|
-
["she", "they"],
|
|
170
|
-
["them", "them"],
|
|
171
|
-
["myself", "ourselves"],
|
|
172
|
-
["yourself", "yourselves"],
|
|
173
|
-
["itself", "themselves"],
|
|
174
|
-
["herself", "themselves"],
|
|
175
|
-
["himself", "themselves"],
|
|
176
|
-
["themself", "themselves"],
|
|
177
|
-
["is", "are"],
|
|
178
|
-
["was", "were"],
|
|
179
|
-
["has", "have"],
|
|
180
|
-
["this", "these"],
|
|
181
|
-
["that", "those"],
|
|
182
|
-
// Words ending in with a consonant and `o`.
|
|
183
|
-
["echo", "echoes"],
|
|
184
|
-
["dingo", "dingoes"],
|
|
185
|
-
["volcano", "volcanoes"],
|
|
186
|
-
["tornado", "tornadoes"],
|
|
187
|
-
["torpedo", "torpedoes"],
|
|
188
|
-
// Ends with `us`.
|
|
189
|
-
["genus", "genera"],
|
|
190
|
-
["viscus", "viscera"],
|
|
191
|
-
// Ends with `ma`.
|
|
192
|
-
["stigma", "stigmata"],
|
|
193
|
-
["stoma", "stomata"],
|
|
194
|
-
["dogma", "dogmata"],
|
|
195
|
-
["lemma", "lemmata"],
|
|
196
|
-
["schema", "schemata"],
|
|
197
|
-
["anathema", "anathemata"],
|
|
198
|
-
// Other irregular rules.
|
|
199
|
-
["ox", "oxen"],
|
|
200
|
-
["axe", "axes"],
|
|
201
|
-
["die", "dice"],
|
|
202
|
-
["yes", "yeses"],
|
|
203
|
-
["foot", "feet"],
|
|
204
|
-
["eave", "eaves"],
|
|
205
|
-
["goose", "geese"],
|
|
206
|
-
["tooth", "teeth"],
|
|
207
|
-
["quiz", "quizzes"],
|
|
208
|
-
["human", "humans"],
|
|
209
|
-
["proof", "proofs"],
|
|
210
|
-
["carve", "carves"],
|
|
211
|
-
["valve", "valves"],
|
|
212
|
-
["looey", "looies"],
|
|
213
|
-
["thief", "thieves"],
|
|
214
|
-
["groove", "grooves"],
|
|
215
|
-
["pickaxe", "pickaxes"],
|
|
216
|
-
["passerby", "passersby"]
|
|
217
|
-
].forEach(function(rule) {
|
|
218
|
-
return pluralize3.addIrregularRule(rule[0], rule[1]);
|
|
219
|
-
});
|
|
220
|
-
[
|
|
221
|
-
[/s?$/i, "s"],
|
|
222
|
-
[/[^\u0000-\u007F]$/i, "$0"],
|
|
223
|
-
[/([^aeiou]ese)$/i, "$1"],
|
|
224
|
-
[/(ax|test)is$/i, "$1es"],
|
|
225
|
-
[/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"],
|
|
226
|
-
[/(e[mn]u)s?$/i, "$1s"],
|
|
227
|
-
[/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"],
|
|
228
|
-
[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"],
|
|
229
|
-
[/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"],
|
|
230
|
-
[/(seraph|cherub)(?:im)?$/i, "$1im"],
|
|
231
|
-
[/(her|at|gr)o$/i, "$1oes"],
|
|
232
|
-
[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"],
|
|
233
|
-
[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"],
|
|
234
|
-
[/sis$/i, "ses"],
|
|
235
|
-
[/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"],
|
|
236
|
-
[/([^aeiouy]|qu)y$/i, "$1ies"],
|
|
237
|
-
[/([^ch][ieo][ln])ey$/i, "$1ies"],
|
|
238
|
-
[/(x|ch|ss|sh|zz)$/i, "$1es"],
|
|
239
|
-
[/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"],
|
|
240
|
-
[/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"],
|
|
241
|
-
[/(pe)(?:rson|ople)$/i, "$1ople"],
|
|
242
|
-
[/(child)(?:ren)?$/i, "$1ren"],
|
|
243
|
-
[/eaux$/i, "$0"],
|
|
244
|
-
[/m[ae]n$/i, "men"],
|
|
245
|
-
["thou", "you"]
|
|
246
|
-
].forEach(function(rule) {
|
|
247
|
-
return pluralize3.addPluralRule(rule[0], rule[1]);
|
|
248
|
-
});
|
|
249
|
-
[
|
|
250
|
-
[/s$/i, ""],
|
|
251
|
-
[/(ss)$/i, "$1"],
|
|
252
|
-
[/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"],
|
|
253
|
-
[/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"],
|
|
254
|
-
[/ies$/i, "y"],
|
|
255
|
-
[/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, "$1ie"],
|
|
256
|
-
[/\b(mon|smil)ies$/i, "$1ey"],
|
|
257
|
-
[/\b((?:tit)?m|l)ice$/i, "$1ouse"],
|
|
258
|
-
[/(seraph|cherub)im$/i, "$1"],
|
|
259
|
-
[/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"],
|
|
260
|
-
[/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"],
|
|
261
|
-
[/(movie|twelve|abuse|e[mn]u)s$/i, "$1"],
|
|
262
|
-
[/(test)(?:is|es)$/i, "$1is"],
|
|
263
|
-
[/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"],
|
|
264
|
-
[/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"],
|
|
265
|
-
[/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"],
|
|
266
|
-
[/(alumn|alg|vertebr)ae$/i, "$1a"],
|
|
267
|
-
[/(cod|mur|sil|vert|ind)ices$/i, "$1ex"],
|
|
268
|
-
[/(matr|append)ices$/i, "$1ix"],
|
|
269
|
-
[/(pe)(rson|ople)$/i, "$1rson"],
|
|
270
|
-
[/(child)ren$/i, "$1"],
|
|
271
|
-
[/(eau)x?$/i, "$1"],
|
|
272
|
-
[/men$/i, "man"]
|
|
273
|
-
].forEach(function(rule) {
|
|
274
|
-
return pluralize3.addSingularRule(rule[0], rule[1]);
|
|
275
|
-
});
|
|
276
|
-
[
|
|
277
|
-
// Singular words with no plurals.
|
|
278
|
-
"adulthood",
|
|
279
|
-
"advice",
|
|
280
|
-
"agenda",
|
|
281
|
-
"aid",
|
|
282
|
-
"aircraft",
|
|
283
|
-
"alcohol",
|
|
284
|
-
"ammo",
|
|
285
|
-
"analytics",
|
|
286
|
-
"anime",
|
|
287
|
-
"athletics",
|
|
288
|
-
"audio",
|
|
289
|
-
"bison",
|
|
290
|
-
"blood",
|
|
291
|
-
"bream",
|
|
292
|
-
"buffalo",
|
|
293
|
-
"butter",
|
|
294
|
-
"carp",
|
|
295
|
-
"cash",
|
|
296
|
-
"chassis",
|
|
297
|
-
"chess",
|
|
298
|
-
"clothing",
|
|
299
|
-
"cod",
|
|
300
|
-
"commerce",
|
|
301
|
-
"cooperation",
|
|
302
|
-
"corps",
|
|
303
|
-
"debris",
|
|
304
|
-
"diabetes",
|
|
305
|
-
"digestion",
|
|
306
|
-
"elk",
|
|
307
|
-
"energy",
|
|
308
|
-
"equipment",
|
|
309
|
-
"excretion",
|
|
310
|
-
"expertise",
|
|
311
|
-
"firmware",
|
|
312
|
-
"flounder",
|
|
313
|
-
"fun",
|
|
314
|
-
"gallows",
|
|
315
|
-
"garbage",
|
|
316
|
-
"graffiti",
|
|
317
|
-
"hardware",
|
|
318
|
-
"headquarters",
|
|
319
|
-
"health",
|
|
320
|
-
"herpes",
|
|
321
|
-
"highjinks",
|
|
322
|
-
"homework",
|
|
323
|
-
"housework",
|
|
324
|
-
"information",
|
|
325
|
-
"jeans",
|
|
326
|
-
"justice",
|
|
327
|
-
"kudos",
|
|
328
|
-
"labour",
|
|
329
|
-
"literature",
|
|
330
|
-
"machinery",
|
|
331
|
-
"mackerel",
|
|
332
|
-
"mail",
|
|
333
|
-
"media",
|
|
334
|
-
"mews",
|
|
335
|
-
"moose",
|
|
336
|
-
"music",
|
|
337
|
-
"mud",
|
|
338
|
-
"manga",
|
|
339
|
-
"news",
|
|
340
|
-
"only",
|
|
341
|
-
"personnel",
|
|
342
|
-
"pike",
|
|
343
|
-
"plankton",
|
|
344
|
-
"pliers",
|
|
345
|
-
"police",
|
|
346
|
-
"pollution",
|
|
347
|
-
"premises",
|
|
348
|
-
"rain",
|
|
349
|
-
"research",
|
|
350
|
-
"rice",
|
|
351
|
-
"salmon",
|
|
352
|
-
"scissors",
|
|
353
|
-
"series",
|
|
354
|
-
"sewage",
|
|
355
|
-
"shambles",
|
|
356
|
-
"shrimp",
|
|
357
|
-
"software",
|
|
358
|
-
"species",
|
|
359
|
-
"staff",
|
|
360
|
-
"swine",
|
|
361
|
-
"tennis",
|
|
362
|
-
"traffic",
|
|
363
|
-
"transportation",
|
|
364
|
-
"trout",
|
|
365
|
-
"tuna",
|
|
366
|
-
"wealth",
|
|
367
|
-
"welfare",
|
|
368
|
-
"whiting",
|
|
369
|
-
"wildebeest",
|
|
370
|
-
"wildlife",
|
|
371
|
-
"you",
|
|
372
|
-
/pok[eé]mon$/i,
|
|
373
|
-
// Regexes.
|
|
374
|
-
/[^aeiou]ese$/i,
|
|
375
|
-
// "chinese", "japanese"
|
|
376
|
-
/deer$/i,
|
|
377
|
-
// "deer", "reindeer"
|
|
378
|
-
/fish$/i,
|
|
379
|
-
// "fish", "blowfish", "angelfish"
|
|
380
|
-
/measles$/i,
|
|
381
|
-
/o[iu]s$/i,
|
|
382
|
-
// "carnivorous"
|
|
383
|
-
/pox$/i,
|
|
384
|
-
// "chickpox", "smallpox"
|
|
385
|
-
/sheep$/i
|
|
386
|
-
].forEach(pluralize3.addUncountableRule);
|
|
387
|
-
return pluralize3;
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
|
|
392
1
|
// packages/typescript/src/lib/generate.ts
|
|
393
2
|
import { template as template2 } from "lodash-es";
|
|
394
|
-
import {
|
|
395
|
-
import { join as join2
|
|
3
|
+
import { readdir } from "node:fs/promises";
|
|
4
|
+
import { join as join2 } from "node:path";
|
|
396
5
|
import { npmRunPathEnv } from "npm-run-path";
|
|
397
|
-
import { spinalcase as
|
|
398
|
-
import { methods, pascalcase as
|
|
6
|
+
import { camelcase as camelcase4, spinalcase as spinalcase3 } from "stringcase";
|
|
7
|
+
import { methods, pascalcase as pascalcase5, toLitObject as toLitObject2 } from "@sdk-it/core";
|
|
399
8
|
import {
|
|
400
|
-
|
|
401
|
-
exist,
|
|
9
|
+
createWriterProxy,
|
|
402
10
|
getFolderExports,
|
|
403
|
-
readFolder,
|
|
404
11
|
writeFiles
|
|
405
12
|
} from "@sdk-it/core/file-system.js";
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
import { isEmpty } from "@sdk-it/core/utils.js";
|
|
414
|
-
import { followRef as followRef2, isRef as isRef3 } from "@sdk-it/core";
|
|
415
|
-
var HAS_MORE_POSITIVE_REGEX_PATTERNS = [
|
|
416
|
-
"\\bhas_?more\\b",
|
|
417
|
-
"\\bhas_?next\\b",
|
|
418
|
-
// e.g., itemsHasNext, items_has_next
|
|
419
|
-
"\\bmore_?items\\b",
|
|
420
|
-
"\\bnext_?page\\b",
|
|
421
|
-
// e.g., userNextPageFlag
|
|
422
|
-
"\\badditional\\b",
|
|
423
|
-
// e.g., hasAdditionalData, additional_results_exist
|
|
424
|
-
"\\bcontinuation\\b",
|
|
425
|
-
// e.g., continuationAvailable, has_continuation_token
|
|
426
|
-
"\\bmore_?results\\b",
|
|
427
|
-
"\\bpage_?available\\b",
|
|
428
|
-
"\\bnext(?:_?(page))?\\b"
|
|
429
|
-
];
|
|
430
|
-
var COMPILED_HAS_MORE_POSITIVE_REGEXES = HAS_MORE_POSITIVE_REGEX_PATTERNS.map((p) => new RegExp(p, "i"));
|
|
431
|
-
var HAS_MORE_INVERTED_REGEX_PATTERNS = [
|
|
432
|
-
"\\bis_?last\\b",
|
|
433
|
-
// e.g., pageIsLast
|
|
434
|
-
"\\blast_?page\\b",
|
|
435
|
-
// e.g., resultsAreLastPage
|
|
436
|
-
"\\bend_?of_?(data|results|list|items|stream)\\b",
|
|
437
|
-
"\\bno_?more_?(items|data|results)?\\b",
|
|
438
|
-
"\\ball_?(items_?)?loaded\\b",
|
|
439
|
-
"\\bis_?complete\\b"
|
|
440
|
-
];
|
|
441
|
-
var COMPILED_HAS_MORE_INVERTED_REGEXES = HAS_MORE_INVERTED_REGEX_PATTERNS.map((p) => new RegExp(p, "i"));
|
|
442
|
-
function forEachOperation(config, callback) {
|
|
443
|
-
const result = [];
|
|
444
|
-
for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {
|
|
445
|
-
const { parameters = [], ...methods2 } = pathItem;
|
|
446
|
-
for (const [method, operation] of Object.entries(methods2)) {
|
|
447
|
-
const metadata = operation["x-oaiMeta"] ?? {};
|
|
448
|
-
const operationTag = operation.tags?.[0];
|
|
449
|
-
result.push(
|
|
450
|
-
callback(
|
|
451
|
-
{
|
|
452
|
-
name: metadata.name,
|
|
453
|
-
method,
|
|
454
|
-
path,
|
|
455
|
-
groupName: operationTag,
|
|
456
|
-
tag: operationTag
|
|
457
|
-
},
|
|
458
|
-
operation
|
|
459
|
-
)
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
return result;
|
|
464
|
-
}
|
|
465
|
-
var PropEmitter = class {
|
|
466
|
-
#spec;
|
|
467
|
-
constructor(spec) {
|
|
468
|
-
this.#spec = spec;
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Handle objects (properties)
|
|
472
|
-
*/
|
|
473
|
-
#object(schema) {
|
|
474
|
-
const lines = [];
|
|
475
|
-
const properties = schema.properties || {};
|
|
476
|
-
if (Object.keys(properties).length > 0) {
|
|
477
|
-
lines.push(`**Properties:**`);
|
|
478
|
-
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
479
|
-
const isRequired = (schema.required ?? []).includes(propName);
|
|
480
|
-
lines.push(...this.#property(propName, propSchema, isRequired));
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
if (schema.additionalProperties) {
|
|
484
|
-
lines.push(`**Additional Properties:**`);
|
|
485
|
-
if (typeof schema.additionalProperties === "boolean") {
|
|
486
|
-
lines.push(`- Allowed: ${schema.additionalProperties}`);
|
|
487
|
-
} else {
|
|
488
|
-
lines.push(
|
|
489
|
-
...this.handle(schema.additionalProperties).map((l) => ` ${l}`)
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return lines;
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* Format a property with its type and description
|
|
497
|
-
*/
|
|
498
|
-
#property(name, schema, required) {
|
|
499
|
-
const docs = this.handle(schema);
|
|
500
|
-
const rawType = docs[0].replace("**Type:** ", "").replace(" (nullable)", "|null");
|
|
501
|
-
const defaultVal = !isRef3(schema) && schema.default !== void 0 ? ` default: ${JSON.stringify(schema.default)}` : "";
|
|
502
|
-
const reqMark = required ? " required" : "";
|
|
503
|
-
const summary = `- \`${name}\` ${rawType}${reqMark}${defaultVal}:`;
|
|
504
|
-
const detailLines = docs.slice(1).filter((l) => !l.startsWith("**Default:**")).map((l) => ` ${l}`);
|
|
505
|
-
return [summary, ...detailLines];
|
|
506
|
-
}
|
|
507
|
-
/**
|
|
508
|
-
* Handle array schemas
|
|
509
|
-
*/
|
|
510
|
-
#array(schema) {
|
|
511
|
-
const lines = [];
|
|
512
|
-
lines.push(`**Array items:**`);
|
|
513
|
-
if (schema.items) {
|
|
514
|
-
const itemDocs = this.handle(schema.items);
|
|
515
|
-
lines.push(...itemDocs.map((line) => ` ${line}`));
|
|
516
|
-
} else {
|
|
517
|
-
lines.push(` **Type:** \`unknown\``);
|
|
518
|
-
}
|
|
519
|
-
if (schema.minItems !== void 0)
|
|
520
|
-
lines.push(`- Minimum items: ${schema.minItems}`);
|
|
521
|
-
if (schema.maxItems !== void 0)
|
|
522
|
-
lines.push(`- Maximum items: ${schema.maxItems}`);
|
|
523
|
-
if (schema.uniqueItems)
|
|
524
|
-
lines.push(`- Items must be unique.`);
|
|
525
|
-
return lines;
|
|
526
|
-
}
|
|
527
|
-
#ref($ref) {
|
|
528
|
-
const schemaName = $ref.split("/").pop() || "object";
|
|
529
|
-
const resolved = followRef2(this.#spec, $ref);
|
|
530
|
-
const lines = [
|
|
531
|
-
`**Type:** [\`${schemaName}\`](#${schemaName.toLowerCase()})`
|
|
532
|
-
];
|
|
533
|
-
if (resolved.description) {
|
|
534
|
-
lines.push(resolved.description);
|
|
535
|
-
}
|
|
536
|
-
return lines;
|
|
537
|
-
}
|
|
538
|
-
#allOf(schemas) {
|
|
539
|
-
const lines = ["**All of (Intersection):**"];
|
|
540
|
-
schemas.forEach((subSchema, index) => {
|
|
541
|
-
lines.push(`- **Constraint ${index + 1}:**`);
|
|
542
|
-
const subLines = this.handle(subSchema);
|
|
543
|
-
lines.push(...subLines.map((l) => ` ${l}`));
|
|
544
|
-
});
|
|
545
|
-
return lines;
|
|
546
|
-
}
|
|
547
|
-
#anyOf(schemas) {
|
|
548
|
-
const lines = ["**Any of (Union):**"];
|
|
549
|
-
schemas.forEach((subSchema, index) => {
|
|
550
|
-
lines.push(`- **Option ${index + 1}:**`);
|
|
551
|
-
const subLines = this.handle(subSchema);
|
|
552
|
-
lines.push(...subLines.map((l) => ` ${l}`));
|
|
553
|
-
});
|
|
554
|
-
return lines;
|
|
555
|
-
}
|
|
556
|
-
#oneOf(schemas) {
|
|
557
|
-
const lines = ["**One of (Exclusive Union):**"];
|
|
558
|
-
schemas.forEach((subSchema, index) => {
|
|
559
|
-
lines.push(`- **Option ${index + 1}:**`);
|
|
560
|
-
const subLines = this.handle(subSchema);
|
|
561
|
-
lines.push(...subLines.map((l) => ` ${l}`));
|
|
562
|
-
});
|
|
563
|
-
return lines;
|
|
564
|
-
}
|
|
565
|
-
#enum(schema) {
|
|
566
|
-
const lines = [`**Type:** \`${schema.type || "unknown"}\` (enum)`];
|
|
567
|
-
if (schema.description)
|
|
568
|
-
lines.push(schema.description);
|
|
569
|
-
lines.push("**Allowed values:**");
|
|
570
|
-
lines.push(
|
|
571
|
-
...(schema.enum || []).map((val) => `- \`${JSON.stringify(val)}\``)
|
|
572
|
-
);
|
|
573
|
-
if (schema.default !== void 0) {
|
|
574
|
-
lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
|
|
575
|
-
}
|
|
576
|
-
return lines;
|
|
577
|
-
}
|
|
578
|
-
#normal(type, schema, nullable) {
|
|
579
|
-
const lines = [];
|
|
580
|
-
const nullableSuffix = nullable ? " (nullable)" : "";
|
|
581
|
-
const description = schema.description ? [schema.description] : [];
|
|
582
|
-
switch (type) {
|
|
583
|
-
case "string":
|
|
584
|
-
lines.push(
|
|
585
|
-
`**Type:** \`string\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
|
|
586
|
-
);
|
|
587
|
-
lines.push(...description);
|
|
588
|
-
if (schema.minLength !== void 0)
|
|
589
|
-
lines.push(`- Minimum length: ${schema.minLength}`);
|
|
590
|
-
if (schema.maxLength !== void 0)
|
|
591
|
-
lines.push(`- Maximum length: ${schema.maxLength}`);
|
|
592
|
-
if (schema.pattern !== void 0)
|
|
593
|
-
lines.push(`- Pattern: \`${schema.pattern}\``);
|
|
594
|
-
break;
|
|
595
|
-
case "number":
|
|
596
|
-
case "integer":
|
|
597
|
-
lines.push(
|
|
598
|
-
`**Type:** \`${type}\`${schema.format ? ` (format: ${schema.format})` : ""}${nullableSuffix}`
|
|
599
|
-
);
|
|
600
|
-
lines.push(...description);
|
|
601
|
-
if (schema.minimum !== void 0) {
|
|
602
|
-
const exclusiveMin = typeof schema.exclusiveMinimum === "number";
|
|
603
|
-
lines.push(
|
|
604
|
-
`- Minimum: ${schema.minimum}${exclusiveMin ? " (exclusive)" : ""}`
|
|
605
|
-
);
|
|
606
|
-
if (exclusiveMin) {
|
|
607
|
-
lines.push(
|
|
608
|
-
`- Must be strictly greater than: ${schema.exclusiveMinimum}`
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
} else if (typeof schema.exclusiveMinimum === "number") {
|
|
612
|
-
lines.push(
|
|
613
|
-
`- Must be strictly greater than: ${schema.exclusiveMinimum}`
|
|
614
|
-
);
|
|
615
|
-
}
|
|
616
|
-
if (schema.maximum !== void 0) {
|
|
617
|
-
const exclusiveMax = typeof schema.exclusiveMaximum === "number";
|
|
618
|
-
lines.push(
|
|
619
|
-
`- Maximum: ${schema.maximum}${exclusiveMax ? " (exclusive)" : ""}`
|
|
620
|
-
);
|
|
621
|
-
if (exclusiveMax) {
|
|
622
|
-
lines.push(
|
|
623
|
-
`- Must be strictly less than: ${schema.exclusiveMaximum}`
|
|
624
|
-
);
|
|
625
|
-
}
|
|
626
|
-
} else if (typeof schema.exclusiveMaximum === "number") {
|
|
627
|
-
lines.push(
|
|
628
|
-
`- Must be strictly less than: ${schema.exclusiveMaximum}`
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
if (schema.multipleOf !== void 0)
|
|
632
|
-
lines.push(`- Must be a multiple of: ${schema.multipleOf}`);
|
|
633
|
-
break;
|
|
634
|
-
case "boolean":
|
|
635
|
-
lines.push(`**Type:** \`boolean\`${nullableSuffix}`);
|
|
636
|
-
lines.push(...description);
|
|
637
|
-
break;
|
|
638
|
-
case "object":
|
|
639
|
-
lines.push(`**Type:** \`object\`${nullableSuffix}`);
|
|
640
|
-
lines.push(...description);
|
|
641
|
-
lines.push(...this.#object(schema));
|
|
642
|
-
break;
|
|
643
|
-
case "array":
|
|
644
|
-
lines.push(`**Type:** \`array\`${nullableSuffix}`);
|
|
645
|
-
lines.push(...description);
|
|
646
|
-
lines.push(...this.#array(schema));
|
|
647
|
-
break;
|
|
648
|
-
case "null":
|
|
649
|
-
lines.push(`**Type:** \`null\``);
|
|
650
|
-
lines.push(...description);
|
|
651
|
-
break;
|
|
652
|
-
default:
|
|
653
|
-
lines.push(`**Type:** \`${type}\`${nullableSuffix}`);
|
|
654
|
-
lines.push(...description);
|
|
655
|
-
}
|
|
656
|
-
if (schema.default !== void 0) {
|
|
657
|
-
lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
|
|
658
|
-
}
|
|
659
|
-
return lines.filter((l) => l);
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* Handle schemas by resolving references and delegating to appropriate handler
|
|
663
|
-
*/
|
|
664
|
-
handle(schemaOrRef) {
|
|
665
|
-
if (isRef3(schemaOrRef)) {
|
|
666
|
-
return this.#ref(schemaOrRef.$ref);
|
|
667
|
-
}
|
|
668
|
-
const schema = schemaOrRef;
|
|
669
|
-
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
670
|
-
return this.#allOf(schema.allOf);
|
|
671
|
-
}
|
|
672
|
-
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
673
|
-
return this.#anyOf(schema.anyOf);
|
|
674
|
-
}
|
|
675
|
-
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
676
|
-
return this.#oneOf(schema.oneOf);
|
|
677
|
-
}
|
|
678
|
-
if (schema.enum && Array.isArray(schema.enum)) {
|
|
679
|
-
return this.#enum(schema);
|
|
680
|
-
}
|
|
681
|
-
let types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
682
|
-
let nullable = false;
|
|
683
|
-
if (types.includes("null")) {
|
|
684
|
-
nullable = true;
|
|
685
|
-
types = types.filter((t) => t !== "null");
|
|
686
|
-
}
|
|
687
|
-
if (types.length === 0) {
|
|
688
|
-
if (schema.properties || schema.additionalProperties) {
|
|
689
|
-
types = ["object"];
|
|
690
|
-
} else if (schema.items) {
|
|
691
|
-
types = ["array"];
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
if (types.length === 0) {
|
|
695
|
-
const lines2 = ["**Type:** `unknown`"];
|
|
696
|
-
if (schema.description)
|
|
697
|
-
lines2.push(schema.description);
|
|
698
|
-
if (schema.default !== void 0)
|
|
699
|
-
lines2.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
|
|
700
|
-
return lines2;
|
|
701
|
-
}
|
|
702
|
-
if (types.length === 1) {
|
|
703
|
-
return this.#normal(types[0], schema, nullable);
|
|
704
|
-
}
|
|
705
|
-
const typeString = types.join(" | ");
|
|
706
|
-
const nullableSuffix = nullable ? " (nullable)" : "";
|
|
707
|
-
const lines = [`**Type:** \`${typeString}\`${nullableSuffix}`];
|
|
708
|
-
if (schema.description)
|
|
709
|
-
lines.push(schema.description);
|
|
710
|
-
if (schema.default !== void 0)
|
|
711
|
-
lines.push(`**Default:** \`${JSON.stringify(schema.default)}\``);
|
|
712
|
-
return lines;
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Process a request body and return markdown documentation
|
|
716
|
-
*/
|
|
717
|
-
requestBody(requestBody) {
|
|
718
|
-
if (!requestBody)
|
|
719
|
-
return [];
|
|
720
|
-
const lines = [];
|
|
721
|
-
lines.push(`##### Request Body`);
|
|
722
|
-
if (requestBody.description) {
|
|
723
|
-
lines.push(requestBody.description);
|
|
724
|
-
}
|
|
725
|
-
if (requestBody.required) {
|
|
726
|
-
lines.push(`*This request body is required.*`);
|
|
727
|
-
}
|
|
728
|
-
if (requestBody.content) {
|
|
729
|
-
for (const [contentType, mediaType] of Object.entries(
|
|
730
|
-
requestBody.content
|
|
731
|
-
)) {
|
|
732
|
-
lines.push(`**Content Type:** \`${contentType}\``);
|
|
733
|
-
if (mediaType.schema) {
|
|
734
|
-
const schemaDocs = this.handle(mediaType.schema);
|
|
735
|
-
lines.push(...schemaDocs);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
return lines;
|
|
740
|
-
}
|
|
741
|
-
};
|
|
742
|
-
function toReadme(spec, generators) {
|
|
743
|
-
const markdown = [];
|
|
744
|
-
const propEmitter = new PropEmitter(spec);
|
|
745
|
-
forEachOperation({ spec }, (entry, operation) => {
|
|
746
|
-
const { method, path, name } = entry;
|
|
747
|
-
spec.components ??= {};
|
|
748
|
-
spec.components.schemas ??= {};
|
|
749
|
-
markdown.push(
|
|
750
|
-
`#### ${name || operation.operationId} | ${`_${method.toUpperCase()} ${path}_`}`
|
|
751
|
-
);
|
|
752
|
-
markdown.push(operation.summary || "");
|
|
753
|
-
const snippet = generators.generateSnippet(entry, operation);
|
|
754
|
-
markdown.push(`##### Example usage`);
|
|
755
|
-
markdown.push(snippet);
|
|
756
|
-
const requestBodyContent = propEmitter.requestBody(operation.requestBody);
|
|
757
|
-
if (requestBodyContent.length > 1) {
|
|
758
|
-
markdown.push(requestBodyContent.join("\n\n"));
|
|
759
|
-
}
|
|
760
|
-
markdown.push(`##### Responses`);
|
|
761
|
-
for (const status in operation.responses) {
|
|
762
|
-
const response = operation.responses[status];
|
|
763
|
-
markdown.push(`<details>`);
|
|
764
|
-
markdown.push(
|
|
765
|
-
`<summary><b>${status}</b> <i>${response.description}</i></summary>`
|
|
766
|
-
);
|
|
767
|
-
if (!isEmpty2(response.content)) {
|
|
768
|
-
for (const [contentType, mediaType] of Object.entries(
|
|
769
|
-
response.content
|
|
770
|
-
)) {
|
|
771
|
-
markdown.push(`
|
|
772
|
-
**Content Type:** \`${contentType}\``);
|
|
773
|
-
if (mediaType.schema) {
|
|
774
|
-
const schemaDocs = propEmitter.handle(mediaType.schema);
|
|
775
|
-
markdown.push(...schemaDocs.map((l) => `
|
|
776
|
-
${l}`));
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
markdown.push(`</details>`);
|
|
781
|
-
}
|
|
782
|
-
});
|
|
783
|
-
return markdown.join("\n\n");
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
// packages/spec/dist/lib/operation.js
|
|
787
|
-
import { camelcase as camelcase2 } from "stringcase";
|
|
788
|
-
import { followRef as followRef3, isRef as isRef5 } from "@sdk-it/core/ref.js";
|
|
789
|
-
|
|
790
|
-
// packages/spec/dist/lib/pagination/pagination.js
|
|
791
|
-
import { isRef as isRef4 } from "@sdk-it/core/ref.js";
|
|
792
|
-
import { isEmpty as isEmpty3 } from "@sdk-it/core/utils.js";
|
|
793
|
-
|
|
794
|
-
// packages/spec/dist/lib/pagination/pagination-result.js
|
|
795
|
-
var import_pluralize2 = __toESM(require_pluralize(), 1);
|
|
796
|
-
var PRIMARY_TOP_TIER_KEYWORDS = [
|
|
797
|
-
"data",
|
|
798
|
-
"items",
|
|
799
|
-
"results",
|
|
800
|
-
"value"
|
|
801
|
-
];
|
|
802
|
-
var PRIMARY_OTHER_KEYWORDS = [
|
|
803
|
-
"records",
|
|
804
|
-
"content",
|
|
805
|
-
"list",
|
|
806
|
-
"payload",
|
|
807
|
-
"entities",
|
|
808
|
-
"collection",
|
|
809
|
-
"users",
|
|
810
|
-
"products",
|
|
811
|
-
"orders",
|
|
812
|
-
"bookings",
|
|
813
|
-
"articles",
|
|
814
|
-
"posts",
|
|
815
|
-
"documents",
|
|
816
|
-
"events"
|
|
817
|
-
];
|
|
818
|
-
var SECONDARY_KEYWORDS = ["entries", "rows", "elements"];
|
|
819
|
-
var PLURAL_DEPRIORITIZE_LIST = [
|
|
820
|
-
"status",
|
|
821
|
-
"success",
|
|
822
|
-
"address",
|
|
823
|
-
"details",
|
|
824
|
-
"properties",
|
|
825
|
-
"params",
|
|
826
|
-
"headers",
|
|
827
|
-
"cookies",
|
|
828
|
-
"series",
|
|
829
|
-
"links",
|
|
830
|
-
"meta",
|
|
831
|
-
"metadata",
|
|
832
|
-
"statistics",
|
|
833
|
-
"settings",
|
|
834
|
-
"options",
|
|
835
|
-
"permissions",
|
|
836
|
-
"credentials",
|
|
837
|
-
"diagnostics",
|
|
838
|
-
"warnings",
|
|
839
|
-
"errors",
|
|
840
|
-
"actions",
|
|
841
|
-
"attributes",
|
|
842
|
-
"categories",
|
|
843
|
-
"features",
|
|
844
|
-
"includes",
|
|
845
|
-
"tags"
|
|
846
|
-
];
|
|
847
|
-
var HAS_MORE_PRIMARY_POSITIVE_EXACT = [
|
|
848
|
-
"hasmore",
|
|
849
|
-
"hasnext",
|
|
850
|
-
"hasnextpage",
|
|
851
|
-
"moreitems",
|
|
852
|
-
"moreitemsavailable",
|
|
853
|
-
"nextpage",
|
|
854
|
-
"nextpageexists",
|
|
855
|
-
"nextpageavailable",
|
|
856
|
-
"hasadditionalresults",
|
|
857
|
-
"moreresultsavailable",
|
|
858
|
-
"canloadmore",
|
|
859
|
-
"hasadditional",
|
|
860
|
-
"additionalitems",
|
|
861
|
-
"fetchmore"
|
|
862
|
-
];
|
|
863
|
-
var HAS_MORE_SECONDARY_POSITIVE_EXACT = ["more", "next"];
|
|
864
|
-
var HAS_MORE_PRIMARY_INVERTED_EXACT = [
|
|
865
|
-
"islast",
|
|
866
|
-
"lastpage",
|
|
867
|
-
"endofresults",
|
|
868
|
-
"endoflist",
|
|
869
|
-
"nomoreitems",
|
|
870
|
-
"nomoredata",
|
|
871
|
-
"allitemsloaded",
|
|
872
|
-
"iscomplete",
|
|
873
|
-
"completed"
|
|
874
|
-
];
|
|
875
|
-
var HAS_MORE_POSITIVE_REGEX_PATTERNS2 = [
|
|
876
|
-
"\\bhas_?more\\b",
|
|
877
|
-
"\\bhas_?next\\b",
|
|
878
|
-
// e.g., itemsHasNext, items_has_next
|
|
879
|
-
"\\bmore_?items\\b",
|
|
880
|
-
"\\bnext_?page\\b",
|
|
881
|
-
// e.g., userNextPageFlag
|
|
882
|
-
"\\badditional\\b",
|
|
883
|
-
// e.g., hasAdditionalData, additional_results_exist
|
|
884
|
-
"\\bcontinuation\\b",
|
|
885
|
-
// e.g., continuationAvailable, has_continuation_token
|
|
886
|
-
"\\bmore_?results\\b",
|
|
887
|
-
"\\bpage_?available\\b",
|
|
888
|
-
"\\bnext(?:_?(page))?\\b"
|
|
889
|
-
];
|
|
890
|
-
var COMPILED_HAS_MORE_POSITIVE_REGEXES2 = HAS_MORE_POSITIVE_REGEX_PATTERNS2.map((p) => new RegExp(p, "i"));
|
|
891
|
-
var HAS_MORE_INVERTED_REGEX_PATTERNS2 = [
|
|
892
|
-
"\\bis_?last\\b",
|
|
893
|
-
// e.g., pageIsLast
|
|
894
|
-
"\\blast_?page\\b",
|
|
895
|
-
// e.g., resultsAreLastPage
|
|
896
|
-
"\\bend_?of_?(data|results|list|items|stream)\\b",
|
|
897
|
-
"\\bno_?more_?(items|data|results)?\\b",
|
|
898
|
-
"\\ball_?(items_?)?loaded\\b",
|
|
899
|
-
"\\bis_?complete\\b"
|
|
900
|
-
];
|
|
901
|
-
var COMPILED_HAS_MORE_INVERTED_REGEXES2 = HAS_MORE_INVERTED_REGEX_PATTERNS2.map((p) => new RegExp(p, "i"));
|
|
902
|
-
function getItemsName(properties) {
|
|
903
|
-
const arrayPropertyNames = [];
|
|
904
|
-
for (const propName in properties) {
|
|
905
|
-
if (propName in properties) {
|
|
906
|
-
const propSchema = properties[propName];
|
|
907
|
-
if (propSchema && propSchema.type === "array") {
|
|
908
|
-
arrayPropertyNames.push(propName);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
if (arrayPropertyNames.length === 0) {
|
|
913
|
-
return null;
|
|
914
|
-
}
|
|
915
|
-
if (arrayPropertyNames.length === 1) {
|
|
916
|
-
return arrayPropertyNames[0];
|
|
917
|
-
}
|
|
918
|
-
let bestCandidate = null;
|
|
919
|
-
let candidateRank = Infinity;
|
|
920
|
-
const updateCandidate = (propName, rank) => {
|
|
921
|
-
if (rank < candidateRank) {
|
|
922
|
-
bestCandidate = propName;
|
|
923
|
-
candidateRank = rank;
|
|
924
|
-
}
|
|
925
|
-
};
|
|
926
|
-
for (const propName of arrayPropertyNames) {
|
|
927
|
-
const lowerPropName = propName.toLowerCase();
|
|
928
|
-
if (PRIMARY_TOP_TIER_KEYWORDS.includes(lowerPropName)) {
|
|
929
|
-
updateCandidate(propName, 2);
|
|
930
|
-
continue;
|
|
931
|
-
}
|
|
932
|
-
if (candidateRank > 3 && PRIMARY_OTHER_KEYWORDS.includes(lowerPropName)) {
|
|
933
|
-
updateCandidate(propName, 3);
|
|
934
|
-
continue;
|
|
935
|
-
}
|
|
936
|
-
if (candidateRank > 4 && SECONDARY_KEYWORDS.includes(lowerPropName)) {
|
|
937
|
-
updateCandidate(propName, 4);
|
|
938
|
-
continue;
|
|
939
|
-
}
|
|
940
|
-
if (candidateRank > 5 && import_pluralize2.default.isPlural(propName) && !PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
|
|
941
|
-
updateCandidate(propName, 5);
|
|
942
|
-
continue;
|
|
943
|
-
}
|
|
944
|
-
if (candidateRank > 6 && import_pluralize2.default.isPlural(propName) && PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
|
|
945
|
-
updateCandidate(propName, 6);
|
|
946
|
-
continue;
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
if (bestCandidate) {
|
|
950
|
-
return bestCandidate;
|
|
951
|
-
}
|
|
952
|
-
return arrayPropertyNames[0];
|
|
953
|
-
}
|
|
954
|
-
function guess(properties) {
|
|
955
|
-
const booleanPropertyNames = [];
|
|
956
|
-
for (const propName in properties) {
|
|
957
|
-
if (Object.prototype.hasOwnProperty.call(properties, propName)) {
|
|
958
|
-
const propSchema = properties[propName];
|
|
959
|
-
if (propSchema && propSchema.type === "boolean" || propSchema.type === "integer") {
|
|
960
|
-
booleanPropertyNames.push(propName);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
}
|
|
964
|
-
if (booleanPropertyNames.length === 0) {
|
|
965
|
-
return null;
|
|
966
|
-
}
|
|
967
|
-
if (booleanPropertyNames.length === 1) {
|
|
968
|
-
return booleanPropertyNames[0];
|
|
969
|
-
}
|
|
970
|
-
let bestCandidate = null;
|
|
971
|
-
let candidateRank = Infinity;
|
|
972
|
-
const updateCandidate = (propName, rank) => {
|
|
973
|
-
if (rank < candidateRank) {
|
|
974
|
-
bestCandidate = propName;
|
|
975
|
-
candidateRank = rank;
|
|
976
|
-
}
|
|
977
|
-
};
|
|
978
|
-
for (const propName of booleanPropertyNames) {
|
|
979
|
-
const normalizedForExactMatch = propName.toLowerCase().replace(/[-_]/g, "");
|
|
980
|
-
let currentPropRank = Infinity;
|
|
981
|
-
if (HAS_MORE_PRIMARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {
|
|
982
|
-
currentPropRank = 1;
|
|
983
|
-
} else if (HAS_MORE_SECONDARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {
|
|
984
|
-
currentPropRank = 2;
|
|
985
|
-
} else {
|
|
986
|
-
let foundPositiveRegex = false;
|
|
987
|
-
for (const regex of COMPILED_HAS_MORE_POSITIVE_REGEXES2) {
|
|
988
|
-
if (regex.test(propName)) {
|
|
989
|
-
currentPropRank = 3;
|
|
990
|
-
foundPositiveRegex = true;
|
|
991
|
-
break;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
if (!foundPositiveRegex) {
|
|
995
|
-
if (HAS_MORE_PRIMARY_INVERTED_EXACT.includes(normalizedForExactMatch)) {
|
|
996
|
-
currentPropRank = 4;
|
|
997
|
-
} else {
|
|
998
|
-
for (const regex of COMPILED_HAS_MORE_INVERTED_REGEXES2) {
|
|
999
|
-
if (regex.test(propName)) {
|
|
1000
|
-
currentPropRank = 5;
|
|
1001
|
-
break;
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
updateCandidate(propName, currentPropRank);
|
|
1008
|
-
}
|
|
1009
|
-
return bestCandidate;
|
|
1010
|
-
}
|
|
1011
|
-
function getHasMoreName(properties) {
|
|
1012
|
-
const rootGuess = guess(properties);
|
|
1013
|
-
if (rootGuess) {
|
|
1014
|
-
return rootGuess;
|
|
1015
|
-
}
|
|
1016
|
-
for (const propName in properties) {
|
|
1017
|
-
const propSchema = properties[propName];
|
|
1018
|
-
if (propSchema.type === "object" && propSchema.properties) {
|
|
1019
|
-
const nested = getHasMoreName(propSchema.properties);
|
|
1020
|
-
if (nested) {
|
|
1021
|
-
return propName + "." + nested;
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
return null;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
// packages/spec/dist/lib/pagination/pagination.js
|
|
1029
|
-
var OFFSET_PARAM_REGEXES = [
|
|
1030
|
-
/\boffset\b/i,
|
|
1031
|
-
/\bskip\b/i,
|
|
1032
|
-
/\bstart(?:ing_at|_index)?\b/i,
|
|
1033
|
-
// e.g., start, starting_at, start_index
|
|
1034
|
-
/\bfrom\b/i
|
|
1035
|
-
];
|
|
1036
|
-
var GENERIC_LIMIT_PARAM_REGEXES = [
|
|
1037
|
-
/\blimit\b/i,
|
|
1038
|
-
/\bcount\b/i,
|
|
1039
|
-
/\b(?:page_?)?size\b/i,
|
|
1040
|
-
// e.g., size, page_size, pagesize
|
|
1041
|
-
/\bmax_results\b/i,
|
|
1042
|
-
/\bnum_results\b/i,
|
|
1043
|
-
/\bshow\b/i,
|
|
1044
|
-
// Can sometimes mean limit
|
|
1045
|
-
/\bper_?page\b/i,
|
|
1046
|
-
// e.g., per_page, perpage
|
|
1047
|
-
/\bper-page\b/i,
|
|
1048
|
-
/\btake\b/i
|
|
1049
|
-
];
|
|
1050
|
-
var PAGE_NUMBER_REGEXES = [
|
|
1051
|
-
/^page$/i,
|
|
1052
|
-
// Exact match for "page"
|
|
1053
|
-
/^p$/i,
|
|
1054
|
-
// Exact match for "p" (common shorthand)
|
|
1055
|
-
/\bpage_?(?:number|num|idx|index)\b/i
|
|
1056
|
-
// e.g., page_number, pageNumber, page_num, page_idx
|
|
1057
|
-
];
|
|
1058
|
-
var PAGE_SIZE_REGEXES = [
|
|
1059
|
-
/\bpage_?size\b/i,
|
|
1060
|
-
// e.g., page_size, pagesize
|
|
1061
|
-
/^size$/i,
|
|
1062
|
-
// Exact "size"
|
|
1063
|
-
// /\bsize\b/i, // Broader "size" - can be ambiguous, prefer more specific ones first
|
|
1064
|
-
/\blimit\b/i,
|
|
1065
|
-
// Limit is often used for page size
|
|
1066
|
-
/\bcount\b/i,
|
|
1067
|
-
// Count can also be used for page size
|
|
1068
|
-
/\bper_?page\b/i,
|
|
1069
|
-
// e.g., per_page, perpage
|
|
1070
|
-
/\bper-page\b/i,
|
|
1071
|
-
/\bnum_?(?:items|records|results)\b/i,
|
|
1072
|
-
// e.g., num_items, numitems
|
|
1073
|
-
/\bresults_?per_?page\b/i
|
|
1074
|
-
];
|
|
1075
|
-
var CURSOR_REGEXES = [
|
|
1076
|
-
/\bcursor\b/i,
|
|
1077
|
-
/\bafter(?:_?cursor)?\b/i,
|
|
1078
|
-
// e.g., after, after_cursor
|
|
1079
|
-
/\bbefore(?:_?cursor)?\b/i,
|
|
1080
|
-
// e.g., before, before_cursor
|
|
1081
|
-
/\b(next|prev|previous)_?(?:page_?)?token\b/i,
|
|
1082
|
-
// e.g., next_page_token, nextPageToken, prev_token
|
|
1083
|
-
/\b(next|prev|previous)_?cursor\b/i,
|
|
1084
|
-
// e.g., next_cursor, previousCursor
|
|
1085
|
-
/\bcontinuation(?:_?token)?\b/i,
|
|
1086
|
-
// e.g., continuation, continuation_token
|
|
1087
|
-
/\bpage(?:_?(token|id))?\b/i,
|
|
1088
|
-
// e.g., after, after_cursor
|
|
1089
|
-
/\bstart_?(?:key|cursor|token|after)\b/i
|
|
1090
|
-
// e.g., start_key, startCursor, startToken, startAfter
|
|
1091
|
-
];
|
|
1092
|
-
var CURSOR_LIMIT_REGEXES = [
|
|
1093
|
-
/\blimit\b/i,
|
|
1094
|
-
/\bcount\b/i,
|
|
1095
|
-
/\bsize\b/i,
|
|
1096
|
-
// General size
|
|
1097
|
-
/\bfirst\b/i,
|
|
1098
|
-
// Common in Relay-style cursor pagination (forward pagination)
|
|
1099
|
-
/\blast\b/i,
|
|
1100
|
-
// Common in Relay-style cursor pagination (backward pagination)
|
|
1101
|
-
/\bpage_?size\b/i,
|
|
1102
|
-
// Sometimes page_size is used with cursors
|
|
1103
|
-
/\bnum_?(?:items|records|results)\b/i,
|
|
1104
|
-
// e.g., num_items
|
|
1105
|
-
/\bmax_?items\b/i,
|
|
1106
|
-
/\btake\b/i
|
|
1107
|
-
];
|
|
1108
|
-
function findParamAndKeyword(queryParams, regexes, excludeParamName) {
|
|
1109
|
-
for (const param of queryParams) {
|
|
1110
|
-
if (param.name === excludeParamName) {
|
|
1111
|
-
continue;
|
|
1112
|
-
}
|
|
1113
|
-
for (const regex of regexes) {
|
|
1114
|
-
const match = param.name.match(regex);
|
|
1115
|
-
if (match) {
|
|
1116
|
-
return { param, keyword: match[0] };
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
return null;
|
|
1121
|
-
}
|
|
1122
|
-
function isOffsetPagination(operation, parameters) {
|
|
1123
|
-
const offsetMatch = findParamAndKeyword(parameters, OFFSET_PARAM_REGEXES);
|
|
1124
|
-
if (!offsetMatch)
|
|
1125
|
-
return null;
|
|
1126
|
-
const limitMatch = findParamAndKeyword(
|
|
1127
|
-
parameters,
|
|
1128
|
-
GENERIC_LIMIT_PARAM_REGEXES,
|
|
1129
|
-
offsetMatch.param.name
|
|
1130
|
-
);
|
|
1131
|
-
if (!limitMatch)
|
|
1132
|
-
return null;
|
|
1133
|
-
return {
|
|
1134
|
-
type: "offset",
|
|
1135
|
-
offsetParamName: offsetMatch.param.name,
|
|
1136
|
-
offsetKeyword: offsetMatch.keyword,
|
|
1137
|
-
limitParamName: limitMatch.param.name,
|
|
1138
|
-
limitKeyword: limitMatch.keyword
|
|
1139
|
-
};
|
|
1140
|
-
}
|
|
1141
|
-
function isPagePagination(operation) {
|
|
1142
|
-
const queryParams = operation.parameters.filter((p) => p.in === "query").filter(
|
|
1143
|
-
(it) => it.schema && !isRef4(it.schema) && it.schema.type === "integer"
|
|
1144
|
-
);
|
|
1145
|
-
if (queryParams.length < 2)
|
|
1146
|
-
return null;
|
|
1147
|
-
const pageNoMatch = findParamAndKeyword(queryParams, PAGE_NUMBER_REGEXES);
|
|
1148
|
-
if (!pageNoMatch)
|
|
1149
|
-
return null;
|
|
1150
|
-
const pageSizeMatch = findParamAndKeyword(
|
|
1151
|
-
queryParams,
|
|
1152
|
-
PAGE_SIZE_REGEXES,
|
|
1153
|
-
pageNoMatch.param.name
|
|
1154
|
-
);
|
|
1155
|
-
if (!pageSizeMatch)
|
|
1156
|
-
return null;
|
|
1157
|
-
return {
|
|
1158
|
-
type: "page",
|
|
1159
|
-
pageNumberParamName: pageNoMatch.param.name,
|
|
1160
|
-
pageNumberKeyword: pageNoMatch.keyword,
|
|
1161
|
-
pageSizeParamName: pageSizeMatch.param.name,
|
|
1162
|
-
pageSizeKeyword: pageSizeMatch.keyword
|
|
1163
|
-
};
|
|
1164
|
-
}
|
|
1165
|
-
function isCursorPagination(operation) {
|
|
1166
|
-
const queryParams = operation.parameters.filter((p) => p.in === "query");
|
|
1167
|
-
if (queryParams.length < 2)
|
|
1168
|
-
return null;
|
|
1169
|
-
const cursorMatch = findParamAndKeyword(queryParams, CURSOR_REGEXES);
|
|
1170
|
-
if (!cursorMatch)
|
|
1171
|
-
return null;
|
|
1172
|
-
const limitMatch = findParamAndKeyword(
|
|
1173
|
-
queryParams,
|
|
1174
|
-
CURSOR_LIMIT_REGEXES,
|
|
1175
|
-
cursorMatch.param.name
|
|
1176
|
-
);
|
|
1177
|
-
if (!limitMatch)
|
|
1178
|
-
return null;
|
|
1179
|
-
return {
|
|
1180
|
-
type: "cursor",
|
|
1181
|
-
cursorParamName: cursorMatch.param.name,
|
|
1182
|
-
cursorKeyword: cursorMatch.keyword,
|
|
1183
|
-
limitParamName: limitMatch.param.name,
|
|
1184
|
-
limitKeyword: limitMatch.keyword
|
|
1185
|
-
};
|
|
1186
|
-
}
|
|
1187
|
-
function guessPagination(operation, body, response) {
|
|
1188
|
-
const bodyParameters = body && body.properties ? Object.keys(body.properties).map((it) => ({ name: it })) : [];
|
|
1189
|
-
const parameters = operation.parameters;
|
|
1190
|
-
if (isEmpty3(operation.parameters) && isEmpty3(bodyParameters)) {
|
|
1191
|
-
return { type: "none", reason: "no parameters" };
|
|
1192
|
-
}
|
|
1193
|
-
if (!response) {
|
|
1194
|
-
return { type: "none", reason: "no response" };
|
|
1195
|
-
}
|
|
1196
|
-
if (!response.properties) {
|
|
1197
|
-
return { type: "none", reason: "empty response" };
|
|
1198
|
-
}
|
|
1199
|
-
const properties = response.properties;
|
|
1200
|
-
const itemsKey = getItemsName(properties);
|
|
1201
|
-
if (!itemsKey) {
|
|
1202
|
-
return { type: "none", reason: "no items key" };
|
|
1203
|
-
}
|
|
1204
|
-
const hasMoreKey = getHasMoreName(excludeKey(properties, itemsKey));
|
|
1205
|
-
if (!hasMoreKey) {
|
|
1206
|
-
return { type: "none", reason: "no hasMore key" };
|
|
1207
|
-
}
|
|
1208
|
-
const pagination = isOffsetPagination(operation, [...parameters, ...bodyParameters]) || isPagePagination(operation) || isCursorPagination(operation);
|
|
1209
|
-
return pagination ? { ...pagination, items: itemsKey, hasMore: hasMoreKey } : { type: "none", reason: "no pagination" };
|
|
1210
|
-
}
|
|
1211
|
-
function excludeKey(obj, key) {
|
|
1212
|
-
const { [key]: _, ...rest } = obj;
|
|
1213
|
-
return rest;
|
|
1214
|
-
}
|
|
1215
|
-
|
|
1216
|
-
// packages/spec/dist/lib/operation.js
|
|
1217
|
-
function augmentSpec(config) {
|
|
1218
|
-
config.spec.paths ??= {};
|
|
1219
|
-
const paths = {};
|
|
1220
|
-
for (const [path, pathItem] of Object.entries(config.spec.paths)) {
|
|
1221
|
-
const { parameters = [], ...methods2 } = pathItem;
|
|
1222
|
-
const fixedPath = path.replace(/:([^/]+)/g, "{$1}");
|
|
1223
|
-
for (const [method, operation] of Object.entries(methods2)) {
|
|
1224
|
-
const formatOperationId = config.operationId ?? defaults.operationId;
|
|
1225
|
-
const formatTag = config.tag ?? defaults.tag;
|
|
1226
|
-
const operationId = formatOperationId(operation, fixedPath, method);
|
|
1227
|
-
const operationTag = formatTag(operation, fixedPath);
|
|
1228
|
-
const requestBody = isRef5(operation.requestBody) ? followRef3(config.spec, operation.requestBody.$ref) : operation.requestBody;
|
|
1229
|
-
const tunedOperation = {
|
|
1230
|
-
...operation,
|
|
1231
|
-
parameters: [...parameters, ...operation.parameters ?? []].map(
|
|
1232
|
-
(it) => isRef5(it) ? followRef3(config.spec, it.$ref) : it
|
|
1233
|
-
),
|
|
1234
|
-
tags: [operationTag],
|
|
1235
|
-
operationId,
|
|
1236
|
-
responses: resolveResponses(config.spec, operation),
|
|
1237
|
-
requestBody
|
|
1238
|
-
};
|
|
1239
|
-
tunedOperation["x-pagination"] = toPagination(
|
|
1240
|
-
config.spec,
|
|
1241
|
-
tunedOperation
|
|
1242
|
-
);
|
|
1243
|
-
Object.assign(paths, {
|
|
1244
|
-
[fixedPath]: {
|
|
1245
|
-
...paths[fixedPath],
|
|
1246
|
-
[method]: tunedOperation
|
|
1247
|
-
}
|
|
1248
|
-
});
|
|
1249
|
-
}
|
|
1250
|
-
}
|
|
1251
|
-
return { ...config.spec, paths };
|
|
1252
|
-
}
|
|
1253
|
-
function toPagination(spec, tunedOperation) {
|
|
1254
|
-
if (tunedOperation["x-pagination"]) {
|
|
1255
|
-
return tunedOperation["x-pagination"];
|
|
1256
|
-
}
|
|
1257
|
-
const schema = getResponseContentSchema(
|
|
1258
|
-
spec,
|
|
1259
|
-
tunedOperation.responses["200"],
|
|
1260
|
-
"application/json"
|
|
1261
|
-
);
|
|
1262
|
-
const pagination = guessPagination(
|
|
1263
|
-
tunedOperation,
|
|
1264
|
-
tunedOperation.requestBody ? getRequestContentSchema(
|
|
1265
|
-
spec,
|
|
1266
|
-
tunedOperation.requestBody,
|
|
1267
|
-
"application/json"
|
|
1268
|
-
) : void 0,
|
|
1269
|
-
schema
|
|
1270
|
-
);
|
|
1271
|
-
if (pagination && pagination.type !== "none" && schema) {
|
|
1272
|
-
return pagination;
|
|
1273
|
-
}
|
|
1274
|
-
return void 0;
|
|
1275
|
-
}
|
|
1276
|
-
function getResponseContentSchema(spec, response, type) {
|
|
1277
|
-
if (!response) {
|
|
1278
|
-
return void 0;
|
|
1279
|
-
}
|
|
1280
|
-
const content = response.content;
|
|
1281
|
-
if (!content) {
|
|
1282
|
-
return void 0;
|
|
1283
|
-
}
|
|
1284
|
-
for (const contentType in content) {
|
|
1285
|
-
if (contentType.toLowerCase() === type.toLowerCase()) {
|
|
1286
|
-
return isRef5(content[contentType].schema) ? followRef3(spec, content[contentType].schema.$ref) : content[contentType].schema;
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
return void 0;
|
|
1290
|
-
}
|
|
1291
|
-
function getRequestContentSchema(spec, requestBody, type) {
|
|
1292
|
-
const content = requestBody.content;
|
|
1293
|
-
if (!content) {
|
|
1294
|
-
return void 0;
|
|
1295
|
-
}
|
|
1296
|
-
for (const contentType in content) {
|
|
1297
|
-
if (contentType.toLowerCase() === type.toLowerCase()) {
|
|
1298
|
-
return isRef5(content[contentType].schema) ? followRef3(spec, content[contentType].schema.$ref) : content[contentType].schema;
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
return void 0;
|
|
1302
|
-
}
|
|
1303
|
-
var defaults = {
|
|
1304
|
-
operationId: (operation, path, method) => {
|
|
1305
|
-
if (operation.operationId) {
|
|
1306
|
-
return camelcase2(operation.operationId);
|
|
1307
|
-
}
|
|
1308
|
-
const metadata = operation["x-oaiMeta"];
|
|
1309
|
-
if (metadata && metadata.name) {
|
|
1310
|
-
return camelcase2(metadata.name);
|
|
1311
|
-
}
|
|
1312
|
-
return camelcase2(
|
|
1313
|
-
[method, ...path.replace(/[\\/\\{\\}]/g, " ").split(" ")].filter(Boolean).join(" ").trim()
|
|
1314
|
-
);
|
|
1315
|
-
},
|
|
1316
|
-
tag: (operation, path) => {
|
|
1317
|
-
return operation.tags?.[0] ? sanitizeTag(operation.tags?.[0]) : determineGenericTag(path, operation);
|
|
1318
|
-
}
|
|
1319
|
-
};
|
|
1320
|
-
function resolveResponses(spec, operation) {
|
|
1321
|
-
const responses = operation.responses ?? {};
|
|
1322
|
-
const resolved = {};
|
|
1323
|
-
for (const status in responses) {
|
|
1324
|
-
const response = isRef5(responses[status]) ? followRef3(spec, responses[status].$ref) : responses[status];
|
|
1325
|
-
resolved[status] = response;
|
|
1326
|
-
}
|
|
1327
|
-
return resolved;
|
|
1328
|
-
}
|
|
1329
|
-
function forEachOperation2(config, callback) {
|
|
1330
|
-
const result = [];
|
|
1331
|
-
for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {
|
|
1332
|
-
const { parameters = [], ...methods2 } = pathItem;
|
|
1333
|
-
for (const [method, operation] of Object.entries(methods2)) {
|
|
1334
|
-
const metadata = operation["x-oaiMeta"] ?? {};
|
|
1335
|
-
const operationTag = operation.tags?.[0];
|
|
1336
|
-
result.push(
|
|
1337
|
-
callback(
|
|
1338
|
-
{
|
|
1339
|
-
name: metadata.name,
|
|
1340
|
-
method,
|
|
1341
|
-
path,
|
|
1342
|
-
groupName: operationTag,
|
|
1343
|
-
tag: operationTag
|
|
1344
|
-
},
|
|
1345
|
-
operation
|
|
1346
|
-
)
|
|
1347
|
-
);
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
return result;
|
|
1351
|
-
}
|
|
1352
|
-
var reservedKeywords = /* @__PURE__ */ new Set([
|
|
1353
|
-
"await",
|
|
1354
|
-
// Reserved in async functions
|
|
1355
|
-
"break",
|
|
1356
|
-
"case",
|
|
1357
|
-
"catch",
|
|
1358
|
-
"class",
|
|
1359
|
-
"const",
|
|
1360
|
-
"continue",
|
|
1361
|
-
"debugger",
|
|
1362
|
-
"default",
|
|
1363
|
-
"delete",
|
|
1364
|
-
"do",
|
|
1365
|
-
"else",
|
|
1366
|
-
"enum",
|
|
1367
|
-
"export",
|
|
1368
|
-
"extends",
|
|
1369
|
-
"false",
|
|
1370
|
-
"finally",
|
|
1371
|
-
"for",
|
|
1372
|
-
"function",
|
|
1373
|
-
"if",
|
|
1374
|
-
"implements",
|
|
1375
|
-
// Strict mode
|
|
1376
|
-
"import",
|
|
1377
|
-
"in",
|
|
1378
|
-
"instanceof",
|
|
1379
|
-
"interface",
|
|
1380
|
-
// Strict mode
|
|
1381
|
-
"let",
|
|
1382
|
-
// Strict mode
|
|
1383
|
-
"new",
|
|
1384
|
-
"null",
|
|
1385
|
-
"package",
|
|
1386
|
-
// Strict mode
|
|
1387
|
-
"private",
|
|
1388
|
-
// Strict mode
|
|
1389
|
-
"protected",
|
|
1390
|
-
// Strict mode
|
|
1391
|
-
"public",
|
|
1392
|
-
// Strict mode
|
|
1393
|
-
"return",
|
|
1394
|
-
"static",
|
|
1395
|
-
// Strict mode
|
|
1396
|
-
"super",
|
|
1397
|
-
"switch",
|
|
1398
|
-
"this",
|
|
1399
|
-
"throw",
|
|
1400
|
-
"true",
|
|
1401
|
-
"try",
|
|
1402
|
-
"typeof",
|
|
1403
|
-
"var",
|
|
1404
|
-
"void",
|
|
1405
|
-
"while",
|
|
1406
|
-
"with",
|
|
1407
|
-
"yield",
|
|
1408
|
-
// Strict mode / Generator functions
|
|
1409
|
-
// 'arguments' is not technically a reserved word, but it's a special identifier within functions
|
|
1410
|
-
// and assigning to it or declaring it can cause issues or unexpected behavior.
|
|
1411
|
-
"arguments"
|
|
1412
|
-
]);
|
|
1413
|
-
function sanitizeTag(camelCasedTag) {
|
|
1414
|
-
if (/^\d/.test(camelCasedTag)) {
|
|
1415
|
-
return `_${camelCasedTag}`;
|
|
1416
|
-
}
|
|
1417
|
-
return reservedKeywords.has(camelcase2(camelCasedTag)) ? `${camelCasedTag}_` : camelCasedTag;
|
|
1418
|
-
}
|
|
1419
|
-
function determineGenericTag(pathString, operation) {
|
|
1420
|
-
const operationId = operation.operationId || "";
|
|
1421
|
-
const VERSION_REGEX = /^[vV]\d+$/;
|
|
1422
|
-
const commonVerbs = /* @__PURE__ */ new Set([
|
|
1423
|
-
// Verbs to potentially strip from operationId prefix
|
|
1424
|
-
"get",
|
|
1425
|
-
"list",
|
|
1426
|
-
"create",
|
|
1427
|
-
"update",
|
|
1428
|
-
"delete",
|
|
1429
|
-
"post",
|
|
1430
|
-
"put",
|
|
1431
|
-
"patch",
|
|
1432
|
-
"do",
|
|
1433
|
-
"send",
|
|
1434
|
-
"add",
|
|
1435
|
-
"remove",
|
|
1436
|
-
"set",
|
|
1437
|
-
"find",
|
|
1438
|
-
"search",
|
|
1439
|
-
"check",
|
|
1440
|
-
"make"
|
|
1441
|
-
]);
|
|
1442
|
-
const segments = pathString.split("/").filter(Boolean);
|
|
1443
|
-
const potentialCandidates = segments.filter(
|
|
1444
|
-
(segment) => segment && !segment.startsWith("{") && !segment.endsWith("}") && !VERSION_REGEX.test(segment)
|
|
1445
|
-
);
|
|
1446
|
-
for (let i = potentialCandidates.length - 1; i >= 0; i--) {
|
|
1447
|
-
const segment = potentialCandidates[i];
|
|
1448
|
-
if (!segment.startsWith("@")) {
|
|
1449
|
-
return sanitizeTag(camelcase2(segment));
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
const canFallbackToPathSegment = potentialCandidates.length > 0;
|
|
1453
|
-
if (operationId) {
|
|
1454
|
-
const lowerOpId = operationId.toLowerCase();
|
|
1455
|
-
const parts = operationId.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").replace(/([a-zA-Z])(\d)/g, "$1_$2").replace(/(\d)([a-zA-Z])/g, "$1_$2").toLowerCase().split(/[_-\s]+/);
|
|
1456
|
-
const validParts = parts.filter(Boolean);
|
|
1457
|
-
if (commonVerbs.has(lowerOpId) && validParts.length === 1 && canFallbackToPathSegment) {
|
|
1458
|
-
} else if (validParts.length > 0) {
|
|
1459
|
-
const firstPart = validParts[0];
|
|
1460
|
-
const isFirstPartVerb = commonVerbs.has(firstPart);
|
|
1461
|
-
if (isFirstPartVerb && validParts.length > 1) {
|
|
1462
|
-
const verbPrefixLength = firstPart.length;
|
|
1463
|
-
let nextPartStartIndex = -1;
|
|
1464
|
-
if (operationId.length > verbPrefixLength) {
|
|
1465
|
-
const charAfterPrefix = operationId[verbPrefixLength];
|
|
1466
|
-
if (charAfterPrefix >= "A" && charAfterPrefix <= "Z") {
|
|
1467
|
-
nextPartStartIndex = verbPrefixLength;
|
|
1468
|
-
} else if (charAfterPrefix >= "0" && charAfterPrefix <= "9") {
|
|
1469
|
-
nextPartStartIndex = verbPrefixLength;
|
|
1470
|
-
} else if (["_", "-"].includes(charAfterPrefix)) {
|
|
1471
|
-
nextPartStartIndex = verbPrefixLength + 1;
|
|
1472
|
-
} else {
|
|
1473
|
-
const match = operationId.substring(verbPrefixLength).match(/[A-Z0-9]/);
|
|
1474
|
-
if (match && match.index !== void 0) {
|
|
1475
|
-
nextPartStartIndex = verbPrefixLength + match.index;
|
|
1476
|
-
}
|
|
1477
|
-
if (nextPartStartIndex === -1 && operationId.length > verbPrefixLength) {
|
|
1478
|
-
nextPartStartIndex = verbPrefixLength;
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
if (nextPartStartIndex !== -1 && nextPartStartIndex < operationId.length) {
|
|
1483
|
-
const remainingOriginalSubstring = operationId.substring(nextPartStartIndex);
|
|
1484
|
-
const potentialTag = camelcase2(remainingOriginalSubstring);
|
|
1485
|
-
if (potentialTag) {
|
|
1486
|
-
return sanitizeTag(potentialTag);
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
const potentialTagJoined = camelcase2(validParts.slice(1).join("_"));
|
|
1490
|
-
if (potentialTagJoined) {
|
|
1491
|
-
return sanitizeTag(potentialTagJoined);
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
const potentialTagFull = camelcase2(operationId);
|
|
1495
|
-
if (potentialTagFull) {
|
|
1496
|
-
const isResultSingleVerb = validParts.length === 1 && isFirstPartVerb;
|
|
1497
|
-
if (!(isResultSingleVerb && canFallbackToPathSegment)) {
|
|
1498
|
-
if (potentialTagFull.length > 0) {
|
|
1499
|
-
return sanitizeTag(potentialTagFull);
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1503
|
-
const firstPartCamel = camelcase2(firstPart);
|
|
1504
|
-
if (firstPartCamel) {
|
|
1505
|
-
const isFirstPartCamelVerb = commonVerbs.has(firstPartCamel);
|
|
1506
|
-
if (!isFirstPartCamelVerb || validParts.length === 1 || !canFallbackToPathSegment) {
|
|
1507
|
-
return sanitizeTag(firstPartCamel);
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
if (isFirstPartVerb && validParts.length > 1 && validParts[1] && canFallbackToPathSegment) {
|
|
1511
|
-
const secondPartCamel = camelcase2(validParts[1]);
|
|
1512
|
-
if (secondPartCamel) {
|
|
1513
|
-
return sanitizeTag(secondPartCamel);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
if (potentialCandidates.length > 0) {
|
|
1519
|
-
let firstCandidate = potentialCandidates[0];
|
|
1520
|
-
if (firstCandidate.startsWith("@")) {
|
|
1521
|
-
firstCandidate = firstCandidate.substring(1);
|
|
1522
|
-
}
|
|
1523
|
-
if (firstCandidate) {
|
|
1524
|
-
return sanitizeTag(camelcase2(firstCandidate));
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
console.warn(
|
|
1528
|
-
`Could not determine a suitable tag for path: ${pathString}, operationId: ${operationId}. Using 'unknown'.`
|
|
1529
|
-
);
|
|
1530
|
-
return "unknown";
|
|
1531
|
-
}
|
|
1532
|
-
function patchParameters(spec, objectSchema, operation) {
|
|
1533
|
-
const securitySchemes = spec.components?.securitySchemes ?? {};
|
|
1534
|
-
const securityOptions = securityToOptions(
|
|
1535
|
-
spec,
|
|
1536
|
-
operation.security ?? [],
|
|
1537
|
-
securitySchemes
|
|
1538
|
-
);
|
|
1539
|
-
objectSchema.properties ??= {};
|
|
1540
|
-
objectSchema.required ??= [];
|
|
1541
|
-
for (const param of operation.parameters) {
|
|
1542
|
-
if (param.required) {
|
|
1543
|
-
objectSchema.required.push(param.name);
|
|
1544
|
-
}
|
|
1545
|
-
objectSchema.properties[param.name] = isRef5(param.schema) ? followRef3(spec, param.schema.$ref) : param.schema ?? { type: "string" };
|
|
1546
|
-
}
|
|
1547
|
-
for (const param of securityOptions) {
|
|
1548
|
-
objectSchema.required = (objectSchema.required ?? []).filter(
|
|
1549
|
-
(name) => name !== param.name
|
|
1550
|
-
);
|
|
1551
|
-
objectSchema.properties[param.name] = isRef5(param.schema) ? followRef3(spec, param.schema.$ref) : param.schema ?? { type: "string" };
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
function securityToOptions(spec, security2, securitySchemes, staticIn) {
|
|
1555
|
-
securitySchemes ??= {};
|
|
1556
|
-
const parameters = [];
|
|
1557
|
-
for (const it of security2) {
|
|
1558
|
-
const [name] = Object.keys(it);
|
|
1559
|
-
if (!name) {
|
|
1560
|
-
continue;
|
|
1561
|
-
}
|
|
1562
|
-
const schema = isRef5(securitySchemes[name]) ? followRef3(spec, securitySchemes[name].$ref) : securitySchemes[name];
|
|
1563
|
-
if (schema.type === "http") {
|
|
1564
|
-
parameters.push({
|
|
1565
|
-
in: staticIn ?? "header",
|
|
1566
|
-
name: "authorization",
|
|
1567
|
-
schema: { type: "string" }
|
|
1568
|
-
});
|
|
1569
|
-
continue;
|
|
1570
|
-
}
|
|
1571
|
-
if (schema.type === "apiKey") {
|
|
1572
|
-
if (!schema.in) {
|
|
1573
|
-
throw new Error(`apiKey security schema must have an "in" field`);
|
|
1574
|
-
}
|
|
1575
|
-
if (!schema.name) {
|
|
1576
|
-
throw new Error(`apiKey security schema must have a "name" field`);
|
|
1577
|
-
}
|
|
1578
|
-
parameters.push({
|
|
1579
|
-
in: staticIn ?? schema.in,
|
|
1580
|
-
name: schema.name,
|
|
1581
|
-
schema: { type: "string" }
|
|
1582
|
-
});
|
|
1583
|
-
continue;
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
return parameters;
|
|
1587
|
-
}
|
|
13
|
+
import { toReadme } from "@sdk-it/readme";
|
|
14
|
+
import {
|
|
15
|
+
augmentSpec,
|
|
16
|
+
cleanFiles,
|
|
17
|
+
readWriteMetadata,
|
|
18
|
+
sanitizeTag as sanitizeTag4
|
|
19
|
+
} from "@sdk-it/spec";
|
|
1588
20
|
|
|
1589
21
|
// packages/typescript/src/lib/client.ts
|
|
1590
22
|
import { toLitObject } from "@sdk-it/core";
|
|
@@ -1709,19 +141,188 @@ export class ${spec.name} {
|
|
|
1709
141
|
}
|
|
1710
142
|
}
|
|
1711
143
|
}
|
|
1712
|
-
}`;
|
|
144
|
+
}`;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// packages/typescript/src/lib/emitters/interface.ts
|
|
148
|
+
import { followRef, isRef, parseRef, pascalcase } from "@sdk-it/core";
|
|
149
|
+
import { isPrimitiveSchema, sanitizeTag } from "@sdk-it/spec";
|
|
150
|
+
var TypeScriptEmitter = class {
|
|
151
|
+
#spec;
|
|
152
|
+
constructor(spec) {
|
|
153
|
+
this.#spec = spec;
|
|
154
|
+
}
|
|
155
|
+
#stringifyKey = (value) => {
|
|
156
|
+
return `'${value}'`;
|
|
157
|
+
};
|
|
158
|
+
object(schema, required = false) {
|
|
159
|
+
const properties = schema.properties || {};
|
|
160
|
+
const propEntries = Object.entries(properties).map(([key, propSchema]) => {
|
|
161
|
+
const isRequired = (schema.required ?? []).includes(key);
|
|
162
|
+
const tsType = this.handle(propSchema, isRequired);
|
|
163
|
+
return `${this.#stringifyKey(key)}: ${tsType}`;
|
|
164
|
+
});
|
|
165
|
+
if (schema.additionalProperties) {
|
|
166
|
+
if (typeof schema.additionalProperties === "object") {
|
|
167
|
+
const indexType = this.handle(schema.additionalProperties, true);
|
|
168
|
+
propEntries.push(`[key: string]: ${indexType}`);
|
|
169
|
+
} else if (schema.additionalProperties === true) {
|
|
170
|
+
propEntries.push("[key: string]: any");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return `${propEntries.length ? `{ ${propEntries.join("; ")} }` : "unknown"}`;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Handle arrays (items could be a single schema or a tuple)
|
|
177
|
+
*/
|
|
178
|
+
#array(schema, required = false) {
|
|
179
|
+
const { items } = schema;
|
|
180
|
+
if (!items) {
|
|
181
|
+
return "any[]";
|
|
182
|
+
}
|
|
183
|
+
if (Array.isArray(items)) {
|
|
184
|
+
const tupleItems = items.map((sub) => this.handle(sub, true));
|
|
185
|
+
return `[${tupleItems.join(", ")}]`;
|
|
186
|
+
}
|
|
187
|
+
const itemsType = this.handle(items, true);
|
|
188
|
+
return itemsType.length > 1 ? `(${itemsType})[]` : `${itemsType}[]`;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Convert a basic type (string | number | boolean | object | array, etc.) to TypeScript
|
|
192
|
+
*/
|
|
193
|
+
normal(type, schema, required = false) {
|
|
194
|
+
switch (type) {
|
|
195
|
+
case "string":
|
|
196
|
+
return this.string(schema, required);
|
|
197
|
+
case "number":
|
|
198
|
+
case "integer":
|
|
199
|
+
return this.number(schema, required);
|
|
200
|
+
case "boolean":
|
|
201
|
+
return appendOptional("boolean", required);
|
|
202
|
+
case "object":
|
|
203
|
+
return this.object(schema, required);
|
|
204
|
+
case "array":
|
|
205
|
+
return this.#array(schema, required);
|
|
206
|
+
case "null":
|
|
207
|
+
return "null";
|
|
208
|
+
default:
|
|
209
|
+
console.warn(`Unknown type: ${type}`);
|
|
210
|
+
return appendOptional("any", required);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
#ref($ref, required) {
|
|
214
|
+
const schemaName = pascalcase(sanitizeTag(parseRef($ref).model));
|
|
215
|
+
const schema = followRef(this.#spec, $ref);
|
|
216
|
+
if (isPrimitiveSchema(schema)) {
|
|
217
|
+
return this.handle(schema, required);
|
|
218
|
+
}
|
|
219
|
+
return `models.${appendOptional(schemaName, required)}`;
|
|
220
|
+
}
|
|
221
|
+
allOf(schemas) {
|
|
222
|
+
const allOfTypes = schemas.map((sub) => this.handle(sub, true));
|
|
223
|
+
return allOfTypes.length > 1 ? `${allOfTypes.join(" & ")}` : allOfTypes[0];
|
|
224
|
+
}
|
|
225
|
+
oneOf(schemas, required) {
|
|
226
|
+
const oneOfTypes = schemas.map((sub) => this.handle(sub, true));
|
|
227
|
+
return appendOptional(
|
|
228
|
+
oneOfTypes.length > 1 ? `${oneOfTypes.join(" | ")}` : oneOfTypes[0],
|
|
229
|
+
required
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
anyOf(schemas, required) {
|
|
233
|
+
return this.oneOf(schemas, required);
|
|
234
|
+
}
|
|
235
|
+
enum(values, required) {
|
|
236
|
+
const enumValues = values.map((val) => typeof val === "string" ? `'${val}'` : `${val}`).join(" | ");
|
|
237
|
+
return appendOptional(enumValues, required);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Handle string type with formats
|
|
241
|
+
*/
|
|
242
|
+
string(schema, required) {
|
|
243
|
+
let type;
|
|
244
|
+
if (schema.contentEncoding === "binary") {
|
|
245
|
+
return appendOptional("Blob", required);
|
|
246
|
+
}
|
|
247
|
+
switch (schema.format) {
|
|
248
|
+
case "date-time":
|
|
249
|
+
case "datetime":
|
|
250
|
+
case "date":
|
|
251
|
+
type = "Date";
|
|
252
|
+
break;
|
|
253
|
+
case "binary":
|
|
254
|
+
case "byte":
|
|
255
|
+
type = "Blob";
|
|
256
|
+
break;
|
|
257
|
+
case "int64":
|
|
258
|
+
type = "bigint";
|
|
259
|
+
break;
|
|
260
|
+
default:
|
|
261
|
+
type = "string";
|
|
262
|
+
}
|
|
263
|
+
return appendOptional(type, required);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Handle number/integer types with formats
|
|
267
|
+
*/
|
|
268
|
+
number(schema, required) {
|
|
269
|
+
const type = schema.format === "int64" ? "bigint" : "number";
|
|
270
|
+
return appendOptional(type, required);
|
|
271
|
+
}
|
|
272
|
+
handle(schema, required) {
|
|
273
|
+
if (isRef(schema)) {
|
|
274
|
+
return this.#ref(schema.$ref, required);
|
|
275
|
+
}
|
|
276
|
+
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
277
|
+
return this.allOf(schema.allOf);
|
|
278
|
+
}
|
|
279
|
+
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
280
|
+
return this.anyOf(schema.anyOf, required);
|
|
281
|
+
}
|
|
282
|
+
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
283
|
+
return this.oneOf(schema.oneOf, required);
|
|
284
|
+
}
|
|
285
|
+
if (schema.enum && Array.isArray(schema.enum)) {
|
|
286
|
+
return this.enum(schema.enum, required);
|
|
287
|
+
}
|
|
288
|
+
if (schema.const) {
|
|
289
|
+
return this.enum([schema.const], true);
|
|
290
|
+
}
|
|
291
|
+
const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
292
|
+
if (!types.length) {
|
|
293
|
+
if ("properties" in schema) {
|
|
294
|
+
return this.object(schema, required);
|
|
295
|
+
}
|
|
296
|
+
return appendOptional("any", required);
|
|
297
|
+
}
|
|
298
|
+
if (types.length > 1) {
|
|
299
|
+
const realTypes = types.filter((t) => t !== "null");
|
|
300
|
+
if (realTypes.length === 1 && types.includes("null")) {
|
|
301
|
+
const tsType = this.normal(realTypes[0], schema, false);
|
|
302
|
+
return appendOptional(`${tsType} | null`, required);
|
|
303
|
+
}
|
|
304
|
+
const typeResults = types.map((t) => this.normal(t, schema, false));
|
|
305
|
+
return appendOptional(typeResults.join(" | "), required);
|
|
306
|
+
}
|
|
307
|
+
return this.normal(types[0], schema, required);
|
|
308
|
+
}
|
|
1713
309
|
};
|
|
310
|
+
function appendOptional(type, isRequired) {
|
|
311
|
+
return isRequired ? type : `${type} | undefined`;
|
|
312
|
+
}
|
|
1714
313
|
|
|
1715
314
|
// packages/typescript/src/lib/generator.ts
|
|
1716
315
|
import { merge, template } from "lodash-es";
|
|
1717
316
|
import { join } from "node:path";
|
|
1718
|
-
import { camelcase as
|
|
1719
|
-
import { followRef as
|
|
317
|
+
import { camelcase as camelcase2, spinalcase } from "stringcase";
|
|
318
|
+
import { followRef as followRef4, isEmpty as isEmpty2, isRef as isRef4, resolveRef } from "@sdk-it/core";
|
|
319
|
+
import { forEachOperation } from "@sdk-it/spec";
|
|
1720
320
|
|
|
1721
321
|
// packages/typescript/src/lib/emitters/zod.ts
|
|
1722
|
-
import {
|
|
322
|
+
import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2 } from "@sdk-it/core";
|
|
323
|
+
import { isPrimitiveSchema as isPrimitiveSchema2, sanitizeTag as sanitizeTag2 } from "@sdk-it/spec";
|
|
1723
324
|
var ZodEmitter = class {
|
|
1724
|
-
generatedRefs = /* @__PURE__ */ new Set();
|
|
325
|
+
#generatedRefs = /* @__PURE__ */ new Set();
|
|
1725
326
|
#spec;
|
|
1726
327
|
#onRef;
|
|
1727
328
|
constructor(spec, onRef) {
|
|
@@ -1748,25 +349,21 @@ var ZodEmitter = class {
|
|
|
1748
349
|
}
|
|
1749
350
|
return `z.object({${propEntries.join(", ")}})${additionalProps}`;
|
|
1750
351
|
}
|
|
1751
|
-
|
|
1752
|
-
* Handle arrays (items could be a single schema or a tuple (array of schemas)).
|
|
1753
|
-
* In JSON Schema 2020-12, `items` can be an array → tuple style.
|
|
1754
|
-
*/
|
|
1755
|
-
array(schema, required = false) {
|
|
352
|
+
#array(schema, required = false) {
|
|
1756
353
|
const { items } = schema;
|
|
1757
354
|
if (!items) {
|
|
1758
|
-
return `z.array(z.unknown())${
|
|
355
|
+
return `z.array(z.unknown())${appendOptional2(required)}`;
|
|
1759
356
|
}
|
|
1760
357
|
if (Array.isArray(items)) {
|
|
1761
358
|
const tupleItems = items.map((sub) => this.handle(sub, true));
|
|
1762
359
|
const base = `z.tuple([${tupleItems.join(", ")}])`;
|
|
1763
|
-
return `${base}${
|
|
360
|
+
return `${base}${appendOptional2(required)}`;
|
|
1764
361
|
}
|
|
1765
362
|
const itemsSchema = this.handle(items, true);
|
|
1766
|
-
return `z.array(${itemsSchema})${
|
|
363
|
+
return `z.array(${itemsSchema})${this.#suffixes(JSON.stringify(schema.default), required, false)}`;
|
|
1767
364
|
}
|
|
1768
365
|
#suffixes = (defaultValue, required, nullable) => {
|
|
1769
|
-
return `${nullable ? ".nullable()" : ""}${appendDefault(defaultValue)}${
|
|
366
|
+
return `${nullable ? ".nullable()" : ""}${appendDefault(defaultValue)}${appendOptional2(required)}`;
|
|
1770
367
|
};
|
|
1771
368
|
/**
|
|
1772
369
|
* Convert a basic type (string | number | boolean | object | array, etc.) to Zod.
|
|
@@ -1786,55 +383,58 @@ var ZodEmitter = class {
|
|
|
1786
383
|
case "object":
|
|
1787
384
|
return `${this.object(schema)}${this.#suffixes(JSON.stringify(schema.default), required, nullable)}`;
|
|
1788
385
|
case "array":
|
|
1789
|
-
return this
|
|
386
|
+
return this.#array(schema, required);
|
|
1790
387
|
case "null":
|
|
1791
|
-
return `z.null()${
|
|
388
|
+
return `z.null()${appendOptional2(required)}`;
|
|
1792
389
|
default:
|
|
1793
|
-
return `z.unknown()${
|
|
390
|
+
return `z.unknown()${appendOptional2(required)}`;
|
|
1794
391
|
}
|
|
1795
392
|
}
|
|
1796
|
-
ref($ref, required) {
|
|
1797
|
-
const schemaName =
|
|
1798
|
-
|
|
393
|
+
#ref($ref, required) {
|
|
394
|
+
const schemaName = pascalcase2(sanitizeTag2(parseRef2($ref).model));
|
|
395
|
+
const schema = followRef2(this.#spec, $ref);
|
|
396
|
+
if (isPrimitiveSchema2(schema)) {
|
|
397
|
+
const result = this.handle(schema, required);
|
|
398
|
+
this.#onRef?.(schemaName, result);
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
if (this.#generatedRefs.has(schemaName)) {
|
|
1799
402
|
return schemaName;
|
|
1800
403
|
}
|
|
1801
|
-
this
|
|
1802
|
-
this.#onRef?.(
|
|
1803
|
-
schemaName,
|
|
1804
|
-
this.handle(followRef4(this.#spec, $ref), required)
|
|
1805
|
-
);
|
|
404
|
+
this.#generatedRefs.add(schemaName);
|
|
405
|
+
this.#onRef?.(schemaName, this.handle(schema, required));
|
|
1806
406
|
return schemaName;
|
|
1807
407
|
}
|
|
408
|
+
#toIntersection(schemas) {
|
|
409
|
+
const [left, ...right] = schemas;
|
|
410
|
+
if (!right.length) {
|
|
411
|
+
return left;
|
|
412
|
+
}
|
|
413
|
+
return `z.intersection(${left}, ${this.#toIntersection(right)})`;
|
|
414
|
+
}
|
|
1808
415
|
allOf(schemas, required) {
|
|
1809
416
|
const allOfSchemas = schemas.map((sub) => this.handle(sub, true));
|
|
1810
417
|
if (allOfSchemas.length === 0) {
|
|
1811
418
|
return `z.unknown()`;
|
|
1812
419
|
}
|
|
1813
420
|
if (allOfSchemas.length === 1) {
|
|
1814
|
-
return `${allOfSchemas[0]}${
|
|
1815
|
-
}
|
|
1816
|
-
return `${this.#toIntersection(allOfSchemas)}${appendOptional(required)}`;
|
|
1817
|
-
}
|
|
1818
|
-
#toIntersection(schemas) {
|
|
1819
|
-
const [left, ...right] = schemas;
|
|
1820
|
-
if (!right.length) {
|
|
1821
|
-
return left;
|
|
421
|
+
return `${allOfSchemas[0]}${appendOptional2(required)}`;
|
|
1822
422
|
}
|
|
1823
|
-
return
|
|
423
|
+
return `${this.#toIntersection(allOfSchemas)}${appendOptional2(required)}`;
|
|
1824
424
|
}
|
|
1825
425
|
anyOf(schemas, required) {
|
|
1826
426
|
const anyOfSchemas = schemas.map((sub) => this.handle(sub, true));
|
|
1827
427
|
if (anyOfSchemas.length === 1) {
|
|
1828
|
-
return `${anyOfSchemas[0]}${
|
|
428
|
+
return `${anyOfSchemas[0]}${appendOptional2(required)}`;
|
|
1829
429
|
}
|
|
1830
|
-
return `z.union([${anyOfSchemas.join(", ")}])${
|
|
430
|
+
return `z.union([${anyOfSchemas.join(", ")}])${appendOptional2(required)}`;
|
|
1831
431
|
}
|
|
1832
432
|
oneOf(schemas, required) {
|
|
1833
433
|
const oneOfSchemas = schemas.map((sub) => this.handle(sub, true));
|
|
1834
434
|
if (oneOfSchemas.length === 1) {
|
|
1835
|
-
return `${oneOfSchemas[0]}${
|
|
435
|
+
return `${oneOfSchemas[0]}${appendOptional2(required)}`;
|
|
1836
436
|
}
|
|
1837
|
-
return `z.union([${oneOfSchemas.join(", ")}])${
|
|
437
|
+
return `z.union([${oneOfSchemas.join(", ")}])${appendOptional2(required)}`;
|
|
1838
438
|
}
|
|
1839
439
|
enum(type, values) {
|
|
1840
440
|
if (values.length === 1) {
|
|
@@ -1931,8 +531,8 @@ var ZodEmitter = class {
|
|
|
1931
531
|
return { base, defaultValue };
|
|
1932
532
|
}
|
|
1933
533
|
handle(schema, required) {
|
|
1934
|
-
if (
|
|
1935
|
-
return `${this
|
|
534
|
+
if (isRef2(schema)) {
|
|
535
|
+
return `${this.#ref(schema.$ref, true)}${appendOptional2(required)}`;
|
|
1936
536
|
}
|
|
1937
537
|
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
1938
538
|
return this.allOf(schema.allOf ?? [], required);
|
|
@@ -1950,7 +550,7 @@ var ZodEmitter = class {
|
|
|
1950
550
|
}
|
|
1951
551
|
const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
1952
552
|
if (!types.length) {
|
|
1953
|
-
return `z.unknown()${
|
|
553
|
+
return `z.unknown()${appendOptional2(required)}`;
|
|
1954
554
|
}
|
|
1955
555
|
if ("nullable" in schema && schema.nullable) {
|
|
1956
556
|
types.push("null");
|
|
@@ -1963,12 +563,12 @@ var ZodEmitter = class {
|
|
|
1963
563
|
return this.normal(realTypes[0], schema, required, true);
|
|
1964
564
|
}
|
|
1965
565
|
const subSchemas = types.map((t) => this.normal(t, schema, false));
|
|
1966
|
-
return `z.union([${subSchemas.join(", ")}])${
|
|
566
|
+
return `z.union([${subSchemas.join(", ")}])${appendOptional2(required)}`;
|
|
1967
567
|
}
|
|
1968
568
|
return this.normal(types[0], schema, required, false);
|
|
1969
569
|
}
|
|
1970
570
|
};
|
|
1971
|
-
function
|
|
571
|
+
function appendOptional2(isRequired) {
|
|
1972
572
|
return isRequired ? "" : ".optional()";
|
|
1973
573
|
}
|
|
1974
574
|
function appendDefault(defaultValue) {
|
|
@@ -1976,201 +576,46 @@ function appendDefault(defaultValue) {
|
|
|
1976
576
|
}
|
|
1977
577
|
|
|
1978
578
|
// packages/typescript/src/lib/sdk.ts
|
|
1979
|
-
import {
|
|
1980
|
-
import {
|
|
1981
|
-
import {
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
propEntries.push("[key: string]: any");
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
return `${propEntries.length ? `{ ${propEntries.join("; ")} }` : "unknown"}`;
|
|
2018
|
-
}
|
|
2019
|
-
/**
|
|
2020
|
-
* Handle arrays (items could be a single schema or a tuple)
|
|
2021
|
-
*/
|
|
2022
|
-
array(schema, required = false) {
|
|
2023
|
-
const { items } = schema;
|
|
2024
|
-
if (!items) {
|
|
2025
|
-
return "any[]";
|
|
2026
|
-
}
|
|
2027
|
-
if (Array.isArray(items)) {
|
|
2028
|
-
const tupleItems = items.map((sub) => this.handle(sub, true));
|
|
2029
|
-
return `[${tupleItems.join(", ")}]`;
|
|
2030
|
-
}
|
|
2031
|
-
const itemsType = this.handle(items, true);
|
|
2032
|
-
return `${itemsType}[]`;
|
|
2033
|
-
}
|
|
2034
|
-
/**
|
|
2035
|
-
* Convert a basic type (string | number | boolean | object | array, etc.) to TypeScript
|
|
2036
|
-
*/
|
|
2037
|
-
normal(type, schema, required = false) {
|
|
2038
|
-
switch (type) {
|
|
2039
|
-
case "string":
|
|
2040
|
-
return this.string(schema, required);
|
|
2041
|
-
case "number":
|
|
2042
|
-
case "integer":
|
|
2043
|
-
return this.number(schema, required);
|
|
2044
|
-
case "boolean":
|
|
2045
|
-
return appendOptional2("boolean", required);
|
|
2046
|
-
case "object":
|
|
2047
|
-
return this.object(schema, required);
|
|
2048
|
-
case "array":
|
|
2049
|
-
return this.array(schema, required);
|
|
2050
|
-
case "null":
|
|
2051
|
-
return "null";
|
|
2052
|
-
default:
|
|
2053
|
-
console.warn(`Unknown type: ${type}`);
|
|
2054
|
-
return appendOptional2("any", required);
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
ref($ref, required) {
|
|
2058
|
-
const schemaName = cleanRef2($ref).split("/").pop();
|
|
2059
|
-
if (this.generatedRefs.has(schemaName)) {
|
|
2060
|
-
return schemaName;
|
|
2061
|
-
}
|
|
2062
|
-
this.generatedRefs.add(schemaName);
|
|
2063
|
-
this.#onRef?.(
|
|
2064
|
-
schemaName,
|
|
2065
|
-
this.handle(followRef5(this.#spec, $ref), required)
|
|
2066
|
-
);
|
|
2067
|
-
return appendOptional2(schemaName, required);
|
|
2068
|
-
}
|
|
2069
|
-
allOf(schemas) {
|
|
2070
|
-
const allOfTypes = schemas.map((sub) => this.handle(sub, true));
|
|
2071
|
-
return allOfTypes.length > 1 ? `${allOfTypes.join(" & ")}` : allOfTypes[0];
|
|
2072
|
-
}
|
|
2073
|
-
anyOf(schemas, required) {
|
|
2074
|
-
const anyOfTypes = schemas.map((sub) => this.handle(sub, true));
|
|
2075
|
-
return appendOptional2(
|
|
2076
|
-
anyOfTypes.length > 1 ? `${anyOfTypes.join(" | ")}` : anyOfTypes[0],
|
|
2077
|
-
required
|
|
2078
|
-
);
|
|
2079
|
-
}
|
|
2080
|
-
oneOf(schemas, required) {
|
|
2081
|
-
const oneOfTypes = schemas.map((sub) => {
|
|
2082
|
-
return this.handle(sub, false);
|
|
2083
|
-
});
|
|
2084
|
-
return appendOptional2(
|
|
2085
|
-
oneOfTypes.length > 1 ? `${oneOfTypes.join(" | ")}` : oneOfTypes[0],
|
|
2086
|
-
required
|
|
2087
|
-
);
|
|
2088
|
-
}
|
|
2089
|
-
enum(values, required) {
|
|
2090
|
-
const enumValues = values.map((val) => typeof val === "string" ? `'${val}'` : `${val}`).join(" | ");
|
|
2091
|
-
return appendOptional2(enumValues, required);
|
|
2092
|
-
}
|
|
2093
|
-
/**
|
|
2094
|
-
* Handle string type with formats
|
|
2095
|
-
*/
|
|
2096
|
-
string(schema, required) {
|
|
2097
|
-
let type;
|
|
2098
|
-
if (schema.contentEncoding === "binary") {
|
|
2099
|
-
return appendOptional2("Blob", required);
|
|
2100
|
-
}
|
|
2101
|
-
switch (schema.format) {
|
|
2102
|
-
case "date-time":
|
|
2103
|
-
case "datetime":
|
|
2104
|
-
case "date":
|
|
2105
|
-
type = "Date";
|
|
2106
|
-
break;
|
|
2107
|
-
case "binary":
|
|
2108
|
-
case "byte":
|
|
2109
|
-
type = "Blob";
|
|
2110
|
-
break;
|
|
2111
|
-
case "int64":
|
|
2112
|
-
type = "bigint";
|
|
2113
|
-
break;
|
|
2114
|
-
default:
|
|
2115
|
-
type = "string";
|
|
2116
|
-
}
|
|
2117
|
-
return appendOptional2(type, required);
|
|
2118
|
-
}
|
|
2119
|
-
/**
|
|
2120
|
-
* Handle number/integer types with formats
|
|
2121
|
-
*/
|
|
2122
|
-
number(schema, required) {
|
|
2123
|
-
const type = schema.format === "int64" ? "bigint" : "number";
|
|
2124
|
-
return appendOptional2(type, required);
|
|
2125
|
-
}
|
|
2126
|
-
handle(schema, required) {
|
|
2127
|
-
if (isRef7(schema)) {
|
|
2128
|
-
return this.ref(schema.$ref, required);
|
|
2129
|
-
}
|
|
2130
|
-
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
2131
|
-
return this.allOf(schema.allOf);
|
|
2132
|
-
}
|
|
2133
|
-
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
2134
|
-
return this.anyOf(schema.anyOf, required);
|
|
2135
|
-
}
|
|
2136
|
-
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
2137
|
-
return this.oneOf(schema.oneOf, required);
|
|
2138
|
-
}
|
|
2139
|
-
if (schema.enum && Array.isArray(schema.enum)) {
|
|
2140
|
-
return this.enum(schema.enum, required);
|
|
2141
|
-
}
|
|
2142
|
-
if (schema.const) {
|
|
2143
|
-
if (schema["x-internal"]) {
|
|
2144
|
-
return `${schema.const}`;
|
|
2145
|
-
}
|
|
2146
|
-
return this.enum([schema.const], required);
|
|
2147
|
-
}
|
|
2148
|
-
const types = Array.isArray(schema.type) ? schema.type : schema.type ? [schema.type] : [];
|
|
2149
|
-
if (!types.length) {
|
|
2150
|
-
if ("properties" in schema) {
|
|
2151
|
-
return this.object(schema, required);
|
|
2152
|
-
}
|
|
2153
|
-
return appendOptional2("any", required);
|
|
2154
|
-
}
|
|
2155
|
-
if (types.length > 1) {
|
|
2156
|
-
const realTypes = types.filter((t) => t !== "null");
|
|
2157
|
-
if (realTypes.length === 1 && types.includes("null")) {
|
|
2158
|
-
const tsType = this.normal(realTypes[0], schema, false);
|
|
2159
|
-
return appendOptional2(`${tsType} | null`, required);
|
|
2160
|
-
}
|
|
2161
|
-
const typeResults = types.map((t) => this.normal(t, schema, false));
|
|
2162
|
-
return appendOptional2(typeResults.join(" | "), required);
|
|
2163
|
-
}
|
|
2164
|
-
return this.normal(types[0], schema, required);
|
|
2165
|
-
}
|
|
579
|
+
import { camelcase } from "stringcase";
|
|
580
|
+
import { isEmpty, pascalcase as pascalcase3 } from "@sdk-it/core";
|
|
581
|
+
import {
|
|
582
|
+
isErrorStatusCode,
|
|
583
|
+
isStreamingContentType,
|
|
584
|
+
isSuccessStatusCode,
|
|
585
|
+
isTextContentType,
|
|
586
|
+
parseJsonContentType,
|
|
587
|
+
sanitizeTag as sanitizeTag3
|
|
588
|
+
} from "@sdk-it/spec";
|
|
589
|
+
|
|
590
|
+
// packages/typescript/src/lib/status-map.ts
|
|
591
|
+
var status_map_default = {
|
|
592
|
+
"200": "Ok",
|
|
593
|
+
"201": "Created",
|
|
594
|
+
"202": "Accepted",
|
|
595
|
+
"204": "NoContent",
|
|
596
|
+
"400": "BadRequest",
|
|
597
|
+
"401": "Unauthorized",
|
|
598
|
+
"402": "PaymentRequired",
|
|
599
|
+
"403": "Forbidden",
|
|
600
|
+
"404": "NotFound",
|
|
601
|
+
"405": "MethodNotAllowed",
|
|
602
|
+
"406": "NotAcceptable",
|
|
603
|
+
"409": "Conflict",
|
|
604
|
+
"412": "PreconditionFailed",
|
|
605
|
+
"413": "PayloadTooLarge",
|
|
606
|
+
"410": "Gone",
|
|
607
|
+
"422": "UnprocessableEntity",
|
|
608
|
+
"429": "TooManyRequests",
|
|
609
|
+
"500": "InternalServerError",
|
|
610
|
+
"501": "NotImplemented",
|
|
611
|
+
"502": "BadGateway",
|
|
612
|
+
"503": "ServiceUnavailable",
|
|
613
|
+
"504": "GatewayTimeout"
|
|
2166
614
|
};
|
|
2167
|
-
function appendOptional2(type, isRequired) {
|
|
2168
|
-
return isRequired ? type : `${type} | undefined`;
|
|
2169
|
-
}
|
|
2170
615
|
|
|
2171
616
|
// packages/typescript/src/lib/utils.ts
|
|
2172
|
-
import { followRef as
|
|
2173
|
-
function
|
|
617
|
+
import { followRef as followRef3, isRef as isRef3, removeDuplicates } from "@sdk-it/core";
|
|
618
|
+
function securityToOptions(spec, security2, securitySchemes, staticIn) {
|
|
2174
619
|
securitySchemes ??= {};
|
|
2175
620
|
const options = {};
|
|
2176
621
|
for (const it of security2) {
|
|
@@ -2178,7 +623,7 @@ function securityToOptions2(spec, security2, securitySchemes, staticIn) {
|
|
|
2178
623
|
if (!name) {
|
|
2179
624
|
continue;
|
|
2180
625
|
}
|
|
2181
|
-
const schema =
|
|
626
|
+
const schema = isRef3(securitySchemes[name]) ? followRef3(spec, securitySchemes[name].$ref) : securitySchemes[name];
|
|
2182
627
|
if (schema.type === "http") {
|
|
2183
628
|
options["authorization"] = {
|
|
2184
629
|
in: staticIn ?? "header",
|
|
@@ -2213,96 +658,34 @@ function mergeImports(...imports) {
|
|
|
2213
658
|
namedImports: []
|
|
2214
659
|
};
|
|
2215
660
|
for (const named of it.namedImports) {
|
|
2216
|
-
if (!merged[it.moduleSpecifier].namedImports.some(
|
|
2217
|
-
(x) => x.name === named.name
|
|
2218
|
-
)) {
|
|
2219
|
-
merged[it.moduleSpecifier].namedImports.push(named);
|
|
2220
|
-
}
|
|
2221
|
-
}
|
|
2222
|
-
}
|
|
2223
|
-
return Object.values(merged);
|
|
2224
|
-
}
|
|
2225
|
-
function importsToString(...imports) {
|
|
2226
|
-
return imports.map((it) => {
|
|
2227
|
-
if (it.defaultImport) {
|
|
2228
|
-
return `import ${it.defaultImport} from '${it.moduleSpecifier}'`;
|
|
2229
|
-
}
|
|
2230
|
-
if (it.namespaceImport) {
|
|
2231
|
-
return `import * as ${it.namespaceImport} from '${it.moduleSpecifier}'`;
|
|
2232
|
-
}
|
|
2233
|
-
if (it.namedImports) {
|
|
2234
|
-
return `import {${removeDuplicates(it.namedImports, (it2) => it2.name).map((n) => `${n.isTypeOnly ? "type" : ""} ${n.name}`).join(", ")}} from '${it.moduleSpecifier}'`;
|
|
2235
|
-
}
|
|
2236
|
-
throw new Error(`Invalid import ${JSON.stringify(it)}`);
|
|
2237
|
-
});
|
|
2238
|
-
}
|
|
2239
|
-
function exclude(list, exclude2) {
|
|
2240
|
-
return list.filter((it) => !exclude2.includes(it));
|
|
2241
|
-
}
|
|
2242
|
-
function useImports(content, ...imports) {
|
|
2243
|
-
const output = [];
|
|
2244
|
-
for (const it of mergeImports(...imports)) {
|
|
2245
|
-
const singleImport = it.defaultImport ?? it.namespaceImport;
|
|
2246
|
-
if (singleImport && content.includes(singleImport)) {
|
|
2247
|
-
output.push(importsToString(it).join("\n"));
|
|
2248
|
-
} else if (it.namedImports.length) {
|
|
2249
|
-
for (const namedImport of it.namedImports) {
|
|
2250
|
-
if (content.includes(namedImport.name)) {
|
|
2251
|
-
output.push(importsToString(it).join("\n"));
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
}
|
|
2256
|
-
return output;
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
// packages/typescript/src/lib/sdk.ts
|
|
2260
|
-
function generateInputs(operationsSet, commonZod, makeImport) {
|
|
2261
|
-
const commonImports = commonZod.keys().toArray();
|
|
2262
|
-
const inputs = {};
|
|
2263
|
-
for (const [name, operations] of Object.entries(operationsSet)) {
|
|
2264
|
-
const output = [];
|
|
2265
|
-
const imports = /* @__PURE__ */ new Set(['import { z } from "zod";']);
|
|
2266
|
-
for (const operation of operations) {
|
|
2267
|
-
const schemaName = camelcase3(`${operation.name} schema`);
|
|
2268
|
-
const schema = `export const ${schemaName} = ${Object.keys(operation.schemas).length === 1 ? Object.values(operation.schemas)[0] : toLitObject2(operation.schemas)};`;
|
|
2269
|
-
const inputContent = schema;
|
|
2270
|
-
for (const schema2 of commonImports) {
|
|
2271
|
-
if (inputContent.includes(schema2)) {
|
|
2272
|
-
imports.add(
|
|
2273
|
-
`import { ${schema2} } from './schemas/${makeImport(spinalcase(schema2))}';`
|
|
2274
|
-
);
|
|
2275
|
-
}
|
|
661
|
+
if (!merged[it.moduleSpecifier].namedImports.some(
|
|
662
|
+
(x) => x.name === named.name
|
|
663
|
+
)) {
|
|
664
|
+
merged[it.moduleSpecifier].namedImports.push(named);
|
|
2276
665
|
}
|
|
2277
|
-
output.push(inputContent);
|
|
2278
666
|
}
|
|
2279
|
-
inputs[`inputs/${spinalcase(name)}.ts`] = [...imports, ...output].join("\n") + "\n";
|
|
2280
667
|
}
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
output.push(
|
|
2288
|
-
`import { ${schema2} } from './${makeImport(spinalcase(schema2))}';`
|
|
2289
|
-
);
|
|
2290
|
-
}
|
|
668
|
+
return Object.values(merged);
|
|
669
|
+
}
|
|
670
|
+
function importsToString(...imports) {
|
|
671
|
+
return imports.map((it) => {
|
|
672
|
+
if (it.defaultImport) {
|
|
673
|
+
return `import ${it.defaultImport} from '${it.moduleSpecifier}'`;
|
|
2291
674
|
}
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
...inputs
|
|
2301
|
-
};
|
|
675
|
+
if (it.namespaceImport) {
|
|
676
|
+
return `import * as ${it.namespaceImport} from '${it.moduleSpecifier}'`;
|
|
677
|
+
}
|
|
678
|
+
if (it.namedImports) {
|
|
679
|
+
return `import {${removeDuplicates(it.namedImports, (it2) => it2.name).map((n) => `${n.isTypeOnly ? "type" : ""} ${n.name}`).join(", ")}} from '${it.moduleSpecifier}'`;
|
|
680
|
+
}
|
|
681
|
+
throw new Error(`Invalid import ${JSON.stringify(it)}`);
|
|
682
|
+
});
|
|
2302
683
|
}
|
|
684
|
+
|
|
685
|
+
// packages/typescript/src/lib/sdk.ts
|
|
2303
686
|
function toEndpoint(groupName, spec, specOperation, operation, utils) {
|
|
2304
|
-
const schemaName =
|
|
2305
|
-
const schemaRef = `${
|
|
687
|
+
const schemaName = camelcase(`${operation.name} schema`);
|
|
688
|
+
const schemaRef = `${camelcase(groupName)}.${schemaName}`;
|
|
2306
689
|
const inputHeaders = [];
|
|
2307
690
|
const inputQuery = [];
|
|
2308
691
|
const inputBody = [];
|
|
@@ -2330,32 +713,13 @@ function toEndpoint(groupName, spec, specOperation, operation, utils) {
|
|
|
2330
713
|
}
|
|
2331
714
|
specOperation.responses ??= {};
|
|
2332
715
|
const outputs = [];
|
|
2333
|
-
const
|
|
2334
|
-
const statusCode = +status;
|
|
2335
|
-
return statusCode >= 200 && statusCode < 300;
|
|
2336
|
-
}).length > 1;
|
|
2337
|
-
const responseWithAtLeast200 = statusesCount ? specOperation.responses : Object.assign(
|
|
2338
|
-
{
|
|
2339
|
-
"200": {
|
|
2340
|
-
description: "OK",
|
|
2341
|
-
content: {
|
|
2342
|
-
"application/json": {
|
|
2343
|
-
schema: { type: "object" }
|
|
2344
|
-
}
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
},
|
|
2348
|
-
specOperation.responses
|
|
2349
|
-
);
|
|
2350
|
-
for (const status in responseWithAtLeast200) {
|
|
716
|
+
for (const status in specOperation.responses) {
|
|
2351
717
|
const handled = handleResponse(
|
|
2352
718
|
spec,
|
|
2353
719
|
operation.name,
|
|
2354
720
|
status,
|
|
2355
|
-
|
|
2356
|
-
utils
|
|
2357
|
-
true
|
|
2358
|
-
// statusesCount,
|
|
721
|
+
specOperation.responses[status],
|
|
722
|
+
utils
|
|
2359
723
|
);
|
|
2360
724
|
responses.push(handled);
|
|
2361
725
|
outputs.push(...handled.outputs);
|
|
@@ -2366,7 +730,7 @@ function toEndpoint(groupName, spec, specOperation, operation, utils) {
|
|
|
2366
730
|
if (addTypeParser && type !== "json") {
|
|
2367
731
|
typePrefix = `${type} `;
|
|
2368
732
|
}
|
|
2369
|
-
const endpoint = `${typePrefix}${operation.
|
|
733
|
+
const endpoint = `${typePrefix}${operation.method.toUpperCase()} ${operation.path}`;
|
|
2370
734
|
schemas.push(
|
|
2371
735
|
`"${endpoint}": {
|
|
2372
736
|
schema: ${schemaRef}${addTypeParser ? `.${type}` : ""},
|
|
@@ -2398,6 +762,7 @@ function normalOperation(style) {
|
|
|
2398
762
|
function paginationOperation(operation, style) {
|
|
2399
763
|
const pagination = operation["x-pagination"];
|
|
2400
764
|
const data = `${style?.errorAsValue ? `result[0]${style.outputType === "status" ? "" : ""}` : `${style?.outputType === "default" ? "result.data" : "result.data"}`}`;
|
|
765
|
+
const returnValue = `${style?.errorAsValue ? `[${style?.outputType === "status" ? "new http.Ok(pagination)" : "pagination"}, null]` : `${style?.outputType === "status" ? "new http.Ok(pagination);" : "pagination"}`}`;
|
|
2401
766
|
if (pagination.type === "offset") {
|
|
2402
767
|
const sameInputNames = pagination.limitParamName === "limit" && pagination.offsetParamName === "offset";
|
|
2403
768
|
const initialParams = sameInputNames ? "input" : `{...input, limit: input.${pagination.limitParamName}, offset: input.${pagination.offsetParamName}}`;
|
|
@@ -2416,7 +781,7 @@ function paginationOperation(operation, style) {
|
|
|
2416
781
|
};
|
|
2417
782
|
});
|
|
2418
783
|
await pagination.getNextPage();
|
|
2419
|
-
return ${
|
|
784
|
+
return ${returnValue}
|
|
2420
785
|
`;
|
|
2421
786
|
return style?.errorAsValue ? `{try {${logic}} catch (error) {return [null as never, error] as const;}}}` : `{${logic}}}`;
|
|
2422
787
|
}
|
|
@@ -2440,7 +805,7 @@ function paginationOperation(operation, style) {
|
|
|
2440
805
|
};
|
|
2441
806
|
});
|
|
2442
807
|
await pagination.getNextPage();
|
|
2443
|
-
return ${
|
|
808
|
+
return ${returnValue}
|
|
2444
809
|
`;
|
|
2445
810
|
return style?.errorAsValue ? `{try {${logic}} catch (error) {return [null as never, error] as const;}}}` : `{${logic}}}`;
|
|
2446
811
|
}
|
|
@@ -2464,36 +829,13 @@ function paginationOperation(operation, style) {
|
|
|
2464
829
|
};
|
|
2465
830
|
});
|
|
2466
831
|
await pagination.getNextPage();
|
|
2467
|
-
return ${
|
|
832
|
+
return ${returnValue}
|
|
2468
833
|
`;
|
|
2469
834
|
return style?.errorAsValue ? `{try {${logic}} catch (error) {return [null as never, error] as const;}}}` : `{${logic}}}`;
|
|
2470
835
|
}
|
|
2471
836
|
return normalOperation(style);
|
|
2472
837
|
}
|
|
2473
|
-
|
|
2474
|
-
"200": "Ok",
|
|
2475
|
-
"201": "Created",
|
|
2476
|
-
"202": "Accepted",
|
|
2477
|
-
"204": "NoContent",
|
|
2478
|
-
"400": "BadRequest",
|
|
2479
|
-
"401": "Unauthorized",
|
|
2480
|
-
"402": "PaymentRequired",
|
|
2481
|
-
"403": "Forbidden",
|
|
2482
|
-
"404": "NotFound",
|
|
2483
|
-
"405": "MethodNotAllowed",
|
|
2484
|
-
"406": "NotAcceptable",
|
|
2485
|
-
"409": "Conflict",
|
|
2486
|
-
"413": "PayloadTooLarge",
|
|
2487
|
-
"410": "Gone",
|
|
2488
|
-
"422": "UnprocessableEntity",
|
|
2489
|
-
"429": "TooManyRequests",
|
|
2490
|
-
"500": "InternalServerError",
|
|
2491
|
-
"501": "NotImplemented",
|
|
2492
|
-
"502": "BadGateway",
|
|
2493
|
-
"503": "ServiceUnavailable",
|
|
2494
|
-
"504": "GatewayTimeout"
|
|
2495
|
-
};
|
|
2496
|
-
function handleResponse(spec, operationName, status, response, utils, numbered) {
|
|
838
|
+
function handleResponse(spec, operationName, status, response, utils) {
|
|
2497
839
|
const schemas = {};
|
|
2498
840
|
const imports = {};
|
|
2499
841
|
const endpointImports = {
|
|
@@ -2507,79 +849,84 @@ function handleResponse(spec, operationName, status, response, utils, numbered)
|
|
|
2507
849
|
};
|
|
2508
850
|
const responses = [];
|
|
2509
851
|
const outputs = [];
|
|
2510
|
-
const typeScriptDeserialzer = new TypeScriptEmitter(
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
852
|
+
const typeScriptDeserialzer = new TypeScriptEmitter(spec);
|
|
853
|
+
const statusCode = +status;
|
|
854
|
+
const statusName = `http.${status_map_default[status] || "APIResponse"}`;
|
|
855
|
+
const interfaceName = pascalcase3(sanitizeTag3(response["x-response-name"]));
|
|
856
|
+
let parser = "buffered";
|
|
857
|
+
if (isEmpty(response.content)) {
|
|
858
|
+
responses.push({
|
|
859
|
+
name: interfaceName,
|
|
860
|
+
schema: "void",
|
|
861
|
+
description: response.description
|
|
862
|
+
});
|
|
863
|
+
} else {
|
|
864
|
+
const contentTypeResult = fromContentType(
|
|
865
|
+
spec,
|
|
866
|
+
typeScriptDeserialzer,
|
|
867
|
+
response
|
|
868
|
+
);
|
|
869
|
+
if (!contentTypeResult) {
|
|
870
|
+
throw new Error(
|
|
871
|
+
`No recognizable content type for response ${status} in operation ${operationName}`
|
|
872
|
+
);
|
|
873
|
+
}
|
|
874
|
+
parser = contentTypeResult.parser;
|
|
875
|
+
const responseSchema = contentTypeResult.responseSchema;
|
|
876
|
+
responses.push({
|
|
877
|
+
name: interfaceName,
|
|
878
|
+
schema: responseSchema,
|
|
879
|
+
description: response.description
|
|
880
|
+
});
|
|
881
|
+
if (isErrorStatusCode(statusCode)) {
|
|
882
|
+
endpointImports[status_map_default[status] ?? "APIError"] = {
|
|
883
|
+
moduleSpecifier: utils.makeImport("../http/response"),
|
|
884
|
+
namedImports: [{ name: status_map_default[status] ?? "APIError" }]
|
|
2520
885
|
};
|
|
886
|
+
} else if (isSuccessStatusCode(statusCode)) {
|
|
2521
887
|
}
|
|
2522
|
-
|
|
2523
|
-
const statusCode = +status;
|
|
2524
|
-
const parser = (response.headers ?? {})["Transfer-Encoding"] ? "chunked" : "buffered";
|
|
2525
|
-
const statusName = `http.${statusCodeToResponseMap[status] || "APIResponse"}`;
|
|
2526
|
-
const interfaceName = pascalcase(
|
|
2527
|
-
operationName + ` output${numbered ? status : ""}`
|
|
2528
|
-
);
|
|
888
|
+
}
|
|
2529
889
|
if (statusCode === 204) {
|
|
2530
890
|
outputs.push(statusName);
|
|
2531
891
|
} else {
|
|
2532
892
|
if (status.endsWith("XX")) {
|
|
2533
|
-
outputs.push(`http.APIError
|
|
893
|
+
outputs.push(`http.APIError<outputs.${interfaceName}>`);
|
|
2534
894
|
} else {
|
|
2535
895
|
outputs.push(
|
|
2536
|
-
parser !== "buffered" ? `{type: ${statusName}
|
|
896
|
+
parser !== "buffered" ? `{type: ${statusName}<outputs.${interfaceName}>, parser: ${parser}}` : `${statusName}<outputs.${interfaceName}>`
|
|
2537
897
|
);
|
|
2538
898
|
}
|
|
2539
899
|
}
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
if (
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
900
|
+
return { schemas, imports, endpointImports, responses, outputs };
|
|
901
|
+
}
|
|
902
|
+
function fromContentType(spec, typeScriptDeserialzer, response) {
|
|
903
|
+
if ((response.headers ?? {})["Transfer-Encoding"]) {
|
|
904
|
+
return streamedOutput();
|
|
905
|
+
}
|
|
906
|
+
for (const type in response.content) {
|
|
907
|
+
if (isStreamingContentType(type)) {
|
|
908
|
+
return streamedOutput();
|
|
909
|
+
}
|
|
910
|
+
if (parseJsonContentType(type)) {
|
|
911
|
+
return {
|
|
912
|
+
parser: "buffered",
|
|
913
|
+
responseSchema: response.content[type].schema ? typeScriptDeserialzer.handle(response.content[type].schema, true) : "void"
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
if (isTextContentType(type)) {
|
|
917
|
+
return {
|
|
918
|
+
parser: "buffered",
|
|
919
|
+
responseSchema: response.content[type].schema ? typeScriptDeserialzer.handle(response.content[type].schema, true) : "void"
|
|
2551
920
|
};
|
|
2552
|
-
schema.required ??= [];
|
|
2553
|
-
schema.required.push("[http.KIND]");
|
|
2554
921
|
}
|
|
2555
|
-
responseSchema = typeScriptDeserialzer.handle(schema, true);
|
|
2556
|
-
}
|
|
2557
|
-
responses.push({
|
|
2558
|
-
name: interfaceName,
|
|
2559
|
-
schema: responseSchema,
|
|
2560
|
-
description: response.description
|
|
2561
|
-
});
|
|
2562
|
-
const statusGroup = +status.slice(0, 1);
|
|
2563
|
-
if (statusCode >= 400 || statusGroup >= 4) {
|
|
2564
|
-
endpointImports[statusCodeToResponseMap[status] ?? "APIError"] = {
|
|
2565
|
-
moduleSpecifier: utils.makeImport("../http/response"),
|
|
2566
|
-
namedImports: [{ name: statusCodeToResponseMap[status] ?? "APIError" }]
|
|
2567
|
-
};
|
|
2568
|
-
endpointImports[interfaceName] = {
|
|
2569
|
-
isTypeOnly: true,
|
|
2570
|
-
moduleSpecifier: `../outputs/${utils.makeImport(spinalcase(operationName))}`,
|
|
2571
|
-
namedImports: [{ isTypeOnly: true, name: interfaceName }]
|
|
2572
|
-
};
|
|
2573
|
-
} else if (statusCode >= 200 && statusCode < 300 || statusCode >= 2 || statusGroup <= 3) {
|
|
2574
|
-
endpointImports[interfaceName] = {
|
|
2575
|
-
defaultImport: void 0,
|
|
2576
|
-
isTypeOnly: true,
|
|
2577
|
-
moduleSpecifier: `../outputs/${utils.makeImport(spinalcase(operationName))}`,
|
|
2578
|
-
namedImports: [{ isTypeOnly: true, name: interfaceName }],
|
|
2579
|
-
namespaceImport: void 0
|
|
2580
|
-
};
|
|
2581
922
|
}
|
|
2582
|
-
return
|
|
923
|
+
return streamedOutput();
|
|
924
|
+
}
|
|
925
|
+
function streamedOutput() {
|
|
926
|
+
return {
|
|
927
|
+
parser: "chunked",
|
|
928
|
+
responseSchema: "ReadableStream"
|
|
929
|
+
};
|
|
2583
930
|
}
|
|
2584
931
|
|
|
2585
932
|
// packages/typescript/src/lib/styles/github/endpoints.txt
|
|
@@ -2600,9 +947,8 @@ function generateCode(config) {
|
|
|
2600
947
|
});
|
|
2601
948
|
});
|
|
2602
949
|
const groups = {};
|
|
2603
|
-
const outputs = {};
|
|
2604
950
|
const endpoints = {};
|
|
2605
|
-
|
|
951
|
+
forEachOperation(config.spec, (entry, operation) => {
|
|
2606
952
|
console.log(`Processing ${entry.method} ${entry.path}`);
|
|
2607
953
|
groups[entry.groupName] ??= [];
|
|
2608
954
|
endpoints[entry.groupName] ??= [];
|
|
@@ -2621,7 +967,7 @@ function generateCode(config) {
|
|
|
2621
967
|
additionalProperties[param.name] = param;
|
|
2622
968
|
}
|
|
2623
969
|
const securitySchemes = config.spec.components?.securitySchemes ?? {};
|
|
2624
|
-
const securityOptions =
|
|
970
|
+
const securityOptions = securityToOptions(
|
|
2625
971
|
config.spec,
|
|
2626
972
|
operation.security ?? [],
|
|
2627
973
|
securitySchemes
|
|
@@ -2649,67 +995,43 @@ function generateCode(config) {
|
|
|
2649
995
|
"application/xml": "xml",
|
|
2650
996
|
"text/plain": "text"
|
|
2651
997
|
};
|
|
2652
|
-
let outgoingContentType;
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
)
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
let objectSchema = ctSchema;
|
|
998
|
+
let outgoingContentType = "empty";
|
|
999
|
+
for (const type in operation.requestBody.content) {
|
|
1000
|
+
let objectSchema = resolveRef(
|
|
1001
|
+
config.spec,
|
|
1002
|
+
operation.requestBody.content[type].schema
|
|
1003
|
+
);
|
|
1004
|
+
if (type === "application/empty") {
|
|
1005
|
+
objectSchema = {
|
|
1006
|
+
type: "object",
|
|
1007
|
+
// properties: objectSchema['x-properties'],
|
|
1008
|
+
additionalProperties: isEmpty2(objectSchema["x-properties"])
|
|
1009
|
+
};
|
|
1010
|
+
} else {
|
|
2666
1011
|
if (objectSchema.type !== "object") {
|
|
2667
1012
|
objectSchema = {
|
|
2668
1013
|
type: "object",
|
|
2669
1014
|
required: [operation.requestBody.required ? "$body" : ""],
|
|
2670
1015
|
properties: {
|
|
2671
|
-
$body:
|
|
1016
|
+
$body: objectSchema
|
|
1017
|
+
// ...objectSchema['x-properties'],
|
|
2672
1018
|
}
|
|
2673
1019
|
};
|
|
2674
1020
|
}
|
|
2675
|
-
const schema = merge({}, objectSchema, {
|
|
2676
|
-
required: Object.values(additionalProperties).filter((p) => p.required).map((p) => p.name),
|
|
2677
|
-
properties: Object.entries(additionalProperties).reduce(
|
|
2678
|
-
(acc, [, p]) => ({
|
|
2679
|
-
...acc,
|
|
2680
|
-
[p.name]: p.schema
|
|
2681
|
-
}),
|
|
2682
|
-
{}
|
|
2683
|
-
)
|
|
2684
|
-
});
|
|
2685
|
-
Object.assign(inputs, bodyInputs(config, objectSchema));
|
|
2686
|
-
schemas[shortContenTypeMap[type]] = zodDeserialzer.handle(schema, true);
|
|
2687
|
-
}
|
|
2688
|
-
if (operation.requestBody.content["application/json"]) {
|
|
2689
|
-
outgoingContentType = "json";
|
|
2690
|
-
} else if (operation.requestBody.content["application/x-www-form-urlencoded"]) {
|
|
2691
|
-
outgoingContentType = "urlencoded";
|
|
2692
|
-
} else if (operation.requestBody.content["multipart/form-data"]) {
|
|
2693
|
-
outgoingContentType = "formdata";
|
|
2694
|
-
} else {
|
|
2695
|
-
outgoingContentType = "json";
|
|
2696
1021
|
}
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
(acc, [, p]) => ({
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
},
|
|
2711
|
-
true
|
|
2712
|
-
);
|
|
1022
|
+
const schema = merge({}, objectSchema, {
|
|
1023
|
+
required: Object.values(additionalProperties).filter((p) => p.required).map((p) => p.name),
|
|
1024
|
+
properties: Object.entries(additionalProperties).reduce((acc, [, p]) => ({ ...acc, [p.name]: p.schema }), {})
|
|
1025
|
+
});
|
|
1026
|
+
Object.assign(inputs, bodyInputs(config.spec, objectSchema));
|
|
1027
|
+
schemas[shortContenTypeMap[type]] = zodDeserialzer.handle(schema, true);
|
|
1028
|
+
}
|
|
1029
|
+
if (operation.requestBody.content["application/json"]) {
|
|
1030
|
+
outgoingContentType = "json";
|
|
1031
|
+
} else if (operation.requestBody.content["application/x-www-form-urlencoded"]) {
|
|
1032
|
+
outgoingContentType = "urlencoded";
|
|
1033
|
+
} else if (operation.requestBody.content["multipart/form-data"]) {
|
|
1034
|
+
outgoingContentType = "formdata";
|
|
2713
1035
|
}
|
|
2714
1036
|
const endpoint = toEndpoint(
|
|
2715
1037
|
entry.groupName,
|
|
@@ -2718,78 +1040,30 @@ function generateCode(config) {
|
|
|
2718
1040
|
{
|
|
2719
1041
|
outgoingContentType,
|
|
2720
1042
|
name: operation.operationId,
|
|
2721
|
-
|
|
2722
|
-
|
|
1043
|
+
method: entry.method,
|
|
1044
|
+
path: entry.path,
|
|
2723
1045
|
schemas,
|
|
2724
1046
|
inputs
|
|
2725
1047
|
},
|
|
2726
1048
|
{ makeImport: config.makeImport, style: config.style }
|
|
2727
1049
|
);
|
|
2728
|
-
const output = [
|
|
2729
|
-
`import z from 'zod';`,
|
|
2730
|
-
`import type * as http from '${config.makeImport("../http/index")}';`
|
|
2731
|
-
];
|
|
2732
|
-
const responses = endpoint.responses.flatMap((it) => it.responses);
|
|
2733
|
-
const responsesImports = endpoint.responses.flatMap(
|
|
2734
|
-
(it) => Object.values(it.imports)
|
|
2735
|
-
);
|
|
2736
|
-
if (responses.length) {
|
|
2737
|
-
output.push(
|
|
2738
|
-
...responses.map(
|
|
2739
|
-
(it) => `${it.description ? `
|
|
2740
|
-
/**
|
|
2741
|
-
* ${it.description}
|
|
2742
|
-
*/
|
|
2743
|
-
` : ""} export type ${it.name} = ${it.schema};`
|
|
2744
|
-
)
|
|
2745
|
-
);
|
|
2746
|
-
} else {
|
|
2747
|
-
output.push(
|
|
2748
|
-
`export type ${pascalcase2(operation.operationId + " output")} = void;`
|
|
2749
|
-
);
|
|
2750
|
-
}
|
|
2751
|
-
output.unshift(...useImports(output.join(""), ...responsesImports));
|
|
2752
|
-
outputs[`${spinalcase2(operation.operationId)}.ts`] = output.join("\n");
|
|
2753
1050
|
endpoints[entry.groupName].push(endpoint);
|
|
2754
1051
|
groups[entry.groupName].push({
|
|
2755
1052
|
name: operation.operationId,
|
|
2756
|
-
type: "http",
|
|
2757
1053
|
inputs,
|
|
2758
1054
|
outgoingContentType,
|
|
2759
1055
|
schemas,
|
|
2760
|
-
|
|
1056
|
+
method: entry.method,
|
|
1057
|
+
path: entry.path
|
|
2761
1058
|
});
|
|
2762
1059
|
});
|
|
2763
|
-
const commonSchemas = Object.values(endpoints).reduce(
|
|
2764
|
-
(acc, endpoint) => ({
|
|
2765
|
-
...acc,
|
|
2766
|
-
...endpoint.reduce(
|
|
2767
|
-
(acc2, { responses }) => ({
|
|
2768
|
-
...acc2,
|
|
2769
|
-
...responses.reduce(
|
|
2770
|
-
(acc3, it) => ({ ...acc3, ...it.schemas }),
|
|
2771
|
-
{}
|
|
2772
|
-
)
|
|
2773
|
-
}),
|
|
2774
|
-
{}
|
|
2775
|
-
)
|
|
2776
|
-
}),
|
|
2777
|
-
{}
|
|
2778
|
-
);
|
|
2779
1060
|
const allSchemas = Object.keys(endpoints).map((it) => ({
|
|
2780
|
-
import: `import ${
|
|
2781
|
-
use: ` ...${
|
|
1061
|
+
import: `import ${camelcase2(it)} from './${config.makeImport(spinalcase(it))}';`,
|
|
1062
|
+
use: ` ...${camelcase2(it)}`
|
|
2782
1063
|
}));
|
|
2783
|
-
const imports = [
|
|
2784
|
-
'import z from "zod";',
|
|
2785
|
-
`import type { ParseError } from '${config.makeImport("../http/parser")}';`,
|
|
2786
|
-
`import type { ServerError } from '${config.makeImport("../http/response")}';`
|
|
2787
|
-
];
|
|
2788
1064
|
return {
|
|
2789
1065
|
groups,
|
|
2790
|
-
commonSchemas,
|
|
2791
1066
|
commonZod,
|
|
2792
|
-
outputs,
|
|
2793
1067
|
endpoints: {
|
|
2794
1068
|
[join("api", "endpoints.ts")]: `
|
|
2795
1069
|
|
|
@@ -2823,14 +1097,15 @@ ${allSchemas.map((it) => it.use).join(",\n")}
|
|
|
2823
1097
|
);
|
|
2824
1098
|
return [
|
|
2825
1099
|
[
|
|
2826
|
-
join("api", `${
|
|
1100
|
+
join("api", `${spinalcase(name)}.ts`),
|
|
2827
1101
|
`${[
|
|
2828
1102
|
...imps,
|
|
2829
1103
|
`import z from 'zod';`,
|
|
2830
1104
|
`import * as http from '${config.makeImport("../http/response")}';`,
|
|
1105
|
+
`import * as outputs from '${config.makeImport("../outputs/index")}';`,
|
|
2831
1106
|
`import { toRequest, json, urlencoded, empty, formdata, createUrl, type HeadersInit } from '${config.makeImport("../http/request")}';`,
|
|
2832
1107
|
`import { chunked, buffered } from "${config.makeImport("../http/parse-response")}";`,
|
|
2833
|
-
`import * as ${
|
|
1108
|
+
`import * as ${camelcase2(name)} from '../inputs/${config.makeImport(spinalcase(name))}';`,
|
|
2834
1109
|
`import { createBaseUrlInterceptor, createHeadersInterceptor, type Interceptor } from '${config.makeImport("../http/interceptors")}';`,
|
|
2835
1110
|
`import { Dispatcher, fetchType, type InstanceType } from '${config.makeImport("../http/dispatcher")}';`,
|
|
2836
1111
|
`import { Pagination, OffsetPagination, CursorPagination } from "${config.makeImport("../pagination/index")}";`
|
|
@@ -2848,8 +1123,8 @@ ${endpoint.flatMap((it) => it.schemas).join(",\n")}
|
|
|
2848
1123
|
};
|
|
2849
1124
|
}
|
|
2850
1125
|
function toProps(spec, schemaOrRef, aggregator = []) {
|
|
2851
|
-
if (
|
|
2852
|
-
const schema =
|
|
1126
|
+
if (isRef4(schemaOrRef)) {
|
|
1127
|
+
const schema = followRef4(spec, schemaOrRef.$ref);
|
|
2853
1128
|
return toProps(spec, schema, aggregator);
|
|
2854
1129
|
} else if (schemaOrRef.type === "object") {
|
|
2855
1130
|
for (const [name] of Object.entries(schemaOrRef.properties ?? {})) {
|
|
@@ -2878,9 +1153,9 @@ function toProps(spec, schemaOrRef, aggregator = []) {
|
|
|
2878
1153
|
console.warn("Unknown schema in body", schemaOrRef);
|
|
2879
1154
|
return void 0;
|
|
2880
1155
|
}
|
|
2881
|
-
function bodyInputs(
|
|
1156
|
+
function bodyInputs(spec, ctSchema) {
|
|
2882
1157
|
const props = [];
|
|
2883
|
-
toProps(
|
|
1158
|
+
toProps(spec, ctSchema, props);
|
|
2884
1159
|
return props.reduce(
|
|
2885
1160
|
(acc, prop) => ({
|
|
2886
1161
|
...acc,
|
|
@@ -3140,6 +1415,28 @@ export class Gone<T = { message: string }> extends APIError<T, 410> {
|
|
|
3140
1415
|
return typeof value === 'object' && value !== null && KIND in value && value[KIND] === this.kind;
|
|
3141
1416
|
}
|
|
3142
1417
|
}
|
|
1418
|
+
export class PreconditionFailed<T = { message: string }> extends APIError<T, 412> {
|
|
1419
|
+
static override readonly kind = Symbol.for('PreconditionFailed');
|
|
1420
|
+
static override status = 412 as const;
|
|
1421
|
+
constructor(data: T) {
|
|
1422
|
+
super(PreconditionFailed.status, data);
|
|
1423
|
+
}
|
|
1424
|
+
static override create<T>(status: number, data: T) {
|
|
1425
|
+
Object.defineProperty(data, KIND, { value: this.kind });
|
|
1426
|
+
return new this(data);
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
static is<T extends { [KIND]: (typeof PreconditionFailed)['kind'] }>(
|
|
1430
|
+
value: unknown,
|
|
1431
|
+
): value is T {
|
|
1432
|
+
return (
|
|
1433
|
+
typeof value === 'object' &&
|
|
1434
|
+
value !== null &&
|
|
1435
|
+
KIND in value &&
|
|
1436
|
+
value[KIND] === this.kind
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
3143
1440
|
export class UnprocessableEntity<
|
|
3144
1441
|
T = { message: string; errors?: Record<string, string[]> },
|
|
3145
1442
|
> extends APIError<T, 422> {
|
|
@@ -3291,7 +1588,7 @@ export class GatewayTimeout<T = { message: string }> extends APIError<T, 504> {
|
|
|
3291
1588
|
}
|
|
3292
1589
|
|
|
3293
1590
|
export type ClientError =
|
|
3294
|
-
| BadRequest<
|
|
1591
|
+
| BadRequest<unknown>
|
|
3295
1592
|
| Unauthorized<unknown>
|
|
3296
1593
|
| PaymentRequired<unknown>
|
|
3297
1594
|
| Forbidden<unknown>
|
|
@@ -3300,6 +1597,9 @@ export type ClientError =
|
|
|
3300
1597
|
| NotAcceptable<unknown>
|
|
3301
1598
|
| Conflict<unknown>
|
|
3302
1599
|
| Gone<unknown>
|
|
1600
|
+
| PreconditionFailed<unknown>
|
|
1601
|
+
| PayloadTooLarge<unknown>
|
|
1602
|
+
| UnsupportedMediaType<unknown>
|
|
3303
1603
|
| UnprocessableEntity<unknown>
|
|
3304
1604
|
| TooManyRequests<unknown>;
|
|
3305
1605
|
|
|
@@ -3316,8 +1616,7 @@ export type SuccessfulResponse =
|
|
|
3316
1616
|
| Ok<unknown>
|
|
3317
1617
|
| Created<unknown>
|
|
3318
1618
|
| Accepted<unknown>
|
|
3319
|
-
| NoContent
|
|
3320
|
-
`;
|
|
1619
|
+
| NoContent;`;
|
|
3321
1620
|
|
|
3322
1621
|
// packages/typescript/src/lib/paginations/cursor-pagination.txt
|
|
3323
1622
|
var cursor_pagination_default = "type CursorPaginationParams = {\n cursor?: string;\n};\n\ninterface CursorMetadata extends Metadata {\n nextCursor?: string;\n}\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationResult<T, M extends CursorMetadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<T, M extends CursorMetadata> = (\n input: CursorPaginationParams,\n) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class CursorPagination<T, M extends CursorMetadata> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: CursorPaginationParams;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M>;\n\n constructor(\n initialParams: PartialNullable<CursorPaginationParams>,\n fetchFn: FetchFn<T, M>,\n ) {\n this.#fetchFn = fetchFn;\n this.#params = {\n cursor: initialParams.cursor ?? undefined,\n };\n }\n\n async getNextPage() {\n const result = await this.#fetchFn(this.#params);\n this.#currentPage = new Page(result.data);\n this.#meta = result.meta;\n this.#params = {\n ...this.#params,\n cursor: result.meta.nextCursor,\n };\n return this;\n }\n\n getCurrentPage() {\n if (!this.#currentPage) {\n throw new Error(\n 'No page data available. Please call getNextPage() first.',\n );\n }\n return this.#currentPage;\n }\n\n get hasMore() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta.hasMore;\n }\n\n async *[Symbol.asyncIterator]() {\n for await (const page of this.iter()) {\n yield page.getCurrentPage();\n }\n }\n\n async *iter() {\n if (!this.#currentPage) {\n yield await this.getNextPage();\n }\n\n while (this.hasMore) {\n yield await this.getNextPage();\n }\n }\n\n get metadata() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n\ntype PartialNullable<T> = {\n [K in keyof T]?: T[K] | null;\n};\n";
|
|
@@ -3329,11 +1628,15 @@ var offset_pagination_default = "type OffsetPaginationParams = {\n offset: numb
|
|
|
3329
1628
|
var page_pagination_default = "type InferPage<T> = T extends Page<infer U> ? U : never;\ntype PaginationParams<P extends number | bigint, S extends number | bigint> = {\n page?: P;\n pageSize?: S;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> = (input: Partial<PaginationParams<P, S>>) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class Pagination<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: PaginationParams<P, S>;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M, P, S>;\n\n constructor(\n initialParams: Partial<PaginationParams<P, S>>,\n fetchFn: FetchFn<T, M, P, S>,\n ) {\n this.#fetchFn = fetchFn;\n this.#params = { ...initialParams, page: initialParams.page };\n }\n\n async getNextPage() {\n const result = await this.#fetchFn(this.#params);\n this.#currentPage = new Page(result.data);\n this.#meta = result.meta;\n this.#params = {\n ...this.#params,\n page: ((this.#params.page as number) || 0 + 1) as never,\n };\n return this;\n }\n\n getCurrentPage() {\n if (!this.#currentPage) {\n throw new Error(\n 'No page data available. Please call getNextPage() first.',\n );\n }\n return this.#currentPage;\n }\n\n get hasMore() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta.hasMore;\n }\n\n async *[Symbol.asyncIterator]() {\n for await (const page of this.iter()) {\n yield page.getCurrentPage();\n }\n }\n\n async *iter() {\n if (!this.#currentPage) {\n yield await this.getNextPage();\n }\n\n while (this.hasMore) {\n yield await this.getNextPage();\n }\n }\n\n get metadata() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n";
|
|
3330
1629
|
|
|
3331
1630
|
// packages/typescript/src/lib/typescript-snippet.ts
|
|
3332
|
-
import { camelcase as
|
|
3333
|
-
import {
|
|
1631
|
+
import { camelcase as camelcase3, spinalcase as spinalcase2 } from "stringcase";
|
|
1632
|
+
import { isEmpty as isEmpty3, pascalcase as pascalcase4, resolveRef as resolveRef2 } from "@sdk-it/core";
|
|
1633
|
+
import {
|
|
1634
|
+
patchParameters,
|
|
1635
|
+
securityToOptions as securityToOptions2
|
|
1636
|
+
} from "@sdk-it/spec";
|
|
3334
1637
|
|
|
3335
1638
|
// packages/typescript/src/lib/emitters/snippet.ts
|
|
3336
|
-
import { followRef as
|
|
1639
|
+
import { followRef as followRef5, isRef as isRef5 } from "@sdk-it/core";
|
|
3337
1640
|
var SnippetEmitter = class {
|
|
3338
1641
|
spec;
|
|
3339
1642
|
generatedRefs = /* @__PURE__ */ new Set();
|
|
@@ -3342,12 +1645,12 @@ var SnippetEmitter = class {
|
|
|
3342
1645
|
this.spec = spec;
|
|
3343
1646
|
}
|
|
3344
1647
|
object(schema) {
|
|
3345
|
-
const schemaObj =
|
|
1648
|
+
const schemaObj = isRef5(schema) ? followRef5(this.spec, schema.$ref) : schema;
|
|
3346
1649
|
const result = {};
|
|
3347
1650
|
const properties = schemaObj.properties || {};
|
|
3348
1651
|
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
3349
1652
|
const isRequired = (schemaObj.required ?? []).includes(propName);
|
|
3350
|
-
const resolvedProp =
|
|
1653
|
+
const resolvedProp = isRef5(propSchema) ? followRef5(this.spec, propSchema.$ref) : propSchema;
|
|
3351
1654
|
if (isRequired || resolvedProp.example !== void 0 || resolvedProp.default !== void 0 || Math.random() > 0.5) {
|
|
3352
1655
|
result[propName] = this.handle(propSchema);
|
|
3353
1656
|
}
|
|
@@ -3360,7 +1663,7 @@ var SnippetEmitter = class {
|
|
|
3360
1663
|
return result;
|
|
3361
1664
|
}
|
|
3362
1665
|
array(schema) {
|
|
3363
|
-
const schemaObj =
|
|
1666
|
+
const schemaObj = isRef5(schema) ? followRef5(this.spec, schema.$ref) : schema;
|
|
3364
1667
|
const itemsSchema = schemaObj.items;
|
|
3365
1668
|
if (!itemsSchema) {
|
|
3366
1669
|
return [];
|
|
@@ -3400,7 +1703,7 @@ var SnippetEmitter = class {
|
|
|
3400
1703
|
return "example.com";
|
|
3401
1704
|
case "binary":
|
|
3402
1705
|
case "byte":
|
|
3403
|
-
return
|
|
1706
|
+
return `new Blob(['example'], { type: 'text/plain' })`;
|
|
3404
1707
|
default:
|
|
3405
1708
|
if (schema.enum && schema.enum.length > 0) {
|
|
3406
1709
|
return String(schema.enum[0]);
|
|
@@ -3448,7 +1751,7 @@ var SnippetEmitter = class {
|
|
|
3448
1751
|
return this.cache.get($ref);
|
|
3449
1752
|
}
|
|
3450
1753
|
this.cache.set($ref, { _ref: refKey });
|
|
3451
|
-
const resolved =
|
|
1754
|
+
const resolved = followRef5(this.spec, $ref);
|
|
3452
1755
|
const result = this.handle(resolved);
|
|
3453
1756
|
this.cache.set($ref, result);
|
|
3454
1757
|
return result;
|
|
@@ -3477,10 +1780,10 @@ var SnippetEmitter = class {
|
|
|
3477
1780
|
return Array.isArray(schema.enum) && schema.enum.length > 0 ? schema.enum[0] : void 0;
|
|
3478
1781
|
}
|
|
3479
1782
|
handle(schemaOrRef) {
|
|
3480
|
-
if (
|
|
1783
|
+
if (isRef5(schemaOrRef)) {
|
|
3481
1784
|
return this.ref(schemaOrRef.$ref);
|
|
3482
1785
|
}
|
|
3483
|
-
const schema =
|
|
1786
|
+
const schema = isRef5(schemaOrRef) ? followRef5(this.spec, schemaOrRef.$ref) : schemaOrRef;
|
|
3484
1787
|
if (schema.example !== void 0) {
|
|
3485
1788
|
return schema.example;
|
|
3486
1789
|
}
|
|
@@ -3540,53 +1843,39 @@ var TypeScriptGenerator = class {
|
|
|
3540
1843
|
this.#spec = spec;
|
|
3541
1844
|
this.#settings = settings;
|
|
3542
1845
|
this.#snippetEmitter = new SnippetEmitter(spec);
|
|
3543
|
-
this.#clientName = settings.name?.trim() ?
|
|
3544
|
-
this.#packageName = settings.name ? `@${
|
|
1846
|
+
this.#clientName = settings.name?.trim() ? pascalcase4(settings.name) : "Client";
|
|
1847
|
+
this.#packageName = settings.name ? `@${spinalcase2(this.#clientName.toLowerCase())}/sdk` : "sdk";
|
|
3545
1848
|
}
|
|
3546
1849
|
succinct(entry, operation, values) {
|
|
3547
1850
|
let payload = "{}";
|
|
3548
|
-
if (!
|
|
1851
|
+
if (!isEmpty3(operation.requestBody)) {
|
|
3549
1852
|
const contentTypes = Object.keys(operation.requestBody.content || {});
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
if (schema.type !== "object") {
|
|
3555
|
-
schema = {
|
|
3556
|
-
type: "object",
|
|
3557
|
-
required: [operation.requestBody.required ? "$body" : ""],
|
|
3558
|
-
properties: {
|
|
3559
|
-
$body: schema
|
|
3560
|
-
}
|
|
3561
|
-
};
|
|
3562
|
-
}
|
|
3563
|
-
const properties = {};
|
|
3564
|
-
patchParameters(
|
|
3565
|
-
this.#spec,
|
|
3566
|
-
{ type: "object", properties },
|
|
3567
|
-
operation
|
|
3568
|
-
);
|
|
3569
|
-
const examplePayload = this.#snippetEmitter.handle({
|
|
3570
|
-
...schema,
|
|
3571
|
-
properties: Object.assign({}, properties, schema.properties)
|
|
3572
|
-
});
|
|
3573
|
-
Object.assign(
|
|
3574
|
-
examplePayload,
|
|
3575
|
-
values.requestBody ?? {},
|
|
3576
|
-
values.pathParameters ?? {},
|
|
3577
|
-
values.queryParameters ?? {},
|
|
3578
|
-
values.headers ?? {},
|
|
3579
|
-
values.cookies ?? {}
|
|
3580
|
-
);
|
|
3581
|
-
payload = JSON.stringify(examplePayload, null, 2);
|
|
3582
|
-
}
|
|
3583
|
-
}
|
|
3584
|
-
} else {
|
|
3585
|
-
const properties = {};
|
|
3586
|
-
patchParameters(this.#spec, { type: "object", properties }, operation);
|
|
1853
|
+
const schema = resolveRef2(
|
|
1854
|
+
this.#spec,
|
|
1855
|
+
operation.requestBody.content[contentTypes[0]].schema
|
|
1856
|
+
);
|
|
3587
1857
|
const examplePayload = this.#snippetEmitter.handle({
|
|
3588
|
-
|
|
1858
|
+
...schema,
|
|
1859
|
+
properties: Object.assign({}, schema.properties, schema.properties)
|
|
3589
1860
|
});
|
|
1861
|
+
Object.assign(
|
|
1862
|
+
examplePayload,
|
|
1863
|
+
values.requestBody ?? {},
|
|
1864
|
+
values.pathParameters ?? {},
|
|
1865
|
+
values.queryParameters ?? {},
|
|
1866
|
+
values.headers ?? {},
|
|
1867
|
+
values.cookies ?? {}
|
|
1868
|
+
);
|
|
1869
|
+
payload = examplePayload;
|
|
1870
|
+
} else {
|
|
1871
|
+
const requestBody = { type: "object", properties: {} };
|
|
1872
|
+
patchParameters(
|
|
1873
|
+
this.#spec,
|
|
1874
|
+
requestBody,
|
|
1875
|
+
operation.parameters,
|
|
1876
|
+
operation.security ?? []
|
|
1877
|
+
);
|
|
1878
|
+
const examplePayload = this.#snippetEmitter.handle(requestBody);
|
|
3590
1879
|
Object.assign(
|
|
3591
1880
|
examplePayload,
|
|
3592
1881
|
values.pathParameters ?? {},
|
|
@@ -3594,48 +1883,138 @@ var TypeScriptGenerator = class {
|
|
|
3594
1883
|
values.headers ?? {},
|
|
3595
1884
|
values.cookies ?? {}
|
|
3596
1885
|
);
|
|
3597
|
-
payload =
|
|
1886
|
+
payload = examplePayload;
|
|
1887
|
+
}
|
|
1888
|
+
payload = JSON.stringify(
|
|
1889
|
+
payload,
|
|
1890
|
+
(key, value) => {
|
|
1891
|
+
if (value?.startsWith && value.startsWith("new")) {
|
|
1892
|
+
return `__REPLACE_${Math.random().toString(36).substring(2, 11)}__${value}__REPLACE_END__`;
|
|
1893
|
+
}
|
|
1894
|
+
return value;
|
|
1895
|
+
},
|
|
1896
|
+
2
|
|
1897
|
+
).replace(/"__REPLACE_[^"]*__([^"]*?)__REPLACE_END__"/g, "$1");
|
|
1898
|
+
let successResponse;
|
|
1899
|
+
for (const status in operation.responses) {
|
|
1900
|
+
if (status.startsWith("2")) {
|
|
1901
|
+
successResponse = operation.responses[status];
|
|
1902
|
+
break;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
if (successResponse) {
|
|
1906
|
+
if (successResponse.headers?.["Transfer-Encoding"]) {
|
|
1907
|
+
return this.#httpStreaming(entry, payload);
|
|
1908
|
+
}
|
|
1909
|
+
if (successResponse.content && successResponse.content["application/octet-stream"]) {
|
|
1910
|
+
return this.#streamDownload(entry, payload);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
if (!isEmpty3(operation["x-pagination"])) {
|
|
1914
|
+
return this.#pagination(operation, entry, payload);
|
|
3598
1915
|
}
|
|
3599
|
-
return
|
|
1916
|
+
return this.#normal(entry, payload);
|
|
3600
1917
|
}
|
|
3601
|
-
|
|
3602
|
-
const
|
|
3603
|
-
|
|
3604
|
-
"
|
|
3605
|
-
|
|
3606
|
-
${payload}
|
|
3607
|
-
|
|
3608
|
-
console.log(
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
1918
|
+
#pagination(opeartion, entry, payload) {
|
|
1919
|
+
const pagination = opeartion["x-pagination"];
|
|
1920
|
+
switch (pagination.type) {
|
|
1921
|
+
case "page":
|
|
1922
|
+
return {
|
|
1923
|
+
content: `const result = ${this.#ddd(entry, payload)}`,
|
|
1924
|
+
footer: `for await (const page of result) {
|
|
1925
|
+
console.log(page);
|
|
1926
|
+
}`
|
|
1927
|
+
};
|
|
1928
|
+
case "offset":
|
|
1929
|
+
return {
|
|
1930
|
+
content: `const result = ${this.#ddd(entry, payload)}`,
|
|
1931
|
+
footer: `for await (const page of result) {
|
|
1932
|
+
console.log(page);
|
|
1933
|
+
}`
|
|
1934
|
+
};
|
|
1935
|
+
case "cursor":
|
|
1936
|
+
return {
|
|
1937
|
+
content: `const result = ${this.#ddd(entry, payload)}`,
|
|
1938
|
+
footer: `for await (const page of result) {
|
|
1939
|
+
console.log(page);
|
|
1940
|
+
}`
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
return this.#normal(entry, payload);
|
|
1944
|
+
}
|
|
1945
|
+
#normal(entry, payload) {
|
|
1946
|
+
return {
|
|
1947
|
+
content: `const result = ${this.#ddd(entry, payload)};`,
|
|
1948
|
+
footer: "console.log(result.data)"
|
|
1949
|
+
};
|
|
1950
|
+
}
|
|
1951
|
+
#streamDownload(entry, payload) {
|
|
1952
|
+
return {
|
|
1953
|
+
content: `const stream = ${this.#ddd(entry, payload)}`,
|
|
1954
|
+
footer: `await writeFile('./report.pdf', stream);`
|
|
1955
|
+
};
|
|
1956
|
+
}
|
|
1957
|
+
#httpStreaming(entry, payload) {
|
|
1958
|
+
return {
|
|
1959
|
+
content: `const stream = ${this.#ddd(entry, payload)}`,
|
|
1960
|
+
footer: `for await (const chunk of stream) {
|
|
1961
|
+
console.log(chunk);
|
|
1962
|
+
}`
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
#ddd(entry, payload) {
|
|
1966
|
+
return `await ${camelcase3(this.#clientName)}.request('${entry.method.toUpperCase()} ${entry.path}', ${payload});`;
|
|
1967
|
+
}
|
|
1968
|
+
snippet(entry, operation, config = {}) {
|
|
1969
|
+
const payload = this.succinct(entry, operation, config);
|
|
1970
|
+
const content = [
|
|
1971
|
+
this.client(),
|
|
1972
|
+
"",
|
|
1973
|
+
payload.content,
|
|
1974
|
+
"",
|
|
1975
|
+
payload.footer
|
|
1976
|
+
];
|
|
1977
|
+
if (config.frame !== false) {
|
|
1978
|
+
content.unshift("```typescript");
|
|
1979
|
+
content.push("```");
|
|
1980
|
+
}
|
|
1981
|
+
return content.join("\n");
|
|
1982
|
+
}
|
|
1983
|
+
#authentication() {
|
|
1984
|
+
return securityToOptions2(
|
|
1985
|
+
this.#spec,
|
|
1986
|
+
this.#spec.security ?? [],
|
|
1987
|
+
this.#spec.components?.securitySchemes ?? {}
|
|
1988
|
+
);
|
|
3612
1989
|
}
|
|
3613
1990
|
client() {
|
|
1991
|
+
const inputs = [
|
|
1992
|
+
`baseUrl: '${this.#spec.servers?.[0]?.url ?? "http://localhost:3000"}'`
|
|
1993
|
+
];
|
|
1994
|
+
const authOptions = this.#authentication();
|
|
1995
|
+
if (!isEmpty3(authOptions)) {
|
|
1996
|
+
const [firstAuth] = authOptions;
|
|
1997
|
+
inputs.push(`${firstAuth.name}: ${firstAuth.example}`);
|
|
1998
|
+
}
|
|
3614
1999
|
return `import { ${this.#clientName} } from '${this.#packageName}';
|
|
3615
2000
|
|
|
3616
|
-
const ${
|
|
3617
|
-
|
|
2001
|
+
const ${camelcase3(this.#clientName)} = new ${this.#clientName}({
|
|
2002
|
+
${inputs.join(",\n ")}
|
|
3618
2003
|
});`;
|
|
3619
2004
|
}
|
|
3620
2005
|
};
|
|
2006
|
+
function generateSnippet(spec, settings, entry, operation, config = {}) {
|
|
2007
|
+
const generator = new TypeScriptGenerator(spec, settings);
|
|
2008
|
+
return generator.snippet(entry, operation, config);
|
|
2009
|
+
}
|
|
3621
2010
|
|
|
3622
2011
|
// packages/typescript/src/lib/generate.ts
|
|
3623
|
-
var ALWAYS_AVAILABLE_FILES = [
|
|
3624
|
-
/readme\.md$/i,
|
|
3625
|
-
// match readme.md, case-insensitive
|
|
3626
|
-
/^tsconfig.*\.json$/,
|
|
3627
|
-
// match any tsconfig*.json
|
|
3628
|
-
/package\.json$/,
|
|
3629
|
-
// exact package.json
|
|
3630
|
-
/metadata\.json$/
|
|
3631
|
-
// exact metadata.json
|
|
3632
|
-
];
|
|
3633
2012
|
function security(spec) {
|
|
3634
2013
|
const security2 = spec.security || [];
|
|
3635
2014
|
const components = spec.components || {};
|
|
3636
2015
|
const securitySchemes = components.securitySchemes || {};
|
|
3637
2016
|
const paths = Object.values(spec.paths ?? {});
|
|
3638
|
-
const options =
|
|
2017
|
+
const options = securityToOptions(spec, security2, securitySchemes);
|
|
3639
2018
|
for (const it of paths) {
|
|
3640
2019
|
for (const method of methods) {
|
|
3641
2020
|
const operation = it[method];
|
|
@@ -3644,7 +2023,7 @@ function security(spec) {
|
|
|
3644
2023
|
}
|
|
3645
2024
|
Object.assign(
|
|
3646
2025
|
options,
|
|
3647
|
-
|
|
2026
|
+
securityToOptions(
|
|
3648
2027
|
spec,
|
|
3649
2028
|
operation.security || [],
|
|
3650
2029
|
securitySchemes,
|
|
@@ -3655,13 +2034,16 @@ function security(spec) {
|
|
|
3655
2034
|
}
|
|
3656
2035
|
return options;
|
|
3657
2036
|
}
|
|
3658
|
-
async function generate(
|
|
3659
|
-
spec =
|
|
2037
|
+
async function generate(openapi, settings) {
|
|
2038
|
+
const spec = augmentSpec(
|
|
2039
|
+
{ spec: openapi, responses: { flattenErrorResponses: true } },
|
|
2040
|
+
false
|
|
2041
|
+
);
|
|
3660
2042
|
const generator = new TypeScriptGenerator(spec, settings);
|
|
3661
2043
|
const style = Object.assign(
|
|
3662
2044
|
{},
|
|
3663
2045
|
{
|
|
3664
|
-
errorAsValue:
|
|
2046
|
+
errorAsValue: false,
|
|
3665
2047
|
name: "github",
|
|
3666
2048
|
outputType: "default"
|
|
3667
2049
|
},
|
|
@@ -3669,19 +2051,11 @@ async function generate(spec, settings) {
|
|
|
3669
2051
|
);
|
|
3670
2052
|
const output = settings.mode === "full" ? join2(settings.output, "src") : settings.output;
|
|
3671
2053
|
settings.useTsExtension ??= true;
|
|
3672
|
-
const
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
for (const file of Object.keys(contents)) {
|
|
3678
|
-
if (contents[file] !== null) {
|
|
3679
|
-
writtenFiles.add(
|
|
3680
|
-
addLeadingSlash(`${relative(settings.output, dir)}/${file}`)
|
|
3681
|
-
);
|
|
3682
|
-
}
|
|
3683
|
-
}
|
|
3684
|
-
};
|
|
2054
|
+
const { writer, files: writtenFiles } = createWriterProxy(
|
|
2055
|
+
settings.writer ?? writeFiles,
|
|
2056
|
+
output
|
|
2057
|
+
);
|
|
2058
|
+
settings.writer = writer;
|
|
3685
2059
|
settings.readFolder ??= async (folder) => {
|
|
3686
2060
|
const files = await readdir(folder, { withFileTypes: true });
|
|
3687
2061
|
return files.map((file) => ({
|
|
@@ -3693,17 +2067,16 @@ async function generate(spec, settings) {
|
|
|
3693
2067
|
const makeImport = (moduleSpecifier) => {
|
|
3694
2068
|
return settings.useTsExtension ? `${moduleSpecifier}.ts` : moduleSpecifier;
|
|
3695
2069
|
};
|
|
3696
|
-
const {
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
}
|
|
3702
|
-
);
|
|
2070
|
+
const { endpoints, groups, commonZod } = generateCode({
|
|
2071
|
+
spec,
|
|
2072
|
+
style,
|
|
2073
|
+
makeImport
|
|
2074
|
+
});
|
|
3703
2075
|
const options = security(spec);
|
|
3704
|
-
const clientName =
|
|
3705
|
-
const packageName = settings.name ? `@${
|
|
3706
|
-
const
|
|
2076
|
+
const clientName = pascalcase5((settings.name || "client").trim());
|
|
2077
|
+
const packageName = settings.name ? `@${spinalcase3(settings.name.trim().toLowerCase())}/sdk` : "sdk";
|
|
2078
|
+
const inputs = toInputs(groups, commonZod, makeImport);
|
|
2079
|
+
const models = serializeModels(spec);
|
|
3707
2080
|
await settings.writer(output, {
|
|
3708
2081
|
"outputs/.gitkeep": "",
|
|
3709
2082
|
"inputs/.gitkeep": "",
|
|
@@ -3725,8 +2098,6 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
|
|
|
3725
2098
|
import type { RequestConfig, HeadersInit } from './${makeImport("request")}';
|
|
3726
2099
|
${interceptors_default}`
|
|
3727
2100
|
});
|
|
3728
|
-
await settings.writer(join2(output, "outputs"), outputs);
|
|
3729
|
-
const modelsImports = Object.entries(commonSchemas).map(([name]) => name);
|
|
3730
2101
|
await settings.writer(output, {
|
|
3731
2102
|
"client.ts": client_default(
|
|
3732
2103
|
{
|
|
@@ -3737,45 +2108,23 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
|
|
|
3737
2108
|
},
|
|
3738
2109
|
style
|
|
3739
2110
|
),
|
|
3740
|
-
...
|
|
3741
|
-
...endpoints
|
|
3742
|
-
...Object.fromEntries(
|
|
3743
|
-
Object.entries(commonSchemas).map(([name, schema]) => [
|
|
3744
|
-
`models/${name}.ts`,
|
|
3745
|
-
[
|
|
3746
|
-
`import { z } from 'zod';`,
|
|
3747
|
-
...exclude(modelsImports, [name]).map(
|
|
3748
|
-
(it) => `import type { ${it} } from './${it}.ts';`
|
|
3749
|
-
),
|
|
3750
|
-
`export type ${name} = ${schema};`
|
|
3751
|
-
].join("\n")
|
|
3752
|
-
])
|
|
3753
|
-
)
|
|
2111
|
+
...inputs,
|
|
2112
|
+
...endpoints
|
|
3754
2113
|
});
|
|
2114
|
+
await settings.writer(output, models);
|
|
3755
2115
|
await settings.writer(join2(output, "pagination"), {
|
|
3756
2116
|
"cursor-pagination.ts": cursor_pagination_default,
|
|
3757
2117
|
"offset-pagination.ts": offset_pagination_default,
|
|
3758
2118
|
"page-pagination.ts": page_pagination_default
|
|
3759
2119
|
});
|
|
3760
|
-
const metadata = await
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
const actualFiles = await readFolder(settings.output, true);
|
|
3769
|
-
const toRemove = actualFiles.filter((f) => !keep.has(addLeadingSlash(f))).filter(
|
|
3770
|
-
(f) => !ALWAYS_AVAILABLE_FILES.some((pattern) => pattern.test(f))
|
|
3771
|
-
);
|
|
3772
|
-
for (const file of toRemove) {
|
|
3773
|
-
if (file.endsWith(`${sep}index.ts`)) {
|
|
3774
|
-
continue;
|
|
3775
|
-
}
|
|
3776
|
-
const filePath = join2(settings.output, file);
|
|
3777
|
-
await unlink(filePath);
|
|
3778
|
-
}
|
|
2120
|
+
const metadata = await readWriteMetadata(output, Array.from(writtenFiles));
|
|
2121
|
+
if (settings.cleanup !== false && writtenFiles.size > 0) {
|
|
2122
|
+
await cleanFiles(metadata.content, output, [
|
|
2123
|
+
"/tsconfig*.json",
|
|
2124
|
+
"/package.json",
|
|
2125
|
+
"/metadata.json",
|
|
2126
|
+
"/**/index.ts"
|
|
2127
|
+
]);
|
|
3779
2128
|
}
|
|
3780
2129
|
const folders = [
|
|
3781
2130
|
getFolderExports(
|
|
@@ -3801,17 +2150,13 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
|
|
|
3801
2150
|
settings.useTsExtension,
|
|
3802
2151
|
["ts"],
|
|
3803
2152
|
(dirent) => !["response.ts", "parser.ts"].includes(dirent.fileName)
|
|
2153
|
+
),
|
|
2154
|
+
getFolderExports(
|
|
2155
|
+
join2(output, "models"),
|
|
2156
|
+
settings.readFolder,
|
|
2157
|
+
settings.useTsExtension
|
|
3804
2158
|
)
|
|
3805
2159
|
];
|
|
3806
|
-
if (modelsImports.length) {
|
|
3807
|
-
folders.push(
|
|
3808
|
-
getFolderExports(
|
|
3809
|
-
join2(output, "models"),
|
|
3810
|
-
settings.readFolder,
|
|
3811
|
-
settings.useTsExtension
|
|
3812
|
-
)
|
|
3813
|
-
);
|
|
3814
|
-
}
|
|
3815
2160
|
const [outputIndex, inputsIndex, apiIndex, httpIndex, modelsIndex] = await Promise.all(folders);
|
|
3816
2161
|
await settings.writer(join2(output, "pagination"), {
|
|
3817
2162
|
"index.ts": await getFolderExports(
|
|
@@ -3826,7 +2171,8 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
|
|
|
3826
2171
|
"outputs/index.ts": outputIndex,
|
|
3827
2172
|
"inputs/index.ts": inputsIndex || null,
|
|
3828
2173
|
"http/index.ts": httpIndex,
|
|
3829
|
-
|
|
2174
|
+
"models/index.ts": modelsIndex
|
|
2175
|
+
// ...(modelsImports.length ? { 'models/index.ts': modelsIndex } : {}),
|
|
3830
2176
|
});
|
|
3831
2177
|
await settings.writer(output, {
|
|
3832
2178
|
"index.ts": await getFolderExports(
|
|
@@ -3907,16 +2253,89 @@ ${template2(dispatcher_default, {})({ throwError: !style.errorAsValue, outputTyp
|
|
|
3907
2253
|
env: npmRunPathEnv()
|
|
3908
2254
|
});
|
|
3909
2255
|
}
|
|
3910
|
-
|
|
3911
|
-
const
|
|
2256
|
+
function serializeModels(spec) {
|
|
2257
|
+
const filesMap = {};
|
|
2258
|
+
const files = {};
|
|
2259
|
+
for (const [name, schema] of Object.entries(spec.components.schemas)) {
|
|
2260
|
+
const isResponseBody = schema["x-responsebody"];
|
|
2261
|
+
const isRequestBody = schema["x-requestbody"];
|
|
2262
|
+
const responseGroup = schema["x-response-group"];
|
|
2263
|
+
const stream = schema["x-stream"];
|
|
2264
|
+
const folder = isResponseBody ? "outputs" : "models";
|
|
2265
|
+
let typeContent = "ReadableStream";
|
|
2266
|
+
if (!stream) {
|
|
2267
|
+
const serializer = new TypeScriptEmitter(spec);
|
|
2268
|
+
typeContent = serializer.handle(schema, true);
|
|
2269
|
+
}
|
|
2270
|
+
const fileContent = [
|
|
2271
|
+
`
|
|
2272
|
+
${schema.description ? `
|
|
2273
|
+
/**
|
|
2274
|
+
* ${schema.description}
|
|
2275
|
+
*/
|
|
2276
|
+
` : ""}`,
|
|
2277
|
+
`export type ${pascalcase5(sanitizeTag4(name))} = ${typeContent};`
|
|
2278
|
+
];
|
|
2279
|
+
const fileName = responseGroup ? join2(folder, `${spinalcase3(responseGroup)}.ts`) : join2(folder, `${spinalcase3(name)}.ts`);
|
|
2280
|
+
filesMap[fileName] ??= [];
|
|
2281
|
+
filesMap[fileName].push(fileContent.join("\n"));
|
|
2282
|
+
}
|
|
2283
|
+
for (const [group, contents] of Object.entries(filesMap)) {
|
|
2284
|
+
let fileContent = contents.join("\n");
|
|
2285
|
+
if (fileContent.includes("models.")) {
|
|
2286
|
+
fileContent = `import type * as models from '../index.ts';
|
|
2287
|
+
${fileContent}`;
|
|
2288
|
+
}
|
|
2289
|
+
files[group] = fileContent;
|
|
2290
|
+
}
|
|
2291
|
+
return files;
|
|
2292
|
+
}
|
|
2293
|
+
function toInputs(operationsSet, commonZod, makeImport) {
|
|
2294
|
+
const commonImports = commonZod.keys().toArray();
|
|
2295
|
+
const inputs = {};
|
|
2296
|
+
for (const [name, operations] of Object.entries(operationsSet)) {
|
|
2297
|
+
const output = [];
|
|
2298
|
+
const imports = /* @__PURE__ */ new Set(['import { z } from "zod";']);
|
|
2299
|
+
for (const operation of operations) {
|
|
2300
|
+
const schemaName = camelcase4(`${operation.name} schema`);
|
|
2301
|
+
const schema = `export const ${schemaName} = ${Object.keys(operation.schemas).length === 1 ? Object.values(operation.schemas)[0] : toLitObject2(operation.schemas)};`;
|
|
2302
|
+
for (const it of commonImports) {
|
|
2303
|
+
if (schema.includes(it)) {
|
|
2304
|
+
imports.add(
|
|
2305
|
+
`import { ${it} } from './schemas/${makeImport(spinalcase3(it))}';`
|
|
2306
|
+
);
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
output.push(schema);
|
|
2310
|
+
}
|
|
2311
|
+
inputs[`inputs/${spinalcase3(name)}.ts`] = [...imports, ...output].join("\n") + "\n";
|
|
2312
|
+
}
|
|
2313
|
+
const schemas = commonZod.entries().reduce((acc, [name, schema]) => {
|
|
2314
|
+
const output = [`import { z } from 'zod';`];
|
|
2315
|
+
const content = `export const ${name} = ${schema};`;
|
|
2316
|
+
for (const schema2 of commonImports) {
|
|
2317
|
+
const preciseMatch = new RegExp(`\\b${schema2}\\b`);
|
|
2318
|
+
if (preciseMatch.test(content) && schema2 !== name) {
|
|
2319
|
+
output.push(
|
|
2320
|
+
`import { ${schema2} } from './${makeImport(spinalcase3(schema2))}';`
|
|
2321
|
+
);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
output.push(content);
|
|
2325
|
+
return [
|
|
2326
|
+
[`inputs/schemas/${spinalcase3(name)}.ts`, output.join("\n")],
|
|
2327
|
+
...acc
|
|
2328
|
+
];
|
|
2329
|
+
}, []);
|
|
3912
2330
|
return {
|
|
3913
|
-
|
|
3914
|
-
|
|
2331
|
+
...Object.fromEntries(schemas),
|
|
2332
|
+
...inputs
|
|
3915
2333
|
};
|
|
3916
2334
|
}
|
|
3917
2335
|
export {
|
|
3918
2336
|
TypeScriptGenerator,
|
|
3919
2337
|
generate,
|
|
3920
|
-
|
|
2338
|
+
generateSnippet,
|
|
2339
|
+
toInputs
|
|
3921
2340
|
};
|
|
3922
2341
|
//# sourceMappingURL=index.js.map
|