@sdk-it/dart 0.19.1 → 0.21.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/dist/index.js +1102 -125
- package/dist/index.js.map +4 -4
- package/dist/lib/generate.d.ts +3 -0
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/security.d.ts +3 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,30 +1,932 @@
|
|
|
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, pluralize2) {
|
|
39
|
+
if (typeof __require === "function" && typeof exports === "object" && typeof module === "object") {
|
|
40
|
+
module.exports = pluralize2();
|
|
41
|
+
} else if (typeof define === "function" && define.amd) {
|
|
42
|
+
define(function() {
|
|
43
|
+
return pluralize2();
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
root.pluralize = pluralize2();
|
|
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 pluralize2(word, count, inclusive) {
|
|
121
|
+
var pluralized = count === 1 ? pluralize2.singular(word) : pluralize2.plural(word);
|
|
122
|
+
return (inclusive ? count + " " : "") + pluralized;
|
|
123
|
+
}
|
|
124
|
+
pluralize2.plural = replaceWord(
|
|
125
|
+
irregularSingles,
|
|
126
|
+
irregularPlurals,
|
|
127
|
+
pluralRules
|
|
128
|
+
);
|
|
129
|
+
pluralize2.isPlural = checkWord(
|
|
130
|
+
irregularSingles,
|
|
131
|
+
irregularPlurals,
|
|
132
|
+
pluralRules
|
|
133
|
+
);
|
|
134
|
+
pluralize2.singular = replaceWord(
|
|
135
|
+
irregularPlurals,
|
|
136
|
+
irregularSingles,
|
|
137
|
+
singularRules
|
|
138
|
+
);
|
|
139
|
+
pluralize2.isSingular = checkWord(
|
|
140
|
+
irregularPlurals,
|
|
141
|
+
irregularSingles,
|
|
142
|
+
singularRules
|
|
143
|
+
);
|
|
144
|
+
pluralize2.addPluralRule = function(rule, replacement) {
|
|
145
|
+
pluralRules.push([sanitizeRule(rule), replacement]);
|
|
146
|
+
};
|
|
147
|
+
pluralize2.addSingularRule = function(rule, replacement) {
|
|
148
|
+
singularRules.push([sanitizeRule(rule), replacement]);
|
|
149
|
+
};
|
|
150
|
+
pluralize2.addUncountableRule = function(word) {
|
|
151
|
+
if (typeof word === "string") {
|
|
152
|
+
uncountables[word.toLowerCase()] = true;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
pluralize2.addPluralRule(word, "$0");
|
|
156
|
+
pluralize2.addSingularRule(word, "$0");
|
|
157
|
+
};
|
|
158
|
+
pluralize2.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 pluralize2.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 pluralize2.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 pluralize2.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(pluralize2.addUncountableRule);
|
|
387
|
+
return pluralize2;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
1
392
|
// packages/dart/src/lib/generate.ts
|
|
2
393
|
import { parse as partContentType } from "fast-content-type-parse";
|
|
3
394
|
import { merge as merge2 } from "lodash-es";
|
|
4
395
|
import assert2 from "node:assert";
|
|
5
|
-
import { writeFile } from "node:fs/promises";
|
|
396
|
+
import { readdir, writeFile } from "node:fs/promises";
|
|
6
397
|
import { join } from "node:path";
|
|
7
398
|
import { camelcase as camelcase3 } from "stringcase";
|
|
8
399
|
import yaml from "yaml";
|
|
9
400
|
import {
|
|
10
|
-
followRef as
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
isRef as isRef2,
|
|
401
|
+
followRef as followRef3,
|
|
402
|
+
isEmpty as isEmpty3,
|
|
403
|
+
isRef as isRef4,
|
|
14
404
|
notRef as notRef2,
|
|
15
405
|
pascalcase as pascalcase2,
|
|
16
|
-
snakecase as snakecase2
|
|
17
|
-
writeFiles
|
|
406
|
+
snakecase as snakecase2
|
|
18
407
|
} from "@sdk-it/core";
|
|
408
|
+
import {
|
|
409
|
+
getFolderExportsV2,
|
|
410
|
+
writeFiles
|
|
411
|
+
} from "@sdk-it/core/file-system.js";
|
|
19
412
|
|
|
20
|
-
// packages/spec/dist/lib/
|
|
21
|
-
import {
|
|
413
|
+
// packages/spec/dist/lib/operation.js
|
|
414
|
+
import { camelcase } from "stringcase";
|
|
415
|
+
import { followRef, isRef as isRef2 } from "@sdk-it/core/ref.js";
|
|
22
416
|
|
|
23
|
-
// packages/spec/dist/lib/
|
|
24
|
-
import {
|
|
417
|
+
// packages/spec/dist/lib/pagination/pagination.js
|
|
418
|
+
import { isRef } from "@sdk-it/core/ref.js";
|
|
419
|
+
import { isEmpty } from "@sdk-it/core/utils.js";
|
|
420
|
+
|
|
421
|
+
// packages/spec/dist/lib/pagination/pagination-result.js
|
|
422
|
+
var import_pluralize = __toESM(require_pluralize(), 1);
|
|
423
|
+
var PRIMARY_TOP_TIER_KEYWORDS = [
|
|
424
|
+
"data",
|
|
425
|
+
"items",
|
|
426
|
+
"results",
|
|
427
|
+
"value"
|
|
428
|
+
];
|
|
429
|
+
var PRIMARY_OTHER_KEYWORDS = [
|
|
430
|
+
"records",
|
|
431
|
+
"content",
|
|
432
|
+
"list",
|
|
433
|
+
"payload",
|
|
434
|
+
"entities",
|
|
435
|
+
"collection",
|
|
436
|
+
"users",
|
|
437
|
+
"products",
|
|
438
|
+
"orders",
|
|
439
|
+
"bookings",
|
|
440
|
+
"articles",
|
|
441
|
+
"posts",
|
|
442
|
+
"documents",
|
|
443
|
+
"events"
|
|
444
|
+
];
|
|
445
|
+
var SECONDARY_KEYWORDS = ["entries", "rows", "elements"];
|
|
446
|
+
var PLURAL_DEPRIORITIZE_LIST = [
|
|
447
|
+
"status",
|
|
448
|
+
"success",
|
|
449
|
+
"address",
|
|
450
|
+
"details",
|
|
451
|
+
"properties",
|
|
452
|
+
"params",
|
|
453
|
+
"headers",
|
|
454
|
+
"cookies",
|
|
455
|
+
"series",
|
|
456
|
+
"links",
|
|
457
|
+
"meta",
|
|
458
|
+
"metadata",
|
|
459
|
+
"statistics",
|
|
460
|
+
"settings",
|
|
461
|
+
"options",
|
|
462
|
+
"permissions",
|
|
463
|
+
"credentials",
|
|
464
|
+
"diagnostics",
|
|
465
|
+
"warnings",
|
|
466
|
+
"errors",
|
|
467
|
+
"actions",
|
|
468
|
+
"attributes",
|
|
469
|
+
"categories",
|
|
470
|
+
"features",
|
|
471
|
+
"includes",
|
|
472
|
+
"tags"
|
|
473
|
+
];
|
|
474
|
+
var HAS_MORE_PRIMARY_POSITIVE_EXACT = [
|
|
475
|
+
"hasmore",
|
|
476
|
+
"hasnext",
|
|
477
|
+
"hasnextpage",
|
|
478
|
+
"moreitems",
|
|
479
|
+
"moreitemsavailable",
|
|
480
|
+
"nextpage",
|
|
481
|
+
"nextpageexists",
|
|
482
|
+
"nextpageavailable",
|
|
483
|
+
"hasadditionalresults",
|
|
484
|
+
"moreresultsavailable",
|
|
485
|
+
"canloadmore",
|
|
486
|
+
"hasadditional",
|
|
487
|
+
"additionalitems",
|
|
488
|
+
"fetchmore"
|
|
489
|
+
];
|
|
490
|
+
var HAS_MORE_SECONDARY_POSITIVE_EXACT = ["more", "next"];
|
|
491
|
+
var HAS_MORE_PRIMARY_INVERTED_EXACT = [
|
|
492
|
+
"islast",
|
|
493
|
+
"lastpage",
|
|
494
|
+
"endofresults",
|
|
495
|
+
"endoflist",
|
|
496
|
+
"nomoreitems",
|
|
497
|
+
"nomoredata",
|
|
498
|
+
"allitemsloaded",
|
|
499
|
+
"iscomplete",
|
|
500
|
+
"completed"
|
|
501
|
+
];
|
|
502
|
+
var HAS_MORE_POSITIVE_REGEX_PATTERNS = [
|
|
503
|
+
"\\bhas_?more\\b",
|
|
504
|
+
"\\bhas_?next\\b",
|
|
505
|
+
// e.g., itemsHasNext, items_has_next
|
|
506
|
+
"\\bmore_?items\\b",
|
|
507
|
+
"\\bnext_?page\\b",
|
|
508
|
+
// e.g., userNextPageFlag
|
|
509
|
+
"\\badditional\\b",
|
|
510
|
+
// e.g., hasAdditionalData, additional_results_exist
|
|
511
|
+
"\\bcontinuation\\b",
|
|
512
|
+
// e.g., continuationAvailable, has_continuation_token
|
|
513
|
+
"\\bmore_?results\\b",
|
|
514
|
+
"\\bpage_?available\\b",
|
|
515
|
+
"\\bnext(?:_?(page))?\\b"
|
|
516
|
+
];
|
|
517
|
+
var COMPILED_HAS_MORE_POSITIVE_REGEXES = HAS_MORE_POSITIVE_REGEX_PATTERNS.map((p) => new RegExp(p, "i"));
|
|
518
|
+
var HAS_MORE_INVERTED_REGEX_PATTERNS = [
|
|
519
|
+
"\\bis_?last\\b",
|
|
520
|
+
// e.g., pageIsLast
|
|
521
|
+
"\\blast_?page\\b",
|
|
522
|
+
// e.g., resultsAreLastPage
|
|
523
|
+
"\\bend_?of_?(data|results|list|items|stream)\\b",
|
|
524
|
+
"\\bno_?more_?(items|data|results)?\\b",
|
|
525
|
+
"\\ball_?(items_?)?loaded\\b",
|
|
526
|
+
"\\bis_?complete\\b"
|
|
527
|
+
];
|
|
528
|
+
var COMPILED_HAS_MORE_INVERTED_REGEXES = HAS_MORE_INVERTED_REGEX_PATTERNS.map((p) => new RegExp(p, "i"));
|
|
529
|
+
function getItemsName(properties) {
|
|
530
|
+
const arrayPropertyNames = [];
|
|
531
|
+
for (const propName in properties) {
|
|
532
|
+
if (propName in properties) {
|
|
533
|
+
const propSchema = properties[propName];
|
|
534
|
+
if (propSchema && propSchema.type === "array") {
|
|
535
|
+
arrayPropertyNames.push(propName);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (arrayPropertyNames.length === 0) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
if (arrayPropertyNames.length === 1) {
|
|
543
|
+
return arrayPropertyNames[0];
|
|
544
|
+
}
|
|
545
|
+
let bestCandidate = null;
|
|
546
|
+
let candidateRank = Infinity;
|
|
547
|
+
const updateCandidate = (propName, rank) => {
|
|
548
|
+
if (rank < candidateRank) {
|
|
549
|
+
bestCandidate = propName;
|
|
550
|
+
candidateRank = rank;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
for (const propName of arrayPropertyNames) {
|
|
554
|
+
const lowerPropName = propName.toLowerCase();
|
|
555
|
+
if (PRIMARY_TOP_TIER_KEYWORDS.includes(lowerPropName)) {
|
|
556
|
+
updateCandidate(propName, 2);
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
if (candidateRank > 3 && PRIMARY_OTHER_KEYWORDS.includes(lowerPropName)) {
|
|
560
|
+
updateCandidate(propName, 3);
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
if (candidateRank > 4 && SECONDARY_KEYWORDS.includes(lowerPropName)) {
|
|
564
|
+
updateCandidate(propName, 4);
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
if (candidateRank > 5 && import_pluralize.default.isPlural(propName) && !PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
|
|
568
|
+
updateCandidate(propName, 5);
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
if (candidateRank > 6 && import_pluralize.default.isPlural(propName) && PLURAL_DEPRIORITIZE_LIST.includes(lowerPropName)) {
|
|
572
|
+
updateCandidate(propName, 6);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (bestCandidate) {
|
|
577
|
+
return bestCandidate;
|
|
578
|
+
}
|
|
579
|
+
return arrayPropertyNames[0];
|
|
580
|
+
}
|
|
581
|
+
function guess(properties) {
|
|
582
|
+
const booleanPropertyNames = [];
|
|
583
|
+
for (const propName in properties) {
|
|
584
|
+
if (Object.prototype.hasOwnProperty.call(properties, propName)) {
|
|
585
|
+
const propSchema = properties[propName];
|
|
586
|
+
if (propSchema && propSchema.type === "boolean" || propSchema.type === "integer") {
|
|
587
|
+
booleanPropertyNames.push(propName);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (booleanPropertyNames.length === 0) {
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
594
|
+
if (booleanPropertyNames.length === 1) {
|
|
595
|
+
return booleanPropertyNames[0];
|
|
596
|
+
}
|
|
597
|
+
let bestCandidate = null;
|
|
598
|
+
let candidateRank = Infinity;
|
|
599
|
+
const updateCandidate = (propName, rank) => {
|
|
600
|
+
if (rank < candidateRank) {
|
|
601
|
+
bestCandidate = propName;
|
|
602
|
+
candidateRank = rank;
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
for (const propName of booleanPropertyNames) {
|
|
606
|
+
const normalizedForExactMatch = propName.toLowerCase().replace(/[-_]/g, "");
|
|
607
|
+
let currentPropRank = Infinity;
|
|
608
|
+
if (HAS_MORE_PRIMARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {
|
|
609
|
+
currentPropRank = 1;
|
|
610
|
+
} else if (HAS_MORE_SECONDARY_POSITIVE_EXACT.includes(normalizedForExactMatch)) {
|
|
611
|
+
currentPropRank = 2;
|
|
612
|
+
} else {
|
|
613
|
+
let foundPositiveRegex = false;
|
|
614
|
+
for (const regex of COMPILED_HAS_MORE_POSITIVE_REGEXES) {
|
|
615
|
+
if (regex.test(propName)) {
|
|
616
|
+
currentPropRank = 3;
|
|
617
|
+
foundPositiveRegex = true;
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (!foundPositiveRegex) {
|
|
622
|
+
if (HAS_MORE_PRIMARY_INVERTED_EXACT.includes(normalizedForExactMatch)) {
|
|
623
|
+
currentPropRank = 4;
|
|
624
|
+
} else {
|
|
625
|
+
for (const regex of COMPILED_HAS_MORE_INVERTED_REGEXES) {
|
|
626
|
+
if (regex.test(propName)) {
|
|
627
|
+
currentPropRank = 5;
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
updateCandidate(propName, currentPropRank);
|
|
635
|
+
}
|
|
636
|
+
return bestCandidate;
|
|
637
|
+
}
|
|
638
|
+
function getHasMoreName(properties) {
|
|
639
|
+
const rootGuess = guess(properties);
|
|
640
|
+
if (rootGuess) {
|
|
641
|
+
return rootGuess;
|
|
642
|
+
}
|
|
643
|
+
for (const propName in properties) {
|
|
644
|
+
const propSchema = properties[propName];
|
|
645
|
+
if (propSchema.type === "object" && propSchema.properties) {
|
|
646
|
+
const nested = getHasMoreName(propSchema.properties);
|
|
647
|
+
if (nested) {
|
|
648
|
+
return propName + "." + nested;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return null;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// packages/spec/dist/lib/pagination/pagination.js
|
|
656
|
+
var OFFSET_PARAM_REGEXES = [
|
|
657
|
+
/\boffset\b/i,
|
|
658
|
+
/\bskip\b/i,
|
|
659
|
+
/\bstart(?:ing_at|_index)?\b/i,
|
|
660
|
+
// e.g., start, starting_at, start_index
|
|
661
|
+
/\bfrom\b/i
|
|
662
|
+
];
|
|
663
|
+
var GENERIC_LIMIT_PARAM_REGEXES = [
|
|
664
|
+
/\blimit\b/i,
|
|
665
|
+
/\bcount\b/i,
|
|
666
|
+
/\b(?:page_?)?size\b/i,
|
|
667
|
+
// e.g., size, page_size, pagesize
|
|
668
|
+
/\bmax_results\b/i,
|
|
669
|
+
/\bnum_results\b/i,
|
|
670
|
+
/\bshow\b/i,
|
|
671
|
+
// Can sometimes mean limit
|
|
672
|
+
/\bper_?page\b/i,
|
|
673
|
+
// e.g., per_page, perpage
|
|
674
|
+
/\bper-page\b/i,
|
|
675
|
+
/\btake\b/i
|
|
676
|
+
];
|
|
677
|
+
var PAGE_NUMBER_REGEXES = [
|
|
678
|
+
/^page$/i,
|
|
679
|
+
// Exact match for "page"
|
|
680
|
+
/^p$/i,
|
|
681
|
+
// Exact match for "p" (common shorthand)
|
|
682
|
+
/\bpage_?(?:number|num|idx|index)\b/i
|
|
683
|
+
// e.g., page_number, pageNumber, page_num, page_idx
|
|
684
|
+
];
|
|
685
|
+
var PAGE_SIZE_REGEXES = [
|
|
686
|
+
/\bpage_?size\b/i,
|
|
687
|
+
// e.g., page_size, pagesize
|
|
688
|
+
/^size$/i,
|
|
689
|
+
// Exact "size"
|
|
690
|
+
// /\bsize\b/i, // Broader "size" - can be ambiguous, prefer more specific ones first
|
|
691
|
+
/\blimit\b/i,
|
|
692
|
+
// Limit is often used for page size
|
|
693
|
+
/\bcount\b/i,
|
|
694
|
+
// Count can also be used for page size
|
|
695
|
+
/\bper_?page\b/i,
|
|
696
|
+
// e.g., per_page, perpage
|
|
697
|
+
/\bper-page\b/i,
|
|
698
|
+
/\bnum_?(?:items|records|results)\b/i,
|
|
699
|
+
// e.g., num_items, numitems
|
|
700
|
+
/\bresults_?per_?page\b/i
|
|
701
|
+
];
|
|
702
|
+
var CURSOR_REGEXES = [
|
|
703
|
+
/\bcursor\b/i,
|
|
704
|
+
/\bafter(?:_?cursor)?\b/i,
|
|
705
|
+
// e.g., after, after_cursor
|
|
706
|
+
/\bbefore(?:_?cursor)?\b/i,
|
|
707
|
+
// e.g., before, before_cursor
|
|
708
|
+
/\b(next|prev|previous)_?(?:page_?)?token\b/i,
|
|
709
|
+
// e.g., next_page_token, nextPageToken, prev_token
|
|
710
|
+
/\b(next|prev|previous)_?cursor\b/i,
|
|
711
|
+
// e.g., next_cursor, previousCursor
|
|
712
|
+
/\bcontinuation(?:_?token)?\b/i,
|
|
713
|
+
// e.g., continuation, continuation_token
|
|
714
|
+
/\bpage(?:_?(token|id))?\b/i,
|
|
715
|
+
// e.g., after, after_cursor
|
|
716
|
+
/\bstart_?(?:key|cursor|token|after)\b/i
|
|
717
|
+
// e.g., start_key, startCursor, startToken, startAfter
|
|
718
|
+
];
|
|
719
|
+
var CURSOR_LIMIT_REGEXES = [
|
|
720
|
+
/\blimit\b/i,
|
|
721
|
+
/\bcount\b/i,
|
|
722
|
+
/\bsize\b/i,
|
|
723
|
+
// General size
|
|
724
|
+
/\bfirst\b/i,
|
|
725
|
+
// Common in Relay-style cursor pagination (forward pagination)
|
|
726
|
+
/\blast\b/i,
|
|
727
|
+
// Common in Relay-style cursor pagination (backward pagination)
|
|
728
|
+
/\bpage_?size\b/i,
|
|
729
|
+
// Sometimes page_size is used with cursors
|
|
730
|
+
/\bnum_?(?:items|records|results)\b/i,
|
|
731
|
+
// e.g., num_items
|
|
732
|
+
/\bmax_?items\b/i,
|
|
733
|
+
/\btake\b/i
|
|
734
|
+
];
|
|
735
|
+
function findParamAndKeyword(queryParams, regexes, excludeParamName) {
|
|
736
|
+
for (const param of queryParams) {
|
|
737
|
+
if (param.name === excludeParamName) {
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
for (const regex of regexes) {
|
|
741
|
+
const match = param.name.match(regex);
|
|
742
|
+
if (match) {
|
|
743
|
+
return { param, keyword: match[0] };
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return null;
|
|
748
|
+
}
|
|
749
|
+
function isOffsetPagination(operation, parameters) {
|
|
750
|
+
const offsetMatch = findParamAndKeyword(parameters, OFFSET_PARAM_REGEXES);
|
|
751
|
+
if (!offsetMatch)
|
|
752
|
+
return null;
|
|
753
|
+
const limitMatch = findParamAndKeyword(
|
|
754
|
+
parameters,
|
|
755
|
+
GENERIC_LIMIT_PARAM_REGEXES,
|
|
756
|
+
offsetMatch.param.name
|
|
757
|
+
);
|
|
758
|
+
if (!limitMatch)
|
|
759
|
+
return null;
|
|
760
|
+
return {
|
|
761
|
+
type: "offset",
|
|
762
|
+
offsetParamName: offsetMatch.param.name,
|
|
763
|
+
offsetKeyword: offsetMatch.keyword,
|
|
764
|
+
limitParamName: limitMatch.param.name,
|
|
765
|
+
limitKeyword: limitMatch.keyword
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
function isPagePagination(operation) {
|
|
769
|
+
const queryParams = operation.parameters.filter((p) => p.in === "query").filter(
|
|
770
|
+
(it) => it.schema && !isRef(it.schema) && it.schema.type === "integer"
|
|
771
|
+
);
|
|
772
|
+
if (queryParams.length < 2)
|
|
773
|
+
return null;
|
|
774
|
+
const pageNoMatch = findParamAndKeyword(queryParams, PAGE_NUMBER_REGEXES);
|
|
775
|
+
if (!pageNoMatch)
|
|
776
|
+
return null;
|
|
777
|
+
const pageSizeMatch = findParamAndKeyword(
|
|
778
|
+
queryParams,
|
|
779
|
+
PAGE_SIZE_REGEXES,
|
|
780
|
+
pageNoMatch.param.name
|
|
781
|
+
);
|
|
782
|
+
if (!pageSizeMatch)
|
|
783
|
+
return null;
|
|
784
|
+
return {
|
|
785
|
+
type: "page",
|
|
786
|
+
pageNumberParamName: pageNoMatch.param.name,
|
|
787
|
+
pageNumberKeyword: pageNoMatch.keyword,
|
|
788
|
+
pageSizeParamName: pageSizeMatch.param.name,
|
|
789
|
+
pageSizeKeyword: pageSizeMatch.keyword
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function isCursorPagination(operation) {
|
|
793
|
+
const queryParams = operation.parameters.filter((p) => p.in === "query");
|
|
794
|
+
if (queryParams.length < 2)
|
|
795
|
+
return null;
|
|
796
|
+
const cursorMatch = findParamAndKeyword(queryParams, CURSOR_REGEXES);
|
|
797
|
+
if (!cursorMatch)
|
|
798
|
+
return null;
|
|
799
|
+
const limitMatch = findParamAndKeyword(
|
|
800
|
+
queryParams,
|
|
801
|
+
CURSOR_LIMIT_REGEXES,
|
|
802
|
+
cursorMatch.param.name
|
|
803
|
+
);
|
|
804
|
+
if (!limitMatch)
|
|
805
|
+
return null;
|
|
806
|
+
return {
|
|
807
|
+
type: "cursor",
|
|
808
|
+
cursorParamName: cursorMatch.param.name,
|
|
809
|
+
cursorKeyword: cursorMatch.keyword,
|
|
810
|
+
limitParamName: limitMatch.param.name,
|
|
811
|
+
limitKeyword: limitMatch.keyword
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
function guessPagination(operation, body, response) {
|
|
815
|
+
const bodyParameters = body && body.properties ? Object.keys(body.properties).map((it) => ({ name: it })) : [];
|
|
816
|
+
const parameters = operation.parameters;
|
|
817
|
+
if (isEmpty(operation.parameters) && isEmpty(bodyParameters)) {
|
|
818
|
+
return { type: "none", reason: "no parameters" };
|
|
819
|
+
}
|
|
820
|
+
if (!response) {
|
|
821
|
+
return { type: "none", reason: "no response" };
|
|
822
|
+
}
|
|
823
|
+
if (!response.properties) {
|
|
824
|
+
return { type: "none", reason: "empty response" };
|
|
825
|
+
}
|
|
826
|
+
const properties = response.properties;
|
|
827
|
+
const itemsKey = getItemsName(properties);
|
|
828
|
+
if (!itemsKey) {
|
|
829
|
+
return { type: "none", reason: "no items key" };
|
|
830
|
+
}
|
|
831
|
+
const hasMoreKey = getHasMoreName(excludeKey(properties, itemsKey));
|
|
832
|
+
if (!hasMoreKey) {
|
|
833
|
+
return { type: "none", reason: "no hasMore key" };
|
|
834
|
+
}
|
|
835
|
+
const pagination = isOffsetPagination(operation, [...parameters, ...bodyParameters]) || isPagePagination(operation) || isCursorPagination(operation);
|
|
836
|
+
return pagination ? { ...pagination, items: itemsKey, hasMore: hasMoreKey } : { type: "none", reason: "no pagination" };
|
|
837
|
+
}
|
|
838
|
+
function excludeKey(obj, key) {
|
|
839
|
+
const { [key]: _, ...rest } = obj;
|
|
840
|
+
return rest;
|
|
841
|
+
}
|
|
25
842
|
|
|
26
843
|
// packages/spec/dist/lib/operation.js
|
|
27
|
-
|
|
844
|
+
function augmentSpec(config) {
|
|
845
|
+
config.spec.paths ??= {};
|
|
846
|
+
const paths = {};
|
|
847
|
+
for (const [path, pathItem] of Object.entries(config.spec.paths)) {
|
|
848
|
+
const { parameters = [], ...methods } = pathItem;
|
|
849
|
+
const fixedPath = path.replace(/:([^/]+)/g, "{$1}");
|
|
850
|
+
for (const [method, operation] of Object.entries(methods)) {
|
|
851
|
+
const formatOperationId = config.operationId ?? defaults.operationId;
|
|
852
|
+
const formatTag = config.tag ?? defaults.tag;
|
|
853
|
+
const operationId = formatOperationId(operation, fixedPath, method);
|
|
854
|
+
const operationTag = formatTag(operation, fixedPath);
|
|
855
|
+
const requestBody = isRef2(operation.requestBody) ? followRef(config.spec, operation.requestBody.$ref) : operation.requestBody;
|
|
856
|
+
const tunedOperation = {
|
|
857
|
+
...operation,
|
|
858
|
+
parameters: [...parameters, ...operation.parameters ?? []].map(
|
|
859
|
+
(it) => isRef2(it) ? followRef(config.spec, it.$ref) : it
|
|
860
|
+
),
|
|
861
|
+
tags: [operationTag],
|
|
862
|
+
operationId,
|
|
863
|
+
responses: resolveResponses(config.spec, operation),
|
|
864
|
+
requestBody
|
|
865
|
+
};
|
|
866
|
+
tunedOperation["x-pagination"] = toPagination(
|
|
867
|
+
config.spec,
|
|
868
|
+
tunedOperation
|
|
869
|
+
);
|
|
870
|
+
Object.assign(paths, {
|
|
871
|
+
[fixedPath]: {
|
|
872
|
+
...paths[fixedPath],
|
|
873
|
+
[method]: tunedOperation
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
return { ...config.spec, paths };
|
|
879
|
+
}
|
|
880
|
+
function toPagination(spec, tunedOperation) {
|
|
881
|
+
if (tunedOperation["x-pagination"]) {
|
|
882
|
+
return tunedOperation["x-pagination"];
|
|
883
|
+
}
|
|
884
|
+
const schema = getResponseContentSchema(
|
|
885
|
+
spec,
|
|
886
|
+
tunedOperation.responses["200"],
|
|
887
|
+
"application/json"
|
|
888
|
+
);
|
|
889
|
+
const pagination = guessPagination(
|
|
890
|
+
tunedOperation,
|
|
891
|
+
tunedOperation.requestBody ? getRequestContentSchema(
|
|
892
|
+
spec,
|
|
893
|
+
tunedOperation.requestBody,
|
|
894
|
+
"application/json"
|
|
895
|
+
) : void 0,
|
|
896
|
+
schema
|
|
897
|
+
);
|
|
898
|
+
if (pagination && pagination.type !== "none" && schema) {
|
|
899
|
+
return pagination;
|
|
900
|
+
}
|
|
901
|
+
return void 0;
|
|
902
|
+
}
|
|
903
|
+
function getResponseContentSchema(spec, response, type) {
|
|
904
|
+
if (!response) {
|
|
905
|
+
return void 0;
|
|
906
|
+
}
|
|
907
|
+
const content = response.content;
|
|
908
|
+
if (!content) {
|
|
909
|
+
return void 0;
|
|
910
|
+
}
|
|
911
|
+
for (const contentType in content) {
|
|
912
|
+
if (contentType.toLowerCase() === type.toLowerCase()) {
|
|
913
|
+
return isRef2(content[contentType].schema) ? followRef(spec, content[contentType].schema.$ref) : content[contentType].schema;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return void 0;
|
|
917
|
+
}
|
|
918
|
+
function getRequestContentSchema(spec, requestBody, type) {
|
|
919
|
+
const content = requestBody.content;
|
|
920
|
+
if (!content) {
|
|
921
|
+
return void 0;
|
|
922
|
+
}
|
|
923
|
+
for (const contentType in content) {
|
|
924
|
+
if (contentType.toLowerCase() === type.toLowerCase()) {
|
|
925
|
+
return isRef2(content[contentType].schema) ? followRef(spec, content[contentType].schema.$ref) : content[contentType].schema;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return void 0;
|
|
929
|
+
}
|
|
28
930
|
var defaults = {
|
|
29
931
|
operationId: (operation, path, method) => {
|
|
30
932
|
if (operation.operationId) {
|
|
@@ -39,34 +941,35 @@ var defaults = {
|
|
|
39
941
|
);
|
|
40
942
|
},
|
|
41
943
|
tag: (operation, path) => {
|
|
42
|
-
return operation.tags?.[0]
|
|
944
|
+
return operation.tags?.[0] ? sanitizeTag(operation.tags?.[0]) : determineGenericTag(path, operation);
|
|
43
945
|
}
|
|
44
946
|
};
|
|
947
|
+
function resolveResponses(spec, operation) {
|
|
948
|
+
const responses = operation.responses ?? {};
|
|
949
|
+
const resolved = {};
|
|
950
|
+
for (const status in responses) {
|
|
951
|
+
const response = isRef2(responses[status]) ? followRef(spec, responses[status].$ref) : responses[status];
|
|
952
|
+
resolved[status] = response;
|
|
953
|
+
}
|
|
954
|
+
return resolved;
|
|
955
|
+
}
|
|
45
956
|
function forEachOperation(config, callback) {
|
|
46
957
|
const result = [];
|
|
47
958
|
for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {
|
|
48
959
|
const { parameters = [], ...methods } = pathItem;
|
|
49
|
-
const fixedPath = path.replace(/:([^/]+)/g, "{$1}");
|
|
50
960
|
for (const [method, operation] of Object.entries(methods)) {
|
|
51
|
-
const formatOperationId = config.operationId ?? defaults.operationId;
|
|
52
|
-
const formatTag = config.tag ?? defaults.tag;
|
|
53
|
-
const operationName = formatOperationId(operation, fixedPath, method);
|
|
54
|
-
const operationTag = formatTag(operation, fixedPath);
|
|
55
961
|
const metadata = operation["x-oaiMeta"] ?? {};
|
|
962
|
+
const operationTag = operation.tags?.[0];
|
|
56
963
|
result.push(
|
|
57
964
|
callback(
|
|
58
965
|
{
|
|
59
966
|
name: metadata.name,
|
|
60
967
|
method,
|
|
61
|
-
path
|
|
968
|
+
path,
|
|
62
969
|
groupName: operationTag,
|
|
63
970
|
tag: operationTag
|
|
64
971
|
},
|
|
65
|
-
|
|
66
|
-
...operation,
|
|
67
|
-
parameters: [...parameters, ...operation.parameters ?? []],
|
|
68
|
-
operationId: operationName
|
|
69
|
-
}
|
|
972
|
+
operation
|
|
70
973
|
)
|
|
71
974
|
);
|
|
72
975
|
}
|
|
@@ -74,15 +977,11 @@ function forEachOperation(config, callback) {
|
|
|
74
977
|
return result;
|
|
75
978
|
}
|
|
76
979
|
var reservedKeywords = /* @__PURE__ */ new Set([
|
|
77
|
-
"abstract",
|
|
78
|
-
"arguments",
|
|
79
980
|
"await",
|
|
80
|
-
|
|
981
|
+
// Reserved in async functions
|
|
81
982
|
"break",
|
|
82
|
-
"byte",
|
|
83
983
|
"case",
|
|
84
984
|
"catch",
|
|
85
|
-
"char",
|
|
86
985
|
"class",
|
|
87
986
|
"const",
|
|
88
987
|
"continue",
|
|
@@ -90,85 +989,59 @@ var reservedKeywords = /* @__PURE__ */ new Set([
|
|
|
90
989
|
"default",
|
|
91
990
|
"delete",
|
|
92
991
|
"do",
|
|
93
|
-
"double",
|
|
94
992
|
"else",
|
|
95
993
|
"enum",
|
|
96
|
-
"eval",
|
|
97
994
|
"export",
|
|
98
995
|
"extends",
|
|
99
996
|
"false",
|
|
100
|
-
"final",
|
|
101
997
|
"finally",
|
|
102
|
-
"float",
|
|
103
998
|
"for",
|
|
104
999
|
"function",
|
|
105
|
-
"goto",
|
|
106
1000
|
"if",
|
|
107
1001
|
"implements",
|
|
1002
|
+
// Strict mode
|
|
108
1003
|
"import",
|
|
109
1004
|
"in",
|
|
110
1005
|
"instanceof",
|
|
111
|
-
"int",
|
|
112
1006
|
"interface",
|
|
1007
|
+
// Strict mode
|
|
113
1008
|
"let",
|
|
114
|
-
|
|
115
|
-
"native",
|
|
1009
|
+
// Strict mode
|
|
116
1010
|
"new",
|
|
117
1011
|
"null",
|
|
118
1012
|
"package",
|
|
1013
|
+
// Strict mode
|
|
119
1014
|
"private",
|
|
1015
|
+
// Strict mode
|
|
120
1016
|
"protected",
|
|
1017
|
+
// Strict mode
|
|
121
1018
|
"public",
|
|
1019
|
+
// Strict mode
|
|
122
1020
|
"return",
|
|
123
|
-
"short",
|
|
124
1021
|
"static",
|
|
1022
|
+
// Strict mode
|
|
125
1023
|
"super",
|
|
126
1024
|
"switch",
|
|
127
|
-
"synchronized",
|
|
128
1025
|
"this",
|
|
129
1026
|
"throw",
|
|
130
|
-
"throws",
|
|
131
|
-
"transient",
|
|
132
1027
|
"true",
|
|
133
1028
|
"try",
|
|
134
1029
|
"typeof",
|
|
135
1030
|
"var",
|
|
136
1031
|
"void",
|
|
137
|
-
"volatile",
|
|
138
1032
|
"while",
|
|
139
1033
|
"with",
|
|
140
1034
|
"yield",
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
"
|
|
145
|
-
"any",
|
|
146
|
-
"unknown",
|
|
147
|
-
"never",
|
|
148
|
-
"get",
|
|
149
|
-
"list",
|
|
150
|
-
"create",
|
|
151
|
-
"update",
|
|
152
|
-
"delete",
|
|
153
|
-
"post",
|
|
154
|
-
"put",
|
|
155
|
-
"patch",
|
|
156
|
-
"do",
|
|
157
|
-
"send",
|
|
158
|
-
"add",
|
|
159
|
-
"remove",
|
|
160
|
-
"set",
|
|
161
|
-
"find",
|
|
162
|
-
"search",
|
|
163
|
-
"check",
|
|
164
|
-
"make"
|
|
165
|
-
// Added make, check
|
|
1035
|
+
// Strict mode / Generator functions
|
|
1036
|
+
// 'arguments' is not technically a reserved word, but it's a special identifier within functions
|
|
1037
|
+
// and assigning to it or declaring it can cause issues or unexpected behavior.
|
|
1038
|
+
"arguments"
|
|
166
1039
|
]);
|
|
167
1040
|
function sanitizeTag(camelCasedTag) {
|
|
168
1041
|
if (/^\d/.test(camelCasedTag)) {
|
|
169
1042
|
return `_${camelCasedTag}`;
|
|
170
1043
|
}
|
|
171
|
-
return reservedKeywords.has(camelCasedTag) ? `${camelCasedTag}_` : camelCasedTag;
|
|
1044
|
+
return reservedKeywords.has(camelcase(camelCasedTag)) ? `${camelCasedTag}_` : camelCasedTag;
|
|
172
1045
|
}
|
|
173
1046
|
function determineGenericTag(pathString, operation) {
|
|
174
1047
|
const operationId = operation.operationId || "";
|
|
@@ -192,7 +1065,6 @@ function determineGenericTag(pathString, operation) {
|
|
|
192
1065
|
"search",
|
|
193
1066
|
"check",
|
|
194
1067
|
"make"
|
|
195
|
-
// Added make
|
|
196
1068
|
]);
|
|
197
1069
|
const segments = pathString.split("/").filter(Boolean);
|
|
198
1070
|
const potentialCandidates = segments.filter(
|
|
@@ -308,6 +1180,68 @@ function isSuccessStatusCode(statusCode) {
|
|
|
308
1180
|
statusCode = Number(statusCode);
|
|
309
1181
|
return statusCode >= 200 && statusCode < 300;
|
|
310
1182
|
}
|
|
1183
|
+
function patchParameters(spec, objectSchema, operation) {
|
|
1184
|
+
const securitySchemes = spec.components?.securitySchemes ?? {};
|
|
1185
|
+
const securityOptions = securityToOptions(
|
|
1186
|
+
spec,
|
|
1187
|
+
operation.security ?? [],
|
|
1188
|
+
securitySchemes
|
|
1189
|
+
);
|
|
1190
|
+
objectSchema.properties ??= {};
|
|
1191
|
+
objectSchema.required ??= [];
|
|
1192
|
+
for (const param of operation.parameters) {
|
|
1193
|
+
if (param.required) {
|
|
1194
|
+
objectSchema.required.push(param.name);
|
|
1195
|
+
}
|
|
1196
|
+
objectSchema.properties[param.name] = isRef2(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" };
|
|
1197
|
+
}
|
|
1198
|
+
for (const param of securityOptions) {
|
|
1199
|
+
objectSchema.required = (objectSchema.required ?? []).filter(
|
|
1200
|
+
(name) => name !== param.name
|
|
1201
|
+
);
|
|
1202
|
+
objectSchema.properties[param.name] = isRef2(param.schema) ? followRef(spec, param.schema.$ref) : param.schema ?? { type: "string" };
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
function securityToOptions(spec, security, securitySchemes, staticIn) {
|
|
1206
|
+
securitySchemes ??= {};
|
|
1207
|
+
const parameters = [];
|
|
1208
|
+
for (const it of security) {
|
|
1209
|
+
const [name] = Object.keys(it);
|
|
1210
|
+
if (!name) {
|
|
1211
|
+
continue;
|
|
1212
|
+
}
|
|
1213
|
+
const schema = isRef2(securitySchemes[name]) ? followRef(spec, securitySchemes[name].$ref) : securitySchemes[name];
|
|
1214
|
+
if (schema.type === "http") {
|
|
1215
|
+
parameters.push({
|
|
1216
|
+
in: staticIn ?? "header",
|
|
1217
|
+
name: "authorization",
|
|
1218
|
+
schema: { type: "string" }
|
|
1219
|
+
});
|
|
1220
|
+
continue;
|
|
1221
|
+
}
|
|
1222
|
+
if (schema.type === "apiKey") {
|
|
1223
|
+
if (!schema.in) {
|
|
1224
|
+
throw new Error(`apiKey security schema must have an "in" field`);
|
|
1225
|
+
}
|
|
1226
|
+
if (!schema.name) {
|
|
1227
|
+
throw new Error(`apiKey security schema must have a "name" field`);
|
|
1228
|
+
}
|
|
1229
|
+
parameters.push({
|
|
1230
|
+
in: staticIn ?? schema.in,
|
|
1231
|
+
name: schema.name,
|
|
1232
|
+
schema: { type: "string" }
|
|
1233
|
+
});
|
|
1234
|
+
continue;
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
return parameters;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// packages/spec/dist/lib/loaders/local-loader.js
|
|
1241
|
+
import { parse } from "yaml";
|
|
1242
|
+
|
|
1243
|
+
// packages/spec/dist/lib/loaders/remote-loader.js
|
|
1244
|
+
import { parse as parse2 } from "yaml";
|
|
311
1245
|
|
|
312
1246
|
// packages/dart/src/lib/dart-emitter.ts
|
|
313
1247
|
import { merge } from "lodash-es";
|
|
@@ -315,9 +1249,9 @@ import assert from "node:assert";
|
|
|
315
1249
|
import { camelcase as camelcase2, snakecase } from "stringcase";
|
|
316
1250
|
import {
|
|
317
1251
|
cleanRef,
|
|
318
|
-
followRef,
|
|
319
|
-
isEmpty,
|
|
320
|
-
isRef,
|
|
1252
|
+
followRef as followRef2,
|
|
1253
|
+
isEmpty as isEmpty2,
|
|
1254
|
+
isRef as isRef3,
|
|
321
1255
|
notRef,
|
|
322
1256
|
parseRef,
|
|
323
1257
|
pascalcase
|
|
@@ -365,7 +1299,7 @@ var DartSerializer = class {
|
|
|
365
1299
|
this.#spec.components.schemas ??= {};
|
|
366
1300
|
this.#spec.components.responses ??= {};
|
|
367
1301
|
const checkSchema = (schema) => {
|
|
368
|
-
if (
|
|
1302
|
+
if (isRef3(schema)) {
|
|
369
1303
|
const { model } = parseRef(schema.$ref);
|
|
370
1304
|
return model === schemaName;
|
|
371
1305
|
}
|
|
@@ -398,7 +1332,7 @@ var DartSerializer = class {
|
|
|
398
1332
|
matches: `json['${camelcase2(context.name)}'] is Map<String, dynamic>`
|
|
399
1333
|
};
|
|
400
1334
|
}
|
|
401
|
-
if (
|
|
1335
|
+
if (isEmpty2(schema.properties)) {
|
|
402
1336
|
if (context.noEmit !== true) {
|
|
403
1337
|
this.#emit(
|
|
404
1338
|
className,
|
|
@@ -571,7 +1505,7 @@ return ${matches.join(" && ")};
|
|
|
571
1505
|
const schemaName = cleanRef($ref).split("/").pop();
|
|
572
1506
|
const serialized = this.handle(
|
|
573
1507
|
schemaName,
|
|
574
|
-
|
|
1508
|
+
followRef2(this.#spec, $ref),
|
|
575
1509
|
required,
|
|
576
1510
|
{
|
|
577
1511
|
...context,
|
|
@@ -584,7 +1518,7 @@ return ${matches.join(" && ")};
|
|
|
584
1518
|
// fixme: this method should no longer be needed because the logic in it is being preprocessed before emitting begins
|
|
585
1519
|
#allOf(className, schemas, context) {
|
|
586
1520
|
const name = pascalcase(context.propName || className);
|
|
587
|
-
const refs = schemas.filter(
|
|
1521
|
+
const refs = schemas.filter(isRef3);
|
|
588
1522
|
const nonRefs = schemas.filter(notRef);
|
|
589
1523
|
if (nonRefs.some((it) => it.type && it.type !== "object")) {
|
|
590
1524
|
assert(false, `allOf ${name} must be an object`);
|
|
@@ -592,7 +1526,7 @@ return ${matches.join(" && ")};
|
|
|
592
1526
|
const objectSchema = merge(
|
|
593
1527
|
{},
|
|
594
1528
|
...nonRefs,
|
|
595
|
-
...refs.map((ref) =>
|
|
1529
|
+
...refs.map((ref) => followRef2(this.#spec, ref.$ref))
|
|
596
1530
|
);
|
|
597
1531
|
delete objectSchema.allOf;
|
|
598
1532
|
return this.handle(name, objectSchema, true, context);
|
|
@@ -608,8 +1542,8 @@ return ${matches.join(" && ")};
|
|
|
608
1542
|
};
|
|
609
1543
|
}
|
|
610
1544
|
const nullSchemaIndex = schemas.findIndex((schema) => {
|
|
611
|
-
if (
|
|
612
|
-
const refSchema =
|
|
1545
|
+
if (isRef3(schema)) {
|
|
1546
|
+
const refSchema = followRef2(this.#spec, schema.$ref);
|
|
613
1547
|
return refSchema.type === "null";
|
|
614
1548
|
}
|
|
615
1549
|
return schema.type === "null";
|
|
@@ -649,7 +1583,7 @@ return ${matches.join(" && ")};
|
|
|
649
1583
|
const patterns = [];
|
|
650
1584
|
const objects = schemas.filter(notRef).filter((it) => it.type === "object");
|
|
651
1585
|
for (const schema of schemas) {
|
|
652
|
-
if (
|
|
1586
|
+
if (isRef3(schema)) {
|
|
653
1587
|
const refType = this.#ref(className, schema.$ref, true, context);
|
|
654
1588
|
patterns.push({
|
|
655
1589
|
pattern: `case ${refType.type || "Map<String, dynamic>"} map when ${refType.use}.matches(map): return ${refType.use}.fromJson(map);`,
|
|
@@ -900,7 +1834,7 @@ return false;
|
|
|
900
1834
|
};
|
|
901
1835
|
}
|
|
902
1836
|
#serialize(className, schema, required = true, context = {}) {
|
|
903
|
-
if (
|
|
1837
|
+
if (isRef3(schema)) {
|
|
904
1838
|
return this.#ref(className, schema.$ref, required, context);
|
|
905
1839
|
}
|
|
906
1840
|
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
@@ -964,14 +1898,14 @@ return false;
|
|
|
964
1898
|
}
|
|
965
1899
|
};
|
|
966
1900
|
function isObjectSchema(schema) {
|
|
967
|
-
return !
|
|
1901
|
+
return !isRef3(schema) && (schema.type === "object" || !!schema.properties);
|
|
968
1902
|
}
|
|
969
1903
|
|
|
970
1904
|
// packages/dart/src/lib/http/dispatcher.txt
|
|
971
1905
|
var dispatcher_default = "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:http/http.dart' as http;\nimport 'package:http_parser/http_parser.dart';\nimport 'package:mime/mime.dart' as mime;\n\nimport './interceptors.dart';\nimport './responses.dart';\n\nclass Dispatcher {\n final List<Interceptor> interceptors;\n\n Dispatcher(this.interceptors);\n\n Future<http.StreamedResponse> multipart(\n RequestConfig config,\n Map<String, dynamic> body,\n ) async {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.MultipartRequest(\n modifiedConfig.method,\n modifiedConfig.url,\n );\n request.headers.addAll(modifiedConfig.headers);\n for (var entry in body.entries) {\n final key = entry.key;\n final value = entry.value;\n if (value is File) {\n final mimeType = mime.lookupMimeType(value.path);\n request.files.add(\n http.MultipartFile(\n key,\n value.openRead(),\n await value.length(),\n filename: value.uri.pathSegments.last,\n contentType: mimeType != null ? MediaType.parse(mimeType) : null,\n ),\n );\n } else {\n request.fields[key] = value.toString();\n }\n }\n\n return request.send();\n }\n\n Future<http.StreamedResponse> empty(RequestConfig config) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n return request.send();\n }\n\n Future<http.StreamedResponse> json(RequestConfig config, dynamic body) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n\n request.headers['Content-Type'] = 'application/json';\n if ((body is Map || body is List)) {\n request.body = jsonEncode(body);\n } else if (body is String) {\n request.body = body;\n } else {\n throw ArgumentError('Unsupported body type: ${body.runtimeType}');\n }\n\n return request.send();\n }\n}\n\nclass Receiver {\n final List<Interceptor> interceptors;\n Receiver(this.interceptors);\n\n dynamic _parse(http.Response response) {\n final contentTypeHeader = response.headers['content-type'];\n final parsed = parseContentType(contentTypeHeader);\n if (parsed.type == 'application/json') {\n return jsonDecode(response.body);\n } else if (parsed.type == 'text/plain') {\n return response.body;\n } else if (parsed.type == 'application/octet-stream') {\n return response.bodyBytes;\n } else {\n throw UnsupportedError('Unsupported content type: ${parsed.type}');\n }\n }\n\n dynamic json(http.StreamedResponse stream) async {\n if (stream.statusCode >= 200 && stream.statusCode < 300) {\n final response = await http.Response.fromStream(stream);\n return _parse(response);\n }\n switch (stream.statusCode) {\n case 400:\n throw BadRequestError('');\n case 401:\n throw UnauthorizedError('');\n case 403:\n throw ForbiddenError('');\n case 404:\n throw NotFoundError('');\n case 500:\n throw InternalServerError('');\n case 402:\n throw PaymentRequiredError('');\n case 405:\n throw MethodNotAllowedError('');\n case 406:\n throw NotAcceptableError('');\n case 409:\n throw ConflictError('');\n case 410:\n throw GoneError('');\n case 422:\n throw UnprocessableEntityError('');\n case 429:\n throw TooManyRequestsError('');\n case 413:\n throw PayloadTooLargeError('');\n case 415:\n throw UnsupportedMediaTypeError('');\n case 501:\n throw NotImplementedError('');\n case 502:\n throw BadGatewayError('');\n case 503:\n throw ServiceUnavailableError('');\n case 504:\n throw GatewayTimeoutError('');\n default:\n throw UnknownApiError('', stream.statusCode);\n }\n }\n}\n\n({String type, Map<String, String> parameters}) parseContentType(\n String? contentTypeHeader,\n) {\n if (contentTypeHeader == null || contentTypeHeader.isEmpty) {\n return (type: '', parameters: {});\n }\n final parts = contentTypeHeader.split(';');\n final type = parts[0].trim();\n final parameters = <String, String>{};\n for (var i = 1; i < parts.length; i++) {\n final param = parts[i].split('=');\n if (param.length == 2) {\n parameters[param[0].trim()] = param[1].trim();\n }\n }\n\n return (type: type, parameters: parameters);\n}\n";
|
|
972
1906
|
|
|
973
1907
|
// packages/dart/src/lib/http/interceptors.txt
|
|
974
|
-
var interceptors_default = "abstract class Interceptor {\n RequestConfig before(RequestConfig config);\n void after();\n}\n\nclass BaseUrlInterceptor extends Interceptor {\n final String Function() getBaseUrl;\n BaseUrlInterceptor(this.getBaseUrl);\n\n @override\n RequestConfig before(RequestConfig config) {\n final baseUrl = getBaseUrl();\n if (config.url.scheme.isEmpty) {\n config.url = Uri.parse(baseUrl + config.url.toString());\n }\n return config;\n }\n\n @override\n void after() {\n //\n }\n}\n\nclass RequestConfig {\n final String method;\n Uri url;\n final Map<String, String> headers;\n RequestConfig({required this.method, required this.url, required this.headers});\n}\n";
|
|
1908
|
+
var interceptors_default = "abstract class Interceptor {\n RequestConfig before(RequestConfig config);\n void after();\n}\n\nclass BaseUrlInterceptor extends Interceptor {\n final String Function() getBaseUrl;\n BaseUrlInterceptor(this.getBaseUrl);\n\n @override\n RequestConfig before(RequestConfig config) {\n final baseUrl = getBaseUrl();\n if (config.url.scheme.isEmpty) {\n config.url = Uri.parse(baseUrl + config.url.toString());\n }\n return config;\n }\n\n @override\n void after() {\n //\n }\n}\n\n\nclass LoggingInterceptor extends Interceptor {\n // ANSI color codes\n static const String _reset = '\\x1B[0m';\n static const String _green = '\\x1B[32m';\n static const String _yellow = '\\x1B[33m';\n static const String _blue = '\\x1B[34m';\n static const String _magenta = '\\x1B[35m';\n static const String _cyan = '\\x1B[36m';\n\n @override\n RequestConfig before(RequestConfig config) {\n print('${_cyan}[LOG] --- HTTP REQUEST ---$_reset');\n print('${_yellow}[LOG] Method: ${config.method.toUpperCase()}$_reset');\n print('${_green}[LOG] URL: ${config.url}$_reset');\n print('${_magenta}[ContentType] ${config.headers['content-type']}$_reset');\n if (config.headers.isNotEmpty) {\n print('${_blue}[LOG] Headers: ${config.headers}$_reset');\n } else {\n print('${_blue}[LOG] Headers: <none>$_reset');\n }\n print('${_cyan}[LOG] --------------$_reset');\n return config;\n }\n\n @override\n void after() {\n // Optionally log after the request\n }\n}\n\nclass RequestConfig {\n final String method;\n Uri url;\n final Map<String, String> headers;\n RequestConfig({required this.method, required this.url, required this.headers});\n}\n";
|
|
975
1909
|
|
|
976
1910
|
// packages/dart/src/lib/http/responses.txt
|
|
977
1911
|
var responses_default = "sealed class ApiError {\n final String message;\n final int? statusCode;\n final String status;\n const ApiError(this.message, {this.statusCode, this.status = ''});\n\n @override\n String toString() =>\n 'ApiError(status: $status, statusCode: $statusCode, message: $message)';\n}\n\nbase class BadRequestError extends ApiError {\n const BadRequestError(String message)\n : super(message, statusCode: 400, status: 'BadRequest');\n}\n\nbase class UnauthorizedError extends ApiError {\n const UnauthorizedError(String message)\n : super(message, statusCode: 401, status: 'Unauthorized');\n}\n\nbase class ForbiddenError extends ApiError {\n const ForbiddenError(String message)\n : super(message, statusCode: 403, status: 'Forbidden');\n}\n\nbase class NotFoundError extends ApiError {\n const NotFoundError(String message)\n : super(message, statusCode: 404, status: 'NotFound');\n}\n\nbase class InternalServerError extends ApiError {\n const InternalServerError(String message)\n : super(message, statusCode: 500, status: 'InternalServerError');\n}\n\nbase class UnknownApiError extends ApiError {\n const UnknownApiError(String message, int statusCode)\n : super(message, statusCode: statusCode, status: 'UnknownApiError');\n}\n\nbase class PaymentRequiredError extends ApiError {\n const PaymentRequiredError(String message)\n : super(message, statusCode: 402, status: 'PaymentRequired');\n}\n\nbase class MethodNotAllowedError extends ApiError {\n const MethodNotAllowedError(String message)\n : super(message, statusCode: 405, status: 'MethodNotAllowed');\n}\n\nbase class NotAcceptableError extends ApiError {\n const NotAcceptableError(String message)\n : super(message, statusCode: 406, status: 'NotAcceptable');\n}\n\nbase class ConflictError extends ApiError {\n const ConflictError(String message)\n : super(message, statusCode: 409, status: 'Conflict');\n}\n\nbase class GoneError extends ApiError {\n const GoneError(String message)\n : super(message, statusCode: 410, status: 'Gone');\n}\n\nbase class UnprocessableEntityError extends ApiError {\n const UnprocessableEntityError(String message)\n : super(message, statusCode: 422, status: 'UnprocessableEntity');\n}\n\nbase class TooManyRequestsError extends ApiError {\n const TooManyRequestsError(String message)\n : super(message, statusCode: 429, status: 'TooManyRequests');\n}\n\nbase class PayloadTooLargeError extends ApiError {\n const PayloadTooLargeError(String message)\n : super(message, statusCode: 413, status: 'PayloadTooLarge');\n}\n\nbase class UnsupportedMediaTypeError extends ApiError {\n const UnsupportedMediaTypeError(String message)\n : super(message, statusCode: 415, status: 'UnsupportedMediaType');\n}\n\nbase class NotImplementedError extends ApiError {\n const NotImplementedError(String message)\n : super(message, statusCode: 501, status: 'NotImplemented');\n}\n\nbase class BadGatewayError extends ApiError {\n const BadGatewayError(String message)\n : super(message, statusCode: 502, status: 'BadGateway');\n}\n\nbase class ServiceUnavailableError extends ApiError {\n const ServiceUnavailableError(String message)\n : super(message, statusCode: 503, status: 'ServiceUnavailable');\n}\n\nbase class GatewayTimeoutError extends ApiError {\n const GatewayTimeoutError(String message)\n : super(message, statusCode: 504, status: 'GatewayTimeout');\n}\n";
|
|
@@ -979,14 +1913,14 @@ var responses_default = "sealed class ApiError {\n final String message;\n fin
|
|
|
979
1913
|
// packages/dart/src/lib/generate.ts
|
|
980
1914
|
function tuneSpec(spec, schemas, refs) {
|
|
981
1915
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
982
|
-
if (
|
|
1916
|
+
if (isRef4(schema))
|
|
983
1917
|
continue;
|
|
984
|
-
if (!
|
|
1918
|
+
if (!isEmpty3(schema.anyOf) && !isEmpty3(schema.oneOf)) {
|
|
985
1919
|
delete schema.anyOf;
|
|
986
1920
|
}
|
|
987
|
-
if (!
|
|
1921
|
+
if (!isEmpty3(schema.allOf)) {
|
|
988
1922
|
const schemas2 = schema.allOf;
|
|
989
|
-
const refs2 = schemas2.filter(
|
|
1923
|
+
const refs2 = schemas2.filter(isRef4);
|
|
990
1924
|
const nonRefs = schemas2.filter(notRef2);
|
|
991
1925
|
if (nonRefs.some((it) => it.type && it.type !== "object")) {
|
|
992
1926
|
assert2(false, `allOf ${name} must be an object`);
|
|
@@ -994,19 +1928,19 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
994
1928
|
const objectSchema = merge2(
|
|
995
1929
|
{},
|
|
996
1930
|
...nonRefs,
|
|
997
|
-
...refs2.map((ref) =>
|
|
1931
|
+
...refs2.map((ref) => followRef3(spec, ref.$ref))
|
|
998
1932
|
);
|
|
999
1933
|
delete objectSchema.allOf;
|
|
1000
1934
|
delete schema.allOf;
|
|
1001
1935
|
Object.assign(schema, objectSchema);
|
|
1002
1936
|
}
|
|
1003
1937
|
if (schema.type === "object") {
|
|
1004
|
-
if (!
|
|
1938
|
+
if (!isEmpty3(schema.oneOf)) {
|
|
1005
1939
|
for (const oneOfIdx in schema.oneOf) {
|
|
1006
1940
|
const oneOf = schema.oneOf[oneOfIdx];
|
|
1007
|
-
if (
|
|
1941
|
+
if (isRef4(oneOf))
|
|
1008
1942
|
continue;
|
|
1009
|
-
if (!
|
|
1943
|
+
if (!isEmpty3(oneOf.required) && schema.properties) {
|
|
1010
1944
|
schema.oneOf[oneOfIdx] = schema.properties[oneOf.required[0]];
|
|
1011
1945
|
}
|
|
1012
1946
|
}
|
|
@@ -1016,7 +1950,7 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
1016
1950
|
}
|
|
1017
1951
|
schema.properties ??= {};
|
|
1018
1952
|
for (const [propName, value] of Object.entries(schema.properties)) {
|
|
1019
|
-
if (
|
|
1953
|
+
if (isRef4(value))
|
|
1020
1954
|
continue;
|
|
1021
1955
|
const refName = pascalcase2(`${name} ${propName.replace("[]", "")}`);
|
|
1022
1956
|
refs.push({ name: refName, value });
|
|
@@ -1031,7 +1965,7 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
1031
1965
|
tuneSpec(spec, props, refs);
|
|
1032
1966
|
}
|
|
1033
1967
|
} else if (schema.type === "array") {
|
|
1034
|
-
if (
|
|
1968
|
+
if (isRef4(schema.items))
|
|
1035
1969
|
continue;
|
|
1036
1970
|
const refName = name;
|
|
1037
1971
|
refs.push({ name: refName, value: schema.items ?? {} });
|
|
@@ -1042,6 +1976,16 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
1042
1976
|
}
|
|
1043
1977
|
}
|
|
1044
1978
|
async function generate(spec, settings) {
|
|
1979
|
+
spec = "x-sdk-augmented" in spec ? spec : augmentSpec({ spec });
|
|
1980
|
+
settings.writer ??= writeFiles;
|
|
1981
|
+
settings.readFolder ??= async (folder) => {
|
|
1982
|
+
const files = await readdir(folder, { withFileTypes: true });
|
|
1983
|
+
return files.map((file) => ({
|
|
1984
|
+
fileName: file.name,
|
|
1985
|
+
filePath: join(file.parentPath, file.name),
|
|
1986
|
+
isFolder: file.isDirectory()
|
|
1987
|
+
}));
|
|
1988
|
+
};
|
|
1045
1989
|
const clientName = settings.name || "Client";
|
|
1046
1990
|
const output = join(settings.output, "lib");
|
|
1047
1991
|
const groups = {};
|
|
@@ -1056,15 +2000,16 @@ async function generate(spec, settings) {
|
|
|
1056
2000
|
for (const status in operation.responses) {
|
|
1057
2001
|
if (!isSuccessStatusCode(status))
|
|
1058
2002
|
continue;
|
|
1059
|
-
const response2 =
|
|
1060
|
-
if (!
|
|
2003
|
+
const response2 = operation.responses[status];
|
|
2004
|
+
if (!isEmpty3(response2.content)) {
|
|
1061
2005
|
for (const [contentType, mediaType] of Object.entries(
|
|
1062
2006
|
response2.content
|
|
1063
2007
|
)) {
|
|
1064
2008
|
if (parseJsonContentType(contentType)) {
|
|
1065
|
-
if (mediaType.schema && !
|
|
2009
|
+
if (mediaType.schema && !isRef4(mediaType.schema)) {
|
|
1066
2010
|
const outputName = pascalcase2(`${operation.operationId} output`);
|
|
1067
2011
|
spec.components.schemas[outputName] = mediaType.schema;
|
|
2012
|
+
operation.responses[status].content ??= {};
|
|
1068
2013
|
operation.responses[status].content[contentType].schema = {
|
|
1069
2014
|
$ref: `#/components/schemas/${outputName}`
|
|
1070
2015
|
};
|
|
@@ -1086,7 +2031,7 @@ async function generate(spec, settings) {
|
|
|
1086
2031
|
}
|
|
1087
2032
|
group.methods.push(`
|
|
1088
2033
|
Future<${response ? response.returnType : "http.StreamedResponse"}> ${camelcase3(operation.operationId)}(
|
|
1089
|
-
${
|
|
2034
|
+
${isEmpty3(operation.requestBody) ? "" : `${input.inputName} input`}
|
|
1090
2035
|
) async {
|
|
1091
2036
|
final stream = await this.dispatcher.${input.contentType}(RequestConfig(
|
|
1092
2037
|
method: '${entry.method}',
|
|
@@ -1151,7 +2096,7 @@ import './http.dart';
|
|
|
1151
2096
|
${Object.keys(groups).map((name) => `late final ${pascalcase2(name)}Client ${camelcase3(name)};`).join("\n")}
|
|
1152
2097
|
|
|
1153
2098
|
${clientName}(this.options) {
|
|
1154
|
-
final interceptors = [BaseUrlInterceptor(() => this.options.baseUrl)];
|
|
2099
|
+
final interceptors = [BaseUrlInterceptor(() => this.options.baseUrl), LoggingInterceptor()];
|
|
1155
2100
|
final dispatcher = Dispatcher(interceptors);
|
|
1156
2101
|
final receiver = Receiver(interceptors);
|
|
1157
2102
|
${Object.keys(groups).map(
|
|
@@ -1174,39 +2119,55 @@ class Options {
|
|
|
1174
2119
|
}
|
|
1175
2120
|
|
|
1176
2121
|
`;
|
|
1177
|
-
await
|
|
2122
|
+
await settings.writer(output, {
|
|
1178
2123
|
...models,
|
|
1179
2124
|
...inputs,
|
|
1180
2125
|
...outputs
|
|
1181
2126
|
});
|
|
1182
|
-
await
|
|
1183
|
-
"models/index.dart": await getFolderExportsV2(
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
"
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
2127
|
+
await settings.writer(output, {
|
|
2128
|
+
"models/index.dart": await getFolderExportsV2(
|
|
2129
|
+
join(output, "models"),
|
|
2130
|
+
settings.readFolder,
|
|
2131
|
+
{
|
|
2132
|
+
exportSyntax: "export",
|
|
2133
|
+
extensions: "dart"
|
|
2134
|
+
}
|
|
2135
|
+
),
|
|
2136
|
+
"inputs/index.dart": await getFolderExportsV2(
|
|
2137
|
+
join(output, "inputs"),
|
|
2138
|
+
settings.readFolder,
|
|
2139
|
+
{
|
|
2140
|
+
exportSyntax: "export",
|
|
2141
|
+
extensions: "dart"
|
|
2142
|
+
}
|
|
2143
|
+
),
|
|
2144
|
+
"outputs/index.dart": await getFolderExportsV2(
|
|
2145
|
+
join(output, "outputs"),
|
|
2146
|
+
settings.readFolder,
|
|
2147
|
+
{
|
|
2148
|
+
exportSyntax: "export",
|
|
2149
|
+
extensions: "dart"
|
|
2150
|
+
}
|
|
2151
|
+
),
|
|
1195
2152
|
"interceptors.dart": interceptors_default,
|
|
1196
2153
|
"http.dart": dispatcher_default,
|
|
1197
2154
|
"responses.dart": responses_default,
|
|
1198
2155
|
...clazzez
|
|
1199
2156
|
});
|
|
1200
|
-
await
|
|
1201
|
-
"package.dart": `${await getFolderExportsV2(
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
2157
|
+
await settings.writer(output, {
|
|
2158
|
+
"package.dart": `${await getFolderExportsV2(
|
|
2159
|
+
join(output),
|
|
2160
|
+
settings.readFolder,
|
|
2161
|
+
{
|
|
2162
|
+
exportSyntax: "export",
|
|
2163
|
+
extensions: "dart",
|
|
2164
|
+
ignore(dirent) {
|
|
2165
|
+
return !dirent.isFolder && dirent.fileName === "package.dart";
|
|
2166
|
+
}
|
|
1206
2167
|
}
|
|
1207
|
-
|
|
2168
|
+
)}${client}`
|
|
1208
2169
|
});
|
|
1209
|
-
await
|
|
2170
|
+
await settings.writer(settings.output, {
|
|
1210
2171
|
"pubspec.yaml": {
|
|
1211
2172
|
ignoreIfExists: true,
|
|
1212
2173
|
content: yaml.stringify({
|
|
@@ -1231,16 +2192,18 @@ function toInputs(spec, { entry, operation }) {
|
|
|
1231
2192
|
const inputName = pascalcase2(`${operation.operationId} input`);
|
|
1232
2193
|
let contentType = "empty";
|
|
1233
2194
|
let encode = "";
|
|
1234
|
-
if (!
|
|
1235
|
-
const
|
|
1236
|
-
|
|
1237
|
-
const ctSchema = isRef2(requestBody.content[type].schema) ? followRef2(spec, requestBody.content[type].schema.$ref) : requestBody.content[type].schema;
|
|
2195
|
+
if (!isEmpty3(operation.requestBody)) {
|
|
2196
|
+
for (const type in operation.requestBody.content) {
|
|
2197
|
+
const ctSchema = isRef4(operation.requestBody.content[type].schema) ? followRef3(spec, operation.requestBody.content[type].schema.$ref) : operation.requestBody.content[type].schema;
|
|
1238
2198
|
if (!ctSchema) {
|
|
1239
2199
|
console.warn(
|
|
1240
2200
|
`Schema not found for ${type} in ${entry.method} ${entry.path}`
|
|
1241
2201
|
);
|
|
1242
2202
|
continue;
|
|
1243
2203
|
}
|
|
2204
|
+
ctSchema.properties ??= {};
|
|
2205
|
+
ctSchema.required ??= [];
|
|
2206
|
+
patchParameters(spec, ctSchema, operation);
|
|
1244
2207
|
const serializer = new DartSerializer(spec, (name, content) => {
|
|
1245
2208
|
inputs[join(`inputs/${name}.dart`)] = `import 'dart:io';import 'dart:typed_data';import '../models/index.dart'; import './index.dart';
|
|
1246
2209
|
|
|
@@ -1257,6 +2220,20 @@ ${content}`;
|
|
|
1257
2220
|
contentType = mediaType;
|
|
1258
2221
|
}
|
|
1259
2222
|
}
|
|
2223
|
+
} else {
|
|
2224
|
+
const ctSchema = {
|
|
2225
|
+
type: "object"
|
|
2226
|
+
};
|
|
2227
|
+
patchParameters(spec, ctSchema, operation);
|
|
2228
|
+
const serializer = new DartSerializer(spec, (name, content) => {
|
|
2229
|
+
inputs[join(`inputs/${name}.dart`)] = `import 'dart:io';import 'dart:typed_data';import '../models/index.dart'; import './index.dart';
|
|
2230
|
+
|
|
2231
|
+
${content}`;
|
|
2232
|
+
});
|
|
2233
|
+
const serialized = serializer.handle(inputName, ctSchema, true, {
|
|
2234
|
+
alias: isObjectSchema(ctSchema) ? void 0 : inputName
|
|
2235
|
+
});
|
|
2236
|
+
encode = serialized.encode;
|
|
1260
2237
|
}
|
|
1261
2238
|
return { inputs, inputName, contentType, encode };
|
|
1262
2239
|
}
|
|
@@ -1265,7 +2242,7 @@ function toOutput(spec, operation) {
|
|
|
1265
2242
|
operation.responses ??= {};
|
|
1266
2243
|
const outputs = {};
|
|
1267
2244
|
for (const status in operation.responses) {
|
|
1268
|
-
const response =
|
|
2245
|
+
const response = isRef4(operation.responses[status]) ? followRef3(spec, operation.responses[status].$ref) : operation.responses[status];
|
|
1269
2246
|
for (const type in response.content) {
|
|
1270
2247
|
const { schema } = response.content[type];
|
|
1271
2248
|
if (!schema) {
|