@sdk-it/core 0.12.9 → 0.12.11
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/package.json +2 -2
- package/dist/index 2.js +0 -844
- package/dist/index 3.js +0 -732
- package/dist/index 4.js +0 -732
- package/dist/index 5.js +0 -732
- package/dist/index 6.js +0 -853
- package/dist/index 7.js +0 -0
- package/dist/index 8.js +0 -844
- package/dist/index.d 2.ts +0 -14
- package/dist/index.d 3.ts +0 -8
- package/dist/index.d 4.ts +0 -8
- package/dist/index.d 5.ts +0 -14
- package/dist/index.d 6.ts +0 -14
- package/dist/index.d 7.ts +0 -8
- package/dist/index.d 8.ts +0 -8
- package/dist/index.d.ts 2.map +0 -1
- package/dist/index.d.ts 3.map +0 -1
- package/dist/index.d.ts 4.map +0 -1
- package/dist/index.d.ts 5.map +0 -1
- package/dist/index.d.ts 6.map +0 -1
- package/dist/index.d.ts 7.map +0 -1
- package/dist/index.d.ts 8.map +0 -1
- package/dist/index.js 2.map +0 -7
- package/dist/index.js 3.map +0 -7
- package/dist/index.js 4.map +0 -7
- package/dist/index.js 5.map +0 -7
- package/dist/index.js 6.map +0 -7
- package/dist/index.js 7.map +0 -7
- package/dist/index.js 8.map +0 -7
package/dist/index 3.js
DELETED
|
@@ -1,732 +0,0 @@
|
|
|
1
|
-
// packages/core/src/lib/deriver.ts
|
|
2
|
-
import ts, { TypeFlags, symbolName } from "typescript";
|
|
3
|
-
var deriveSymbol = Symbol.for("serialize");
|
|
4
|
-
var $types = Symbol.for("types");
|
|
5
|
-
var defaults = {
|
|
6
|
-
ReadableStream: "any",
|
|
7
|
-
DateConstructor: "string",
|
|
8
|
-
ArrayBufferConstructor: "any",
|
|
9
|
-
SharedArrayBufferConstructor: "any",
|
|
10
|
-
Int8ArrayConstructor: "any",
|
|
11
|
-
Uint8Array: "any"
|
|
12
|
-
};
|
|
13
|
-
var TypeDeriver = class {
|
|
14
|
-
collector = {};
|
|
15
|
-
checker;
|
|
16
|
-
constructor(checker) {
|
|
17
|
-
this.checker = checker;
|
|
18
|
-
}
|
|
19
|
-
serializeType(type) {
|
|
20
|
-
if (type.flags & TypeFlags.Any) {
|
|
21
|
-
return {
|
|
22
|
-
[deriveSymbol]: true,
|
|
23
|
-
optional: false,
|
|
24
|
-
[$types]: []
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
if (type.flags & ts.TypeFlags.Boolean) {
|
|
28
|
-
return {
|
|
29
|
-
[deriveSymbol]: true,
|
|
30
|
-
optional: false,
|
|
31
|
-
[$types]: ["boolean"]
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
if (type.isIntersection()) {
|
|
35
|
-
let optional;
|
|
36
|
-
const types = [];
|
|
37
|
-
for (const unionType of type.types) {
|
|
38
|
-
if (optional === void 0) {
|
|
39
|
-
optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;
|
|
40
|
-
if (optional) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
types.push(this.serializeType(unionType));
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
[deriveSymbol]: true,
|
|
48
|
-
kind: "intersection",
|
|
49
|
-
optional,
|
|
50
|
-
[$types]: types
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
if (type.isUnion()) {
|
|
54
|
-
let optional;
|
|
55
|
-
const types = [];
|
|
56
|
-
for (const unionType of type.types) {
|
|
57
|
-
if (optional === void 0) {
|
|
58
|
-
optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;
|
|
59
|
-
if (optional) {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
types.push(this.serializeType(unionType));
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
[deriveSymbol]: true,
|
|
67
|
-
kind: "union",
|
|
68
|
-
optional,
|
|
69
|
-
[$types]: types
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
if (this.checker.isArrayLikeType(type)) {
|
|
73
|
-
const [argType] = this.checker.getTypeArguments(type);
|
|
74
|
-
if (!argType) {
|
|
75
|
-
const typeName = type.symbol?.getName() || "<unknown>";
|
|
76
|
-
console.warn(
|
|
77
|
-
`Could not find generic type argument for array type ${typeName}`
|
|
78
|
-
);
|
|
79
|
-
return {
|
|
80
|
-
[deriveSymbol]: true,
|
|
81
|
-
optional: false,
|
|
82
|
-
kind: "array",
|
|
83
|
-
[$types]: ["any"]
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
const typeSymbol = argType.getSymbol();
|
|
87
|
-
if (!typeSymbol) {
|
|
88
|
-
return {
|
|
89
|
-
[deriveSymbol]: true,
|
|
90
|
-
optional: false,
|
|
91
|
-
kind: "array",
|
|
92
|
-
[$types]: [this.serializeType(argType)]
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
if (typeSymbol.valueDeclaration) {
|
|
96
|
-
return {
|
|
97
|
-
kind: "array",
|
|
98
|
-
[deriveSymbol]: true,
|
|
99
|
-
[$types]: [this.serializeNode(typeSymbol.valueDeclaration)]
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
const maybeDeclaration = typeSymbol.declarations?.[0];
|
|
103
|
-
if (maybeDeclaration) {
|
|
104
|
-
if (ts.isMappedTypeNode(maybeDeclaration)) {
|
|
105
|
-
const resolvedType = this.checker.getPropertiesOfType(argType).reduce((acc, prop) => {
|
|
106
|
-
const propType = this.checker.getTypeOfSymbol(prop);
|
|
107
|
-
acc[prop.name] = this.serializeType(propType);
|
|
108
|
-
return acc;
|
|
109
|
-
}, {});
|
|
110
|
-
return {
|
|
111
|
-
kind: "array",
|
|
112
|
-
optional: false,
|
|
113
|
-
[deriveSymbol]: true,
|
|
114
|
-
[$types]: [resolvedType]
|
|
115
|
-
};
|
|
116
|
-
} else {
|
|
117
|
-
return {
|
|
118
|
-
kind: "array",
|
|
119
|
-
...this.serializeNode(maybeDeclaration)
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
kind: "array",
|
|
125
|
-
optional: false,
|
|
126
|
-
[deriveSymbol]: true,
|
|
127
|
-
[$types]: ["any"]
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
if (type.isClass()) {
|
|
131
|
-
const declaration = type.symbol?.valueDeclaration;
|
|
132
|
-
if (!declaration) {
|
|
133
|
-
return {
|
|
134
|
-
[deriveSymbol]: true,
|
|
135
|
-
optional: false,
|
|
136
|
-
[$types]: [type.symbol.getName()]
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
return this.serializeNode(declaration);
|
|
140
|
-
}
|
|
141
|
-
if (isInterfaceType(type)) {
|
|
142
|
-
const valueDeclaration = type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];
|
|
143
|
-
if (!valueDeclaration) {
|
|
144
|
-
return {
|
|
145
|
-
[deriveSymbol]: true,
|
|
146
|
-
optional: false,
|
|
147
|
-
[$types]: [type.symbol.getName()]
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
return this.serializeNode(valueDeclaration);
|
|
151
|
-
}
|
|
152
|
-
if (type.flags & TypeFlags.Null) {
|
|
153
|
-
return {
|
|
154
|
-
[deriveSymbol]: true,
|
|
155
|
-
optional: true,
|
|
156
|
-
[$types]: ["null"]
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (type.flags & TypeFlags.Object) {
|
|
160
|
-
if (defaults[symbolName(type.symbol)]) {
|
|
161
|
-
return {
|
|
162
|
-
[deriveSymbol]: true,
|
|
163
|
-
optional: false,
|
|
164
|
-
[$types]: [defaults[type.symbol.name]]
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
const properties = this.checker.getPropertiesOfType(type);
|
|
168
|
-
if (properties.length > 0) {
|
|
169
|
-
const serializedProps = {};
|
|
170
|
-
for (const prop of properties) {
|
|
171
|
-
if ((prop.getDeclarations() ?? []).some(
|
|
172
|
-
(it) => ts.isPropertySignature(it) || ts.isPropertyAssignment(it)
|
|
173
|
-
)) {
|
|
174
|
-
const propType = this.checker.getTypeOfSymbol(prop);
|
|
175
|
-
serializedProps[prop.name] = this.serializeType(propType);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return {
|
|
179
|
-
[deriveSymbol]: true,
|
|
180
|
-
kind: "object",
|
|
181
|
-
optional: false,
|
|
182
|
-
[$types]: [serializedProps]
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
const declaration = type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];
|
|
186
|
-
if (!declaration) {
|
|
187
|
-
return {
|
|
188
|
-
[deriveSymbol]: true,
|
|
189
|
-
optional: false,
|
|
190
|
-
[$types]: [type.symbol.getName()]
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
return this.serializeNode(declaration);
|
|
194
|
-
}
|
|
195
|
-
return {
|
|
196
|
-
[deriveSymbol]: true,
|
|
197
|
-
optional: false,
|
|
198
|
-
[$types]: [
|
|
199
|
-
this.checker.typeToString(
|
|
200
|
-
type,
|
|
201
|
-
void 0,
|
|
202
|
-
ts.TypeFormatFlags.NoTruncation
|
|
203
|
-
)
|
|
204
|
-
]
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
serializeNode(node) {
|
|
208
|
-
if (ts.isObjectLiteralExpression(node)) {
|
|
209
|
-
const symbolType = this.checker.getTypeAtLocation(node);
|
|
210
|
-
const props = {};
|
|
211
|
-
for (const symbol of symbolType.getProperties()) {
|
|
212
|
-
const type = this.checker.getTypeOfSymbol(symbol);
|
|
213
|
-
props[symbol.name] = this.serializeType(type);
|
|
214
|
-
}
|
|
215
|
-
return props;
|
|
216
|
-
}
|
|
217
|
-
if (ts.isPropertyAccessExpression(node)) {
|
|
218
|
-
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
219
|
-
if (!symbol) {
|
|
220
|
-
console.warn(`No symbol found for ${node.name.getText()}`);
|
|
221
|
-
return null;
|
|
222
|
-
}
|
|
223
|
-
const type = this.checker.getTypeOfSymbol(symbol);
|
|
224
|
-
return this.serializeType(type);
|
|
225
|
-
}
|
|
226
|
-
if (ts.isPropertySignature(node)) {
|
|
227
|
-
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
228
|
-
if (!symbol) {
|
|
229
|
-
console.warn(`No symbol found for ${node.name.getText()}`);
|
|
230
|
-
return null;
|
|
231
|
-
}
|
|
232
|
-
const type = this.checker.getTypeOfSymbol(symbol);
|
|
233
|
-
return this.serializeType(type);
|
|
234
|
-
}
|
|
235
|
-
if (ts.isPropertyDeclaration(node)) {
|
|
236
|
-
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
237
|
-
if (!symbol) {
|
|
238
|
-
console.warn(`No symbol found for ${node.name.getText()}`);
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
const type = this.checker.getTypeOfSymbol(symbol);
|
|
242
|
-
return this.serializeType(type);
|
|
243
|
-
}
|
|
244
|
-
if (ts.isInterfaceDeclaration(node)) {
|
|
245
|
-
if (!node.name?.text) {
|
|
246
|
-
throw new Error("Interface has no name");
|
|
247
|
-
}
|
|
248
|
-
if (defaults[node.name.text]) {
|
|
249
|
-
return {
|
|
250
|
-
[deriveSymbol]: true,
|
|
251
|
-
optional: false,
|
|
252
|
-
[$types]: [defaults[node.name.text]]
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
if (!this.collector[node.name.text]) {
|
|
256
|
-
this.collector[node.name.text] = {};
|
|
257
|
-
const members = {};
|
|
258
|
-
for (const member of node.members.filter(ts.isPropertySignature)) {
|
|
259
|
-
members[member.name.getText()] = this.serializeNode(member);
|
|
260
|
-
}
|
|
261
|
-
this.collector[node.name.text] = members;
|
|
262
|
-
}
|
|
263
|
-
return {
|
|
264
|
-
[deriveSymbol]: true,
|
|
265
|
-
optional: false,
|
|
266
|
-
[$types]: [`#/components/schemas/${node.name.text}`]
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
if (ts.isClassDeclaration(node)) {
|
|
270
|
-
if (!node.name?.text) {
|
|
271
|
-
throw new Error("Class has no name");
|
|
272
|
-
}
|
|
273
|
-
if (defaults[node.name.text]) {
|
|
274
|
-
return {
|
|
275
|
-
[deriveSymbol]: true,
|
|
276
|
-
optional: false,
|
|
277
|
-
[$types]: [defaults[node.name.text]]
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
if (!this.collector[node.name.text]) {
|
|
281
|
-
this.collector[node.name.text] = {};
|
|
282
|
-
const members = {};
|
|
283
|
-
for (const member of node.members.filter(ts.isPropertyDeclaration)) {
|
|
284
|
-
members[member.name.getText()] = this.serializeNode(member);
|
|
285
|
-
}
|
|
286
|
-
this.collector[node.name.text] = members;
|
|
287
|
-
}
|
|
288
|
-
return {
|
|
289
|
-
[deriveSymbol]: true,
|
|
290
|
-
optional: false,
|
|
291
|
-
[$types]: [`#/components/schemas/${node.name.text}`],
|
|
292
|
-
$ref: `#/components/schemas/${node.name.text}`
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
if (ts.isVariableDeclaration(node)) {
|
|
296
|
-
const symbol = this.checker.getSymbolAtLocation(node.name);
|
|
297
|
-
if (!symbol) {
|
|
298
|
-
console.warn(`No symbol found for ${node.name.getText()}`);
|
|
299
|
-
return null;
|
|
300
|
-
}
|
|
301
|
-
if (!node.type) {
|
|
302
|
-
console.warn(`No type found for ${node.name.getText()}`);
|
|
303
|
-
return "any";
|
|
304
|
-
}
|
|
305
|
-
const type = this.checker.getTypeFromTypeNode(node.type);
|
|
306
|
-
return this.serializeType(type);
|
|
307
|
-
}
|
|
308
|
-
if (ts.isIdentifier(node)) {
|
|
309
|
-
const symbol = this.checker.getSymbolAtLocation(node);
|
|
310
|
-
if (!symbol) {
|
|
311
|
-
console.warn(`Identifer: No symbol found for ${node.getText()}`);
|
|
312
|
-
return null;
|
|
313
|
-
}
|
|
314
|
-
const type = this.checker.getTypeAtLocation(node);
|
|
315
|
-
return this.serializeType(type);
|
|
316
|
-
}
|
|
317
|
-
if (ts.isAwaitExpression(node)) {
|
|
318
|
-
const type = this.checker.getTypeAtLocation(node);
|
|
319
|
-
return this.serializeType(type);
|
|
320
|
-
}
|
|
321
|
-
if (ts.isCallExpression(node)) {
|
|
322
|
-
const type = this.checker.getTypeAtLocation(node);
|
|
323
|
-
return this.serializeType(type);
|
|
324
|
-
}
|
|
325
|
-
if (ts.isAsExpression(node)) {
|
|
326
|
-
const type = this.checker.getTypeAtLocation(node);
|
|
327
|
-
return this.serializeType(type);
|
|
328
|
-
}
|
|
329
|
-
if (ts.isTypeLiteralNode(node)) {
|
|
330
|
-
const symbolType = this.checker.getTypeAtLocation(node);
|
|
331
|
-
const props = {};
|
|
332
|
-
for (const symbol of symbolType.getProperties()) {
|
|
333
|
-
const type = this.checker.getTypeOfSymbol(symbol);
|
|
334
|
-
props[symbol.name] = this.serializeType(type);
|
|
335
|
-
}
|
|
336
|
-
return {
|
|
337
|
-
[deriveSymbol]: true,
|
|
338
|
-
optional: false,
|
|
339
|
-
[$types]: [props]
|
|
340
|
-
};
|
|
341
|
-
}
|
|
342
|
-
if (node.kind === ts.SyntaxKind.NullKeyword) {
|
|
343
|
-
return {
|
|
344
|
-
[deriveSymbol]: true,
|
|
345
|
-
optional: true,
|
|
346
|
-
[$types]: ["null"]
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
if (node.kind === ts.SyntaxKind.BooleanKeyword) {
|
|
350
|
-
return {
|
|
351
|
-
[deriveSymbol]: true,
|
|
352
|
-
optional: false,
|
|
353
|
-
[$types]: ["boolean"]
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
if (node.kind === ts.SyntaxKind.TrueKeyword || node.kind === ts.SyntaxKind.FalseKeyword) {
|
|
357
|
-
return {
|
|
358
|
-
[deriveSymbol]: true,
|
|
359
|
-
optional: false,
|
|
360
|
-
[$types]: ["boolean"]
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
if (ts.isArrayLiteralExpression(node)) {
|
|
364
|
-
const type = this.checker.getTypeAtLocation(node);
|
|
365
|
-
return this.serializeType(type);
|
|
366
|
-
}
|
|
367
|
-
console.warn(`Unhandled node: ${ts.SyntaxKind[node.kind]} ${node.flags}`);
|
|
368
|
-
return {
|
|
369
|
-
[deriveSymbol]: true,
|
|
370
|
-
optional: false,
|
|
371
|
-
[$types]: ["any"]
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
function isInterfaceType(type) {
|
|
376
|
-
if (type.isClassOrInterface()) {
|
|
377
|
-
return !!(type.symbol.flags & ts.SymbolFlags.Interface);
|
|
378
|
-
}
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// packages/core/src/lib/program.ts
|
|
383
|
-
import debug from "debug";
|
|
384
|
-
import { dirname, join } from "node:path";
|
|
385
|
-
import ts2 from "typescript";
|
|
386
|
-
var logger = debug("january:client");
|
|
387
|
-
function parseTsConfig(tsconfigPath) {
|
|
388
|
-
logger(`Using TypeScript version: ${ts2.version}`);
|
|
389
|
-
const configContent = ts2.readConfigFile(tsconfigPath, ts2.sys.readFile);
|
|
390
|
-
if (configContent.error) {
|
|
391
|
-
console.error(
|
|
392
|
-
`Failed to read tsconfig file:`,
|
|
393
|
-
ts2.formatDiagnosticsWithColorAndContext([configContent.error], {
|
|
394
|
-
getCanonicalFileName: (path) => path,
|
|
395
|
-
getCurrentDirectory: ts2.sys.getCurrentDirectory,
|
|
396
|
-
getNewLine: () => ts2.sys.newLine
|
|
397
|
-
})
|
|
398
|
-
);
|
|
399
|
-
throw new Error("Failed to parse tsconfig.json");
|
|
400
|
-
}
|
|
401
|
-
const parsed = ts2.parseJsonConfigFileContent(
|
|
402
|
-
configContent.config,
|
|
403
|
-
ts2.sys,
|
|
404
|
-
dirname(tsconfigPath)
|
|
405
|
-
);
|
|
406
|
-
if (parsed.errors.length > 0) {
|
|
407
|
-
console.error(
|
|
408
|
-
`Errors found in tsconfig.json:`,
|
|
409
|
-
ts2.formatDiagnosticsWithColorAndContext(parsed.errors, {
|
|
410
|
-
getCanonicalFileName: (path) => path,
|
|
411
|
-
getCurrentDirectory: ts2.sys.getCurrentDirectory,
|
|
412
|
-
getNewLine: () => ts2.sys.newLine
|
|
413
|
-
})
|
|
414
|
-
);
|
|
415
|
-
throw new Error("Failed to parse tsconfig.json");
|
|
416
|
-
}
|
|
417
|
-
return parsed;
|
|
418
|
-
}
|
|
419
|
-
function getProgram(tsconfigPath) {
|
|
420
|
-
const tsConfigParseResult = parseTsConfig(tsconfigPath);
|
|
421
|
-
logger(`Parsing tsconfig`);
|
|
422
|
-
return ts2.createProgram({
|
|
423
|
-
options: {
|
|
424
|
-
...tsConfigParseResult.options,
|
|
425
|
-
noEmit: true,
|
|
426
|
-
incremental: true,
|
|
427
|
-
tsBuildInfoFile: join(dirname(tsconfigPath), "./.tsbuildinfo")
|
|
428
|
-
// not working atm
|
|
429
|
-
},
|
|
430
|
-
rootNames: tsConfigParseResult.fileNames,
|
|
431
|
-
projectReferences: tsConfigParseResult.projectReferences,
|
|
432
|
-
configFileParsingDiagnostics: tsConfigParseResult.errors
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
function getPropertyAssignment(node, name) {
|
|
436
|
-
if (ts2.isObjectLiteralExpression(node)) {
|
|
437
|
-
return node.properties.filter((prop) => ts2.isPropertyAssignment(prop)).find((prop) => prop.name.getText() === name);
|
|
438
|
-
}
|
|
439
|
-
return void 0;
|
|
440
|
-
}
|
|
441
|
-
function isCallExpression(node, name) {
|
|
442
|
-
return ts2.isCallExpression(node) && node.expression && ts2.isIdentifier(node.expression) && node.expression.text === name;
|
|
443
|
-
}
|
|
444
|
-
function isInterfaceType2(type) {
|
|
445
|
-
if (type.isClassOrInterface()) {
|
|
446
|
-
return !!(type.symbol.flags & ts2.SymbolFlags.Interface);
|
|
447
|
-
}
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// packages/core/src/lib/paths.ts
|
|
452
|
-
var methods = [
|
|
453
|
-
"get",
|
|
454
|
-
"post",
|
|
455
|
-
"put",
|
|
456
|
-
"patch",
|
|
457
|
-
"delete",
|
|
458
|
-
"trace",
|
|
459
|
-
"head"
|
|
460
|
-
];
|
|
461
|
-
var semanticSourceToOpenAPI = {
|
|
462
|
-
queries: "query",
|
|
463
|
-
query: "query",
|
|
464
|
-
headers: "header",
|
|
465
|
-
params: "path"
|
|
466
|
-
};
|
|
467
|
-
var Paths = class {
|
|
468
|
-
#commonZodImport;
|
|
469
|
-
#onOperation;
|
|
470
|
-
#operations = [];
|
|
471
|
-
constructor(config) {
|
|
472
|
-
this.#commonZodImport = config.commonZodImport;
|
|
473
|
-
this.#onOperation = config.onOperation;
|
|
474
|
-
}
|
|
475
|
-
addPath(name, path, method, selectors, responses, sourceFile, tags, description) {
|
|
476
|
-
const responsesObject = this.#responseItemToResponses(responses);
|
|
477
|
-
this.#operations.push({
|
|
478
|
-
name,
|
|
479
|
-
path,
|
|
480
|
-
sourceFile,
|
|
481
|
-
method,
|
|
482
|
-
selectors,
|
|
483
|
-
responses: responsesObject,
|
|
484
|
-
tags,
|
|
485
|
-
description
|
|
486
|
-
});
|
|
487
|
-
return this;
|
|
488
|
-
}
|
|
489
|
-
#responseItemToResponses(responses) {
|
|
490
|
-
const responsesObject = {};
|
|
491
|
-
for (const item of responses) {
|
|
492
|
-
const ct = item.contentType;
|
|
493
|
-
const schema = item.response ? toSchema(item.response) : {};
|
|
494
|
-
if (!responsesObject[item.statusCode]) {
|
|
495
|
-
responsesObject[item.statusCode] = {
|
|
496
|
-
description: `Response for ${item.statusCode}`,
|
|
497
|
-
content: {
|
|
498
|
-
[ct]: ct === "application/octet-stream" ? { schema: { type: "string", format: "binary" } } : { schema }
|
|
499
|
-
},
|
|
500
|
-
headers: item.headers.length ? item.headers.reduce(
|
|
501
|
-
(acc, header) => ({
|
|
502
|
-
...acc,
|
|
503
|
-
[header]: { schema: { type: "string" } }
|
|
504
|
-
}),
|
|
505
|
-
{}
|
|
506
|
-
) : void 0
|
|
507
|
-
};
|
|
508
|
-
} else {
|
|
509
|
-
if (!responsesObject[item.statusCode].content[ct]) {
|
|
510
|
-
responsesObject[item.statusCode].content[ct] = { schema };
|
|
511
|
-
} else {
|
|
512
|
-
const existing = responsesObject[item.statusCode].content[ct].schema;
|
|
513
|
-
if (existing.oneOf) {
|
|
514
|
-
if (!existing.oneOf.find(
|
|
515
|
-
(it) => JSON.stringify(it) === JSON.stringify(schema)
|
|
516
|
-
)) {
|
|
517
|
-
existing.oneOf.push(schema);
|
|
518
|
-
}
|
|
519
|
-
} else if (JSON.stringify(existing) !== JSON.stringify(schema)) {
|
|
520
|
-
responsesObject[item.statusCode].content[ct].schema = {
|
|
521
|
-
oneOf: [existing, schema]
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
return responsesObject;
|
|
528
|
-
}
|
|
529
|
-
async #selectosToParameters(selectors) {
|
|
530
|
-
const parameters = [];
|
|
531
|
-
const bodySchemaProps = {};
|
|
532
|
-
for (const selector of selectors) {
|
|
533
|
-
if (selector.source === "body") {
|
|
534
|
-
bodySchemaProps[selector.name] = await evalZod(
|
|
535
|
-
selector.against,
|
|
536
|
-
this.#commonZodImport
|
|
537
|
-
);
|
|
538
|
-
continue;
|
|
539
|
-
}
|
|
540
|
-
const parameter = {
|
|
541
|
-
in: semanticSourceToOpenAPI[selector.source],
|
|
542
|
-
name: selector.name,
|
|
543
|
-
required: selector.required,
|
|
544
|
-
schema: await evalZod(selector.against, this.#commonZodImport)
|
|
545
|
-
};
|
|
546
|
-
parameters.push(parameter);
|
|
547
|
-
}
|
|
548
|
-
return { parameters, bodySchemaProps };
|
|
549
|
-
}
|
|
550
|
-
async getPaths() {
|
|
551
|
-
const operations = {};
|
|
552
|
-
for (const operation of this.#operations) {
|
|
553
|
-
const { path, method, selectors } = operation;
|
|
554
|
-
const { parameters, bodySchemaProps } = await this.#selectosToParameters(selectors);
|
|
555
|
-
const operationObject = {
|
|
556
|
-
operationId: operation.name,
|
|
557
|
-
parameters,
|
|
558
|
-
tags: operation.tags,
|
|
559
|
-
description: operation.description,
|
|
560
|
-
requestBody: Object.keys(bodySchemaProps).length ? {
|
|
561
|
-
content: {
|
|
562
|
-
"application/json": {
|
|
563
|
-
schema: {
|
|
564
|
-
type: "object",
|
|
565
|
-
properties: bodySchemaProps
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
} : void 0,
|
|
570
|
-
responses: operation.responses
|
|
571
|
-
};
|
|
572
|
-
if (!operations[path]) {
|
|
573
|
-
operations[path] = {};
|
|
574
|
-
}
|
|
575
|
-
operations[path][method] = operationObject;
|
|
576
|
-
if (this.#onOperation) {
|
|
577
|
-
const operations2 = this.#onOperation?.(
|
|
578
|
-
operation.sourceFile,
|
|
579
|
-
method,
|
|
580
|
-
path,
|
|
581
|
-
operationObject
|
|
582
|
-
);
|
|
583
|
-
Object.assign(operations2, operations2 ?? {});
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
return operations;
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
async function evalZod(schema, commonZodImport) {
|
|
590
|
-
const lines = [
|
|
591
|
-
`import { createRequire } from "node:module";`,
|
|
592
|
-
`const filename = "${import.meta.url}";`,
|
|
593
|
-
`const require = createRequire(filename);`,
|
|
594
|
-
`const z = require("zod");`,
|
|
595
|
-
commonZodImport ? `import * as commonZod from '${commonZodImport}';` : "",
|
|
596
|
-
`const {zodToJsonSchema} = require('zod-to-json-schema');`,
|
|
597
|
-
`const schema = ${schema.replace(".optional()", "")};`,
|
|
598
|
-
`const jsonSchema = zodToJsonSchema(schema, {
|
|
599
|
-
$refStrategy: 'root',
|
|
600
|
-
basePath: ['#', 'components', 'schemas']
|
|
601
|
-
});`,
|
|
602
|
-
`export default jsonSchema;`
|
|
603
|
-
];
|
|
604
|
-
const base64 = Buffer.from(lines.join("\n")).toString("base64");
|
|
605
|
-
return import(`data:text/javascript;base64,${base64}`).then((mod) => mod.default).then(({ $schema, ...result }) => result);
|
|
606
|
-
}
|
|
607
|
-
function toSchema(data) {
|
|
608
|
-
if (data === null || data === void 0) {
|
|
609
|
-
return { type: "any" };
|
|
610
|
-
} else if (typeof data === "string") {
|
|
611
|
-
const isRef = data.startsWith("#");
|
|
612
|
-
if (isRef) {
|
|
613
|
-
return { $ref: data };
|
|
614
|
-
}
|
|
615
|
-
return { type: data };
|
|
616
|
-
} else if (data.kind === "array") {
|
|
617
|
-
const items = data[$types].map(toSchema);
|
|
618
|
-
return { type: "array", items: data[$types].length ? items[0] : {} };
|
|
619
|
-
} else if (data.kind === "union") {
|
|
620
|
-
return { oneOf: data[$types].map(toSchema) };
|
|
621
|
-
} else if (data.kind === "intersection") {
|
|
622
|
-
return { allOf: data[$types].map(toSchema) };
|
|
623
|
-
} else if ($types in data) {
|
|
624
|
-
return data[$types].map(toSchema)[0] ?? {};
|
|
625
|
-
} else {
|
|
626
|
-
const props = {};
|
|
627
|
-
for (const [key, value] of Object.entries(data)) {
|
|
628
|
-
props[key] = toSchema(value);
|
|
629
|
-
}
|
|
630
|
-
return {
|
|
631
|
-
type: "object",
|
|
632
|
-
properties: props,
|
|
633
|
-
additionalProperties: false
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
function isHttpMethod(name) {
|
|
638
|
-
return ["get", "post", "put", "delete", "patch"].includes(name);
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// packages/core/src/lib/file-system.ts
|
|
642
|
-
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
643
|
-
import { dirname as dirname2, isAbsolute, join as join2 } from "node:path";
|
|
644
|
-
async function getFile(filePath) {
|
|
645
|
-
if (await exist(filePath)) {
|
|
646
|
-
return readFile(filePath, "utf-8");
|
|
647
|
-
}
|
|
648
|
-
return null;
|
|
649
|
-
}
|
|
650
|
-
async function exist(file) {
|
|
651
|
-
return stat(file).then(() => true).catch(() => false);
|
|
652
|
-
}
|
|
653
|
-
async function readFolder(path) {
|
|
654
|
-
if (await exist(path)) {
|
|
655
|
-
return readdir(path);
|
|
656
|
-
}
|
|
657
|
-
return [];
|
|
658
|
-
}
|
|
659
|
-
async function writeFiles(dir, contents) {
|
|
660
|
-
return Promise.all(
|
|
661
|
-
Object.entries(contents).map(async ([file, content]) => {
|
|
662
|
-
const filePath = isAbsolute(file) ? file : join2(dir, file);
|
|
663
|
-
await mkdir(dirname2(filePath), { recursive: true });
|
|
664
|
-
if (typeof content === "string") {
|
|
665
|
-
await writeFile(filePath, content, "utf-8");
|
|
666
|
-
} else {
|
|
667
|
-
if (content.ignoreIfExists) {
|
|
668
|
-
if (!await exist(filePath)) {
|
|
669
|
-
await writeFile(filePath, content.content, "utf-8");
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
})
|
|
674
|
-
);
|
|
675
|
-
}
|
|
676
|
-
async function getFolderExports(folder, extensions = ["ts"]) {
|
|
677
|
-
const files = await readdir(folder, { withFileTypes: true });
|
|
678
|
-
const exports = [];
|
|
679
|
-
for (const file of files) {
|
|
680
|
-
if (file.isDirectory()) {
|
|
681
|
-
exports.push(`export * from './${file.name}';`);
|
|
682
|
-
} else if (file.name !== "index.ts" && extensions.includes(getExt(file.name))) {
|
|
683
|
-
exports.push(`export * from './${file.name}';`);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
return exports.join("\n");
|
|
687
|
-
}
|
|
688
|
-
var getExt = (fileName) => {
|
|
689
|
-
if (!fileName) {
|
|
690
|
-
return "";
|
|
691
|
-
}
|
|
692
|
-
const lastDot = fileName.lastIndexOf(".");
|
|
693
|
-
if (lastDot === -1) {
|
|
694
|
-
return "";
|
|
695
|
-
}
|
|
696
|
-
const ext = fileName.slice(lastDot + 1).split("/").filter(Boolean).join("");
|
|
697
|
-
if (ext === fileName) {
|
|
698
|
-
return "";
|
|
699
|
-
}
|
|
700
|
-
return ext || "txt";
|
|
701
|
-
};
|
|
702
|
-
|
|
703
|
-
// packages/core/src/index.ts
|
|
704
|
-
function removeDuplicates(data, accessor) {
|
|
705
|
-
return [...new Map(data.map((x) => [accessor(x), x])).values()];
|
|
706
|
-
}
|
|
707
|
-
function toLitObject(obj, accessor = (value) => value) {
|
|
708
|
-
return `{${Object.keys(obj).map((key) => `${key}: ${accessor(obj[key])}`).join(", ")}}`;
|
|
709
|
-
}
|
|
710
|
-
export {
|
|
711
|
-
$types,
|
|
712
|
-
Paths,
|
|
713
|
-
TypeDeriver,
|
|
714
|
-
deriveSymbol,
|
|
715
|
-
exist,
|
|
716
|
-
getExt,
|
|
717
|
-
getFile,
|
|
718
|
-
getFolderExports,
|
|
719
|
-
getProgram,
|
|
720
|
-
getPropertyAssignment,
|
|
721
|
-
isCallExpression,
|
|
722
|
-
isHttpMethod,
|
|
723
|
-
isInterfaceType2 as isInterfaceType,
|
|
724
|
-
methods,
|
|
725
|
-
parseTsConfig,
|
|
726
|
-
readFolder,
|
|
727
|
-
removeDuplicates,
|
|
728
|
-
toLitObject,
|
|
729
|
-
toSchema,
|
|
730
|
-
writeFiles
|
|
731
|
-
};
|
|
732
|
-
//# sourceMappingURL=index.js.map
|