@sdk-it/hono 0.1.1 → 0.2.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.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './lib/hono.ts';
1
+ export * from './lib/response-analyzer.ts';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -1,562 +1,13 @@
1
- // packages/hono/src/lib/hono.ts
2
- import debug2 from "debug";
3
- import { join as join2 } from "node:path";
4
- import { camelcase } from "stringcase";
5
- import ts3 from "typescript";
6
-
7
- // packages/core/dist/index.js
8
- import ts, { TypeFlags } from "typescript";
1
+ // packages/hono/src/lib/response-analyzer.ts
9
2
  import debug from "debug";
10
- import { dirname, join } from "node:path";
11
- import ts2 from "typescript";
12
- var deriveSymbol = Symbol.for("serialize");
13
- var $types = Symbol.for("types");
14
- var TypeDeriver = class {
15
- collector = {};
16
- checker;
17
- constructor(checker) {
18
- this.checker = checker;
19
- }
20
- serializeType(type) {
21
- if (type.flags & TypeFlags.Any) {
22
- return {
23
- [deriveSymbol]: true,
24
- optional: false,
25
- [$types]: []
26
- };
27
- }
28
- if (type.isIntersection()) {
29
- let optional;
30
- const types = [];
31
- for (const unionType of type.types) {
32
- if (optional === void 0) {
33
- optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;
34
- if (optional) {
35
- continue;
36
- }
37
- }
38
- types.push(this.serializeType(unionType));
39
- }
40
- return {
41
- [deriveSymbol]: true,
42
- kind: "intersection",
43
- optional,
44
- [$types]: types
45
- };
46
- }
47
- if (type.isUnion()) {
48
- let optional;
49
- const types = [];
50
- for (const unionType of type.types) {
51
- if (optional === void 0) {
52
- optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;
53
- if (optional) {
54
- continue;
55
- }
56
- }
57
- types.push(this.serializeType(unionType));
58
- }
59
- return {
60
- [deriveSymbol]: true,
61
- kind: "union",
62
- optional,
63
- [$types]: types
64
- };
65
- }
66
- if (this.checker.isArrayLikeType(type)) {
67
- const [argType] = this.checker.getTypeArguments(type);
68
- if (!argType) {
69
- const typeName = type.symbol?.getName() || "<unknown>";
70
- console.warn(
71
- `Could not find generic type argument for array type ${typeName}`
72
- );
73
- return {
74
- [deriveSymbol]: true,
75
- optional: false,
76
- kind: "array",
77
- [$types]: ["any"]
78
- };
79
- }
80
- const typeSymbol = argType.getSymbol();
81
- if (!typeSymbol) {
82
- console.warn(
83
- `No symbol found for array type ${this.checker.typeToString(argType)}`
84
- );
85
- const typeString = this.checker.typeToString(argType);
86
- return {
87
- [deriveSymbol]: true,
88
- optional: false,
89
- kind: "array",
90
- [$types]: typeString === "undefined" ? [] : [typeString]
91
- };
92
- }
93
- if (typeSymbol.valueDeclaration) {
94
- return {
95
- kind: "array",
96
- ...this.serializeNode(typeSymbol.valueDeclaration)
97
- };
98
- }
99
- const maybeDeclaration = typeSymbol.declarations?.[0];
100
- if (maybeDeclaration) {
101
- if (ts.isMappedTypeNode(maybeDeclaration)) {
102
- const resolvedType = this.checker.getPropertiesOfType(argType).reduce((acc, prop) => {
103
- const propType = this.checker.getTypeOfSymbol(prop);
104
- acc[prop.name] = this.serializeType(propType);
105
- return acc;
106
- }, {});
107
- return {
108
- kind: "array",
109
- optional: false,
110
- [deriveSymbol]: true,
111
- [$types]: [resolvedType]
112
- };
113
- } else {
114
- return {
115
- kind: "array",
116
- ...this.serializeNode(maybeDeclaration)
117
- };
118
- }
119
- }
120
- return {
121
- kind: "array",
122
- optional: false,
123
- [deriveSymbol]: true,
124
- [$types]: ["any"]
125
- };
126
- }
127
- if (type.isClass()) {
128
- const declaration = type.symbol?.valueDeclaration;
129
- if (!declaration) {
130
- return {
131
- [deriveSymbol]: true,
132
- optional: false,
133
- [$types]: [type.symbol.getName()]
134
- };
135
- }
136
- return this.serializeNode(declaration);
137
- }
138
- if (isInterfaceType(type)) {
139
- const valueDeclaration = type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];
140
- if (!valueDeclaration) {
141
- return {
142
- [deriveSymbol]: true,
143
- optional: false,
144
- [$types]: [type.symbol.getName()]
145
- };
146
- }
147
- return this.serializeNode(valueDeclaration);
148
- }
149
- if (type.flags & TypeFlags.Object) {
150
- const properties = this.checker.getPropertiesOfType(type);
151
- if (properties.length > 0) {
152
- const serializedProps = properties.reduce(
153
- (acc, prop) => {
154
- const propType = this.checker.getTypeOfSymbol(prop);
155
- acc[prop.name] = this.serializeType(propType);
156
- return acc;
157
- },
158
- {}
159
- );
160
- return {
161
- [deriveSymbol]: true,
162
- kind: "object",
163
- optional: false,
164
- [$types]: [serializedProps]
165
- };
166
- }
167
- const declaration = type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];
168
- if (!declaration) {
169
- return {
170
- [deriveSymbol]: true,
171
- optional: false,
172
- [$types]: [type.symbol.getName()]
173
- };
174
- }
175
- return this.serializeNode(declaration);
176
- }
177
- return {
178
- [deriveSymbol]: true,
179
- optional: false,
180
- [$types]: [
181
- this.checker.typeToString(
182
- type,
183
- void 0,
184
- ts.TypeFormatFlags.NoTruncation
185
- )
186
- ]
187
- };
188
- }
189
- serializeNode(node) {
190
- if (ts.isObjectLiteralExpression(node)) {
191
- const symbolType = this.checker.getTypeAtLocation(node);
192
- const props = {};
193
- for (const symbol of symbolType.getProperties()) {
194
- const type = this.checker.getTypeOfSymbol(symbol);
195
- props[symbol.name] = this.serializeType(type);
196
- }
197
- return props;
198
- }
199
- if (ts.isPropertyAccessExpression(node)) {
200
- const symbol = this.checker.getSymbolAtLocation(node.name);
201
- if (!symbol) {
202
- console.warn(`No symbol found for ${node.name.getText()}`);
203
- return null;
204
- }
205
- const type = this.checker.getTypeOfSymbol(symbol);
206
- return this.serializeType(type);
207
- }
208
- if (ts.isPropertySignature(node)) {
209
- const symbol = this.checker.getSymbolAtLocation(node.name);
210
- if (!symbol) {
211
- console.warn(`No symbol found for ${node.name.getText()}`);
212
- return null;
213
- }
214
- const type = this.checker.getTypeOfSymbol(symbol);
215
- return this.serializeType(type);
216
- }
217
- if (ts.isPropertyDeclaration(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.isInterfaceDeclaration(node)) {
227
- if (!node.name?.text) {
228
- throw new Error("Interface has no name");
229
- }
230
- const defaults = {
231
- ReadableStream: "ReadableStream",
232
- DateConstructor: "Date"
233
- };
234
- if (defaults[node.name.text]) {
235
- return {
236
- [deriveSymbol]: true,
237
- optional: false,
238
- [$types]: [`#/components/schemas/${node.name.text}`]
239
- };
240
- }
241
- if (!this.collector[node.name.text]) {
242
- this.collector[node.name.text] = {};
243
- const members = {};
244
- for (const member of node.members.filter(ts.isPropertySignature)) {
245
- members[member.name.getText()] = this.serializeNode(member);
246
- }
247
- this.collector[node.name.text] = members;
248
- }
249
- return {
250
- [deriveSymbol]: true,
251
- optional: false,
252
- [$types]: [`#/components/schemas/${node.name.text}`]
253
- };
254
- }
255
- if (ts.isClassDeclaration(node)) {
256
- if (!node.name?.text) {
257
- throw new Error("Class has no name");
258
- }
259
- if (!this.collector[node.name.text]) {
260
- this.collector[node.name.text] = {};
261
- const members = {};
262
- for (const member of node.members.filter(ts.isPropertyDeclaration)) {
263
- members[member.name.getText()] = this.serializeNode(member);
264
- }
265
- this.collector[node.name.text] = members;
266
- }
267
- return {
268
- [deriveSymbol]: true,
269
- optional: false,
270
- [$types]: [node.name.text],
271
- $ref: `#/components/schemas/${node.name.text}`
272
- };
273
- }
274
- if (ts.isVariableDeclaration(node)) {
275
- const symbol = this.checker.getSymbolAtLocation(node.name);
276
- if (!symbol) {
277
- console.warn(`No symbol found for ${node.name.getText()}`);
278
- return null;
279
- }
280
- if (!node.type) {
281
- console.warn(`No type found for ${node.name.getText()}`);
282
- return "any";
283
- }
284
- const type = this.checker.getTypeFromTypeNode(node.type);
285
- return this.serializeType(type);
286
- }
287
- if (ts.isIdentifier(node)) {
288
- const symbol = this.checker.getSymbolAtLocation(node);
289
- if (!symbol) {
290
- console.warn(`Identifer: No symbol found for ${node.getText()}`);
291
- return null;
292
- }
293
- const type = this.checker.getTypeAtLocation(node);
294
- return this.serializeType(type);
295
- }
296
- if (ts.isAwaitExpression(node)) {
297
- const type = this.checker.getTypeAtLocation(node);
298
- return this.serializeType(type);
299
- }
300
- if (ts.isCallExpression(node)) {
301
- const type = this.checker.getTypeAtLocation(node);
302
- return this.serializeType(type);
303
- }
304
- if (ts.isAsExpression(node)) {
305
- const type = this.checker.getTypeAtLocation(node);
306
- return this.serializeType(type);
307
- }
308
- if (ts.isTypeLiteralNode(node)) {
309
- const symbolType = this.checker.getTypeAtLocation(node);
310
- const props = {};
311
- for (const symbol of symbolType.getProperties()) {
312
- const type = this.checker.getTypeOfSymbol(symbol);
313
- props[symbol.name] = this.serializeType(type);
314
- }
315
- return {
316
- [deriveSymbol]: true,
317
- optional: false,
318
- [$types]: [props]
319
- };
320
- }
321
- if (node.kind === ts.SyntaxKind.NullKeyword) {
322
- return {
323
- [deriveSymbol]: true,
324
- optional: true,
325
- [$types]: ["null"]
326
- };
327
- }
328
- console.warn(`Unhandled node: ${ts.SyntaxKind[node.kind]} ${node.flags}`);
329
- return {
330
- [deriveSymbol]: true,
331
- optional: false,
332
- [$types]: ["any"]
333
- };
334
- }
335
- };
336
- function isInterfaceType(type) {
337
- if (type.isClassOrInterface()) {
338
- return !!(type.symbol.flags & ts.SymbolFlags.Interface);
339
- }
340
- return false;
341
- }
342
- var logger = debug("january:client");
343
- function parseTsConfig(tsconfigPath) {
344
- logger(`Using TypeScript version: ${ts2.version}`);
345
- const configContent = ts2.readConfigFile(tsconfigPath, ts2.sys.readFile);
346
- if (configContent.error) {
347
- console.error(
348
- `Failed to read tsconfig file:`,
349
- ts2.formatDiagnosticsWithColorAndContext([configContent.error], {
350
- getCanonicalFileName: (path) => path,
351
- getCurrentDirectory: ts2.sys.getCurrentDirectory,
352
- getNewLine: () => ts2.sys.newLine
353
- })
354
- );
355
- throw new Error("Failed to parse tsconfig.json");
356
- }
357
- const parsed = ts2.parseJsonConfigFileContent(
358
- configContent.config,
359
- ts2.sys,
360
- dirname(tsconfigPath)
361
- );
362
- if (parsed.errors.length > 0) {
363
- console.error(
364
- `Errors found in tsconfig.json:`,
365
- ts2.formatDiagnosticsWithColorAndContext(parsed.errors, {
366
- getCanonicalFileName: (path) => path,
367
- getCurrentDirectory: ts2.sys.getCurrentDirectory,
368
- getNewLine: () => ts2.sys.newLine
369
- })
370
- );
371
- throw new Error("Failed to parse tsconfig.json");
372
- }
373
- return parsed;
374
- }
375
- function getProgram(tsconfigPath) {
376
- const tsConfigParseResult = parseTsConfig(tsconfigPath);
377
- logger(`Parsing tsconfig`);
378
- return ts2.createProgram({
379
- options: {
380
- ...tsConfigParseResult.options,
381
- noEmit: true,
382
- incremental: true,
383
- tsBuildInfoFile: join(dirname(tsconfigPath), "./.tsbuildinfo")
384
- // not working atm
385
- },
386
- rootNames: tsConfigParseResult.fileNames,
387
- projectReferences: tsConfigParseResult.projectReferences,
388
- configFileParsingDiagnostics: tsConfigParseResult.errors
389
- });
390
- }
391
- function isCallExpression(node, name) {
392
- return ts2.isCallExpression(node) && node.expression && ts2.isIdentifier(node.expression) && node.expression.text === name;
393
- }
394
-
395
- // packages/hono/src/lib/paths.ts
396
- var semanticSourceToOpenAPI = {
397
- queries: "query",
398
- query: "query",
399
- headers: "header",
400
- params: "path"
401
- };
402
- var Paths = class {
403
- operations = [];
404
- addPath(name, path, method, selectors, responses) {
405
- const responsesObject = this.#responseItemToResponses(responses);
406
- this.operations.push({
407
- name,
408
- path,
409
- method,
410
- selectors,
411
- responses: responsesObject
412
- });
413
- return this;
414
- }
415
- #responseItemToResponses(responses) {
416
- const responsesObject = {};
417
- for (const item of responses) {
418
- const ct = item.contentType;
419
- const schema = toSchema(item.response);
420
- if (!responsesObject[item.statusCode]) {
421
- responsesObject[item.statusCode] = {
422
- description: `Response for ${item.statusCode}`,
423
- content: {
424
- [ct]: ct === "application/octet-stream" ? { schema: { type: "string", format: "binary" } } : { schema }
425
- },
426
- headers: item.headers.length ? item.headers.reduce(
427
- (acc, header) => ({
428
- ...acc,
429
- [header]: { schema: { type: "string" } }
430
- }),
431
- {}
432
- ) : void 0
433
- };
434
- } else {
435
- if (!responsesObject[item.statusCode].content[ct]) {
436
- responsesObject[item.statusCode].content[ct] = { schema };
437
- } else {
438
- const existing = responsesObject[item.statusCode].content[ct].schema;
439
- if (existing.oneOf) {
440
- if (!existing.oneOf.find(
441
- (it) => JSON.stringify(it) === JSON.stringify(schema)
442
- )) {
443
- existing.oneOf.push(schema);
444
- }
445
- } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {
446
- responsesObject[item.statusCode].content[ct].schema = {
447
- oneOf: [existing, schema]
448
- };
449
- }
450
- }
451
- }
452
- }
453
- return responsesObject;
454
- }
455
- async #selectosToParameters(selectors) {
456
- const parameters = [];
457
- const bodySchemaProps = {};
458
- for (const selector of selectors) {
459
- if (selector.source === "body") {
460
- bodySchemaProps[selector.name] = await evalZod(selector.against);
461
- continue;
462
- }
463
- const parameter = {
464
- in: semanticSourceToOpenAPI[selector.source],
465
- name: selector.name,
466
- required: selector.required,
467
- schema: await evalZod(selector.against)
468
- };
469
- parameters.push(parameter);
470
- }
471
- return { parameters, bodySchemaProps };
472
- }
473
- async getPaths() {
474
- const operations = {};
475
- for (const operation of this.operations) {
476
- const { name, path, method, selectors } = operation;
477
- const { parameters, bodySchemaProps } = await this.#selectosToParameters(selectors);
478
- const operationObject = {
479
- operationId: name,
480
- parameters,
481
- requestBody: Object.keys(bodySchemaProps).length ? {
482
- content: {
483
- "application/json": {
484
- schema: {
485
- type: "object",
486
- properties: bodySchemaProps
487
- }
488
- }
489
- }
490
- } : void 0,
491
- responses: operation.responses
492
- };
493
- if (!operations[path]) {
494
- operations[path] = {};
495
- }
496
- operations[path][method] = operationObject;
497
- }
498
- return operations;
499
- }
500
- };
501
- async function evalZod(schema) {
502
- const lines = [
503
- `import { z } from 'zod';`,
504
- `import { zodToJsonSchema } from 'zod-to-json-schema';`,
505
- `const schema = ${schema.replace(".optional()", "")};`,
506
- `const jsonSchema = zodToJsonSchema(schema, {
507
- $refStrategy: 'root',
508
- basePath: ['#', 'components', 'schemas']
509
- });`,
510
- `export default jsonSchema;`
511
- ];
512
- const base64Code = Buffer.from(lines.join("\n")).toString("base64");
513
- const dataUrl = `data:text/javascript;base64,${base64Code}`;
514
- return import(dataUrl).then((mod) => mod.default).then(({ $schema, ...result }) => result);
515
- }
516
- var typeMappings = {
517
- DateConstructor: "Date"
518
- };
519
- function toSchema(data) {
520
- if (data === null || data === void 0) {
521
- return { type: "any" };
522
- } else if (typeof data === "string") {
523
- const isRef = data.startsWith("#");
524
- if (isRef) {
525
- return { $ref: data };
526
- }
527
- return {
528
- type: `${typeMappings[data] || data}`
529
- };
530
- } else if (data.kind === "array") {
531
- const items = data[$types].map(toSchema);
532
- return { type: "array", items: data[$types].length ? items[0] : {} };
533
- } else if (data.kind === "union") {
534
- return { oneOf: data[$types].map(toSchema) };
535
- } else if (data.kind === "intersection") {
536
- return { allOf: data[$types].map(toSchema) };
537
- } else if ($types in data) {
538
- return data[$types].map(toSchema)[0] ?? {};
539
- } else {
540
- const props = {};
541
- for (const [key, value] of Object.entries(data)) {
542
- props[key] = toSchema(value);
543
- }
544
- return {
545
- type: "object",
546
- properties: props,
547
- additionalProperties: false
548
- };
549
- }
550
- }
551
-
552
- // packages/hono/src/lib/hono.ts
553
- var logger2 = debug2("connect:client");
554
- var visitor = (callback, contextVarName) => {
3
+ import ts from "typescript";
4
+ var logger = debug("@sdk-it/hono");
5
+ var handlerVisitor = (callback, contextVarName) => {
555
6
  return (node) => {
556
- if (ts3.isReturnStatement(node) && node.expression) {
557
- if (ts3.isCallExpression(node.expression) && node.expression.expression && ts3.isPropertyAccessExpression(node.expression.expression)) {
7
+ if (ts.isReturnStatement(node) && node.expression) {
8
+ if (ts.isCallExpression(node.expression) && ts.isPropertyAccessExpression(node.expression.expression)) {
558
9
  const propAccess = node.expression.expression;
559
- if (ts3.isIdentifier(propAccess.expression) && propAccess.expression.text === contextVarName) {
10
+ if (ts.isIdentifier(propAccess.expression) && propAccess.expression.text === contextVarName) {
560
11
  let contentType = "application/json";
561
12
  const callerMethod = propAccess.name.text;
562
13
  if (callerMethod === "body") {
@@ -567,123 +18,33 @@ var visitor = (callback, contextVarName) => {
567
18
  }
568
19
  }
569
20
  }
570
- return ts3.forEachChild(node, visitor(callback, contextVarName));
21
+ return ts.forEachChild(node, handlerVisitor(callback, contextVarName));
571
22
  };
572
23
  };
573
- function analyze(sourceFile, deriver, paths) {
574
- sourceFile.forEachChild((node) => {
575
- if (ts3.isExpressionStatement(node) && ts3.isCallExpression(node.expression)) {
576
- const openapiMiddleware = node.expression.arguments.find(
577
- (arg) => isCallExpression(arg, "openapi")
578
- );
579
- if (!openapiMiddleware) {
580
- return;
581
- }
582
- if (!ts3.isStringLiteral(node.expression.arguments[0])) {
583
- logger2(`Route path must be a string literal`);
584
- return;
585
- }
586
- if (!ts3.isPropertyAccessExpression(node.expression.expression) || !ts3.isIdentifier(node.expression.expression.name)) {
587
- logger2(`Invalid route method`);
588
- return;
589
- }
590
- const path = node.expression.arguments[0].text;
591
- const method = node.expression.expression.name.text.toLowerCase();
592
- if (!path || !method) {
593
- logger2(`Failed to extract path or method for route`);
594
- return;
595
- }
596
- const handlerMiddleware = node.expression.arguments.at(-1);
597
- if (!handlerMiddleware || !ts3.isArrowFunction(handlerMiddleware)) {
598
- console.warn(`No handler middleware found for ${method} ${path}`);
599
- return;
600
- }
601
- const operationName = camelcase(
602
- `${method} ${path.replace(/[^a-zA-Z0-9]/g, "")}`
603
- );
604
- const selector = openapiMiddleware.arguments.find(
605
- (arg) => ts3.isArrowFunction(arg)
606
- );
607
- if (!selector || !ts3.isParenthesizedExpression(selector.body)) {
608
- return;
609
- }
610
- if (!ts3.isObjectLiteralExpression(selector.body.expression)) {
611
- return;
612
- }
613
- const objExpr = selector.body.expression;
614
- const props = objExpr.properties.filter(ts3.isPropertyAssignment);
615
- const selectors = [];
616
- for (const prop of props) {
617
- if (!ts3.isObjectLiteralExpression(prop.initializer)) {
618
- continue;
619
- }
620
- const name = prop.name.getText();
621
- const select = prop.initializer.properties.filter(ts3.isPropertyAssignment).find((prop2) => prop2.name.getText() === "select");
622
- if (!select) {
623
- console.warn(`No select found in ${name}`);
624
- continue;
625
- }
626
- const against = prop.initializer.properties.filter(ts3.isPropertyAssignment).find((prop2) => prop2.name.getText() === "against");
627
- if (!against) {
628
- console.warn(`No against found in ${name}`);
629
- continue;
630
- }
631
- const [, source, selectText] = select.initializer.getText().split(".");
632
- selectors.push({
633
- name,
634
- nullable: against.initializer.getText().includes("nullable"),
635
- required: !against.initializer.getText().includes("optional"),
636
- select: selectText,
637
- against: against.initializer.getText(),
638
- source
639
- });
640
- }
641
- const contextVarName = handlerMiddleware.parameters[0].name.getText();
642
- const responsesList = [];
643
- const visit = visitor((node2, statusCode, headers, contentType) => {
644
- responsesList.push({
645
- headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],
646
- contentType,
647
- statusCode: statusCode ? resolveStatusCode(statusCode) : "200",
648
- response: deriver.serializeNode(node2)
649
- });
650
- }, contextVarName);
651
- visit(handlerMiddleware.body);
652
- paths.addPath(operationName, path, method, selectors, responsesList);
653
- }
654
- });
24
+ function toResponses(handler, deriver) {
25
+ const contextVarName = handler.parameters[0].name.getText();
26
+ const responsesList = [];
27
+ const visit = handlerVisitor((node, statusCode, headers, contentType) => {
28
+ responsesList.push({
29
+ headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],
30
+ contentType,
31
+ statusCode: statusCode ? resolveStatusCode(statusCode) : "200",
32
+ response: deriver.serializeNode(node)
33
+ });
34
+ }, contextVarName);
35
+ visit(handler.body);
36
+ return responsesList;
655
37
  }
656
38
  function resolveStatusCode(node) {
657
- if (ts3.isNumericLiteral(node)) {
39
+ if (ts.isNumericLiteral(node)) {
658
40
  return node.text;
659
41
  }
660
42
  throw new Error(`Could not resolve status code`);
661
43
  }
662
- async function serialize(tsconfigPath) {
663
- logger2(`Parsing tsconfig`);
664
- const program = getProgram(tsconfigPath);
665
- logger2(`Program created`);
666
- const typeChecker = program.getTypeChecker();
667
- logger2(`Type checker created`);
668
- const typeDeriver = new TypeDeriver(typeChecker);
669
- const paths = new Paths();
670
- analyze(
671
- program.getSourceFile(join2(process.cwd(), "apps/backend/src/main.ts")),
672
- typeDeriver,
673
- paths
674
- );
675
- const components = {
676
- schemas: Object.entries(typeDeriver.collector).reduce(
677
- (acc, [key, value]) => ({ ...acc, [key]: toSchema(value) }),
678
- {}
679
- )
680
- };
681
- return {
682
- paths: await paths.getPaths(),
683
- components
684
- };
44
+ function responseAnalyzer(handler, deriver) {
45
+ return toResponses(handler, deriver);
685
46
  }
686
47
  export {
687
- serialize
48
+ responseAnalyzer
688
49
  };
689
50
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/lib/hono.ts", "../../core/src/lib/deriver.ts", "../../core/src/lib/program.ts", "../src/lib/paths.ts"],
4
- "sourcesContent": ["import debug from 'debug';\nimport { join } from 'node:path';\nimport type { ComponentsObject } from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\nimport ts from 'typescript';\n\nimport { TypeDeriver, getProgram, isCallExpression } from '@sdk-it/core';\n\nimport {\n type Method,\n Paths,\n type ResponseItem,\n type Selector,\n type SemanticSource,\n toSchema,\n} from './paths.ts';\n\nconst logger = debug('connect:client');\n\nconst visitor: (\n on: (\n node: ts.Node,\n statusCode: ts.Node | undefined,\n headers: ts.Node | undefined,\n contentType: string,\n ) => void,\n contextVarName: string,\n) => ts.Visitor = (callback, contextVarName) => {\n return (node: ts.Node) => {\n if (ts.isReturnStatement(node) && node.expression) {\n if (\n ts.isCallExpression(node.expression) &&\n node.expression.expression &&\n ts.isPropertyAccessExpression(node.expression.expression)\n ) {\n const propAccess = node.expression.expression;\n if (\n ts.isIdentifier(propAccess.expression) &&\n propAccess.expression.text === contextVarName\n ) {\n let contentType = 'application/json';\n const callerMethod = propAccess.name.text;\n if (callerMethod === 'body') {\n contentType = 'application/octet-stream';\n }\n const [body, statusCode, headers] = node.expression.arguments;\n callback(body, statusCode, headers, contentType);\n }\n }\n }\n return ts.forEachChild(node, visitor(callback, contextVarName));\n };\n};\n\nfunction analyze(\n sourceFile: ts.SourceFile,\n deriver: TypeDeriver,\n paths: Paths,\n) {\n sourceFile.forEachChild((node) => {\n if (\n ts.isExpressionStatement(node) &&\n ts.isCallExpression(node.expression)\n ) {\n const openapiMiddleware = node.expression.arguments.find((arg) =>\n isCallExpression(arg, 'openapi'),\n );\n if (!openapiMiddleware) {\n return;\n }\n\n if (!ts.isStringLiteral(node.expression.arguments[0])) {\n logger(`Route path must be a string literal`);\n return;\n }\n\n if (\n !ts.isPropertyAccessExpression(node.expression.expression) ||\n !ts.isIdentifier(node.expression.expression.name)\n ) {\n logger(`Invalid route method`);\n return;\n }\n const path = node.expression.arguments[0].text;\n const method =\n node.expression.expression.name.text.toLowerCase() as Method;\n\n if (!path || !method) {\n logger(`Failed to extract path or method for route`);\n return;\n }\n\n const handlerMiddleware = node.expression.arguments.at(-1);\n if (!handlerMiddleware || !ts.isArrowFunction(handlerMiddleware)) {\n console.warn(`No handler middleware found for ${method} ${path}`);\n return;\n }\n\n const operationName = camelcase(\n `${method} ${path.replace(/[^a-zA-Z0-9]/g, '')}`,\n );\n\n const selector = openapiMiddleware.arguments.find((arg) =>\n ts.isArrowFunction(arg),\n );\n if (!selector || !ts.isParenthesizedExpression(selector.body)) {\n return;\n }\n if (!ts.isObjectLiteralExpression(selector.body.expression)) {\n return;\n }\n const objExpr = selector.body.expression;\n const props = objExpr.properties.filter(ts.isPropertyAssignment);\n\n const selectors: Selector[] = [];\n for (const prop of props) {\n if (!ts.isObjectLiteralExpression(prop.initializer)) {\n continue;\n }\n const name = prop.name.getText();\n const select = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'select');\n if (!select) {\n console.warn(`No select found in ${name}`);\n continue;\n }\n const against = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'against');\n if (!against) {\n console.warn(`No against found in ${name}`);\n continue;\n }\n const [, source, selectText] = select.initializer.getText().split('.');\n selectors.push({\n name,\n nullable: against.initializer.getText().includes('nullable'),\n required: !against.initializer.getText().includes('optional'),\n select: selectText,\n against: against.initializer.getText(),\n source: source as SemanticSource,\n });\n }\n\n const contextVarName = handlerMiddleware.parameters[0].name.getText();\n const responsesList: ResponseItem[] = [];\n const visit = visitor((node, statusCode, headers, contentType) => {\n responsesList.push({\n headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],\n contentType,\n statusCode: statusCode ? resolveStatusCode(statusCode) : '200',\n response: deriver.serializeNode(node),\n });\n }, contextVarName);\n visit(handlerMiddleware.body);\n paths.addPath(operationName, path, method, selectors, responsesList);\n }\n });\n}\n\nfunction resolveStatusCode(node: ts.Node) {\n if (ts.isNumericLiteral(node)) {\n return node.text;\n }\n throw new Error(`Could not resolve status code`);\n}\n\nexport async function serialize(tsconfigPath: string) {\n logger(`Parsing tsconfig`);\n const program = getProgram(tsconfigPath);\n logger(`Program created`);\n const typeChecker = program.getTypeChecker();\n logger(`Type checker created`);\n const typeDeriver = new TypeDeriver(typeChecker);\n const paths = new Paths();\n analyze(\n program.getSourceFile(join(process.cwd(), 'apps/backend/src/main.ts'))!,\n typeDeriver,\n paths,\n );\n\n const components: ComponentsObject = {\n schemas: Object.entries(typeDeriver.collector).reduce(\n (acc, [key, value]) => ({ ...acc, [key]: toSchema(value) }),\n {},\n ),\n };\n\n return {\n paths: await paths.getPaths(),\n components,\n };\n}\n\nexport type Serialized = ReturnType<typeof serialize>;\n", "import ts, { TypeFlags } from 'typescript';\n\ntype Collector = Record<string, any>;\nexport const deriveSymbol = Symbol.for('serialize');\nexport const $types = Symbol.for('types');\n\nexport class TypeDeriver {\n public readonly collector: Collector = {};\n public readonly checker: ts.TypeChecker;\n constructor(checker: ts.TypeChecker) {\n this.checker = checker;\n }\n\n serializeType(type: ts.Type): any {\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n\n if (type.isIntersection()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'intersection',\n optional,\n [$types]: types,\n };\n }\n if (type.isUnion()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'union',\n optional,\n [$types]: types,\n };\n }\n if (this.checker.isArrayLikeType(type)) {\n const [argType] = this.checker.getTypeArguments(type as ts.TypeReference);\n if (!argType) {\n const typeName = type.symbol?.getName() || '<unknown>';\n console.warn(\n `Could not find generic type argument for array type ${typeName}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: ['any'],\n };\n }\n const typeSymbol = argType.getSymbol();\n if (!typeSymbol) {\n console.warn(\n `No symbol found for array type ${this.checker.typeToString(argType)}`,\n );\n const typeString = this.checker.typeToString(argType);\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: typeString === 'undefined' ? [] : [typeString],\n };\n }\n\n if (typeSymbol.valueDeclaration) {\n return {\n kind: 'array',\n ...this.serializeNode(typeSymbol.valueDeclaration),\n };\n }\n const maybeDeclaration = typeSymbol.declarations?.[0];\n if (maybeDeclaration) {\n if (ts.isMappedTypeNode(maybeDeclaration)) {\n const resolvedType = this.checker\n .getPropertiesOfType(argType)\n .reduce<Record<string, unknown>>((acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n }, {});\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: [resolvedType],\n };\n } else {\n return {\n kind: 'array',\n ...this.serializeNode(maybeDeclaration),\n };\n }\n }\n\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: ['any'],\n };\n }\n if (type.isClass()) {\n const declaration = type.symbol?.valueDeclaration;\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n if (isInterfaceType(type)) {\n const valueDeclaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!valueDeclaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(valueDeclaration);\n }\n if (type.flags & TypeFlags.Object) {\n const properties = this.checker.getPropertiesOfType(type);\n if (properties.length > 0) {\n const serializedProps = properties.reduce<Record<string, any>>(\n (acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n },\n {},\n );\n return {\n [deriveSymbol]: true,\n kind: 'object',\n optional: false,\n [$types]: [serializedProps],\n };\n }\n const declaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.checker.typeToString(\n type,\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n ),\n ],\n };\n }\n\n serializeNode(node: ts.Node): any {\n if (ts.isObjectLiteralExpression(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, any> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return props;\n }\n if (ts.isPropertyAccessExpression(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertySignature(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertyDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isInterfaceDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Interface has no name');\n }\n const defaults: Record<string, string> = {\n ReadableStream: 'ReadableStream',\n DateConstructor: 'Date',\n };\n if (defaults[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertySignature)) {\n members[member.name.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (ts.isClassDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Class has no name');\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertyDeclaration)) {\n members[member.name!.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [node.name.text],\n $ref: `#/components/schemas/${node.name.text}`,\n };\n }\n if (ts.isVariableDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n if (!node.type) {\n console.warn(`No type found for ${node.name.getText()}`);\n return 'any';\n }\n const type = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(type);\n }\n if (ts.isIdentifier(node)) {\n const symbol = this.checker.getSymbolAtLocation(node);\n if (!symbol) {\n console.warn(`Identifer: No symbol found for ${node.getText()}`);\n return null;\n }\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAwaitExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isCallExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAsExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTypeLiteralNode(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, unknown> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [props],\n };\n }\n\n if (node.kind === ts.SyntaxKind.NullKeyword) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\n };\n }\n console.warn(`Unhandled node: ${ts.SyntaxKind[node.kind]} ${node.flags}`);\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n}\n\nfunction isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}\n", "import debug from 'debug';\nimport { dirname, join } from 'node:path';\nimport ts from 'typescript';\n\n\n\n\n\nconst logger = debug('january:client');\n\nexport function parseTsConfig(tsconfigPath: string) {\n logger(`Using TypeScript version: ${ts.version}`);\n const configContent = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configContent.error) {\n console.error(\n `Failed to read tsconfig file:`,\n ts.formatDiagnosticsWithColorAndContext([configContent.error], {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n configContent.config,\n ts.sys,\n dirname(tsconfigPath),\n );\n\n if (parsed.errors.length > 0) {\n console.error(\n `Errors found in tsconfig.json:`,\n ts.formatDiagnosticsWithColorAndContext(parsed.errors, {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n return parsed;\n}\nexport function getProgram(tsconfigPath: string) {\n const tsConfigParseResult = parseTsConfig(tsconfigPath);\n logger(`Parsing tsconfig`);\n return ts.createProgram({\n options: {\n ...tsConfigParseResult.options,\n noEmit: true,\n incremental: true,\n tsBuildInfoFile: join(dirname(tsconfigPath), './.tsbuildinfo'), // not working atm\n },\n rootNames: tsConfigParseResult.fileNames,\n projectReferences: tsConfigParseResult.projectReferences,\n configFileParsingDiagnostics: tsConfigParseResult.errors,\n });\n}\nexport function getPropertyAssignment(node: ts.Node, name: string) {\n if (ts.isObjectLiteralExpression(node)) {\n return node.properties\n .filter((prop) => ts.isPropertyAssignment(prop))\n .find((prop) => prop.name!.getText() === name);\n }\n return undefined;\n}\nexport function isCallExpression(\n node: ts.Node,\n name: string,\n): node is ts.CallExpression {\n return (\n ts.isCallExpression(node) &&\n node.expression &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === name\n );\n}\n\nexport function isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}", "import type {\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from '@sdk-it/core';\n\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n select: string;\n against: string;\n source: SemanticSource;\n nullable: boolean;\n required: boolean;\n}\nexport type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';\n\nexport interface ResponseItem {\n statusCode: string;\n response: DateType;\n contentType: string;\n headers: string[];\n}\n\nexport class Paths {\n private operations: Array<{\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n }> = [];\n\n addPath(\n name: string,\n path: string,\n method: Method,\n selectors: Selector[],\n responses: ResponseItem[],\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n this.operations.push({\n name,\n path,\n method,\n selectors,\n responses: responsesObject,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = toSchema(item.response);\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content: {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n },\n headers: item.headers.length\n ? item.headers.reduce(\n (acc, header) => ({\n ...acc,\n [header]: { schema: { type: 'string' } },\n }),\n {},\n )\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<string, SchemaObject> = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = await evalZod(selector.against);\n continue;\n }\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: selector.required,\n schema: await evalZod(selector.against),\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n for (const operation of this.operations) {\n const { name, path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const operationObject: OperationObject = {\n operationId: name,\n parameters,\n requestBody: Object.keys(bodySchemaProps).length\n ? {\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: bodySchemaProps,\n },\n },\n },\n }\n : undefined,\n responses: operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n }\n return operations;\n }\n}\n\nasync function evalZod(schema: string) {\n const lines = [\n `import { z } from 'zod';`,\n `import { zodToJsonSchema } from 'zod-to-json-schema';`,\n `const schema = ${schema.replace('.optional()', '')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n\t\t\t$refStrategy: 'root',\n\t\t\tbasePath: ['#', 'components', 'schemas']\n\t\t});`,\n `export default jsonSchema;`,\n ];\n const base64Code = Buffer.from(lines.join('\\n')).toString('base64');\n const dataUrl = `data:text/javascript;base64,${base64Code}`;\n return import(dataUrl)\n .then((mod) => mod.default)\n .then(({ $schema, ...result }) => result);\n}\n\nconst typeMappings: Record<string, string> = {\n DateConstructor: 'Date',\n};\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return {\n type: `${typeMappings[data] || data}`,\n };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { oneOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n }\n return {\n type: 'object',\n properties: props,\n additionalProperties: false,\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["debug", "join", "ts", "ts", "ts", "logger", "debug", "ts", "prop", "node", "join"]
3
+ "sources": ["../src/lib/response-analyzer.ts"],
4
+ "sourcesContent": ["import debug from 'debug';\nimport ts from 'typescript';\n\nimport type { ResponseItem, TypeDeriver } from '@sdk-it/core';\n\nconst logger = debug('@sdk-it/hono');\n\nconst handlerVisitor: (\n on: (\n node: ts.Node,\n statusCode: ts.Node | undefined,\n headers: ts.Node | undefined,\n contentType: string,\n ) => void,\n contextVarName: string,\n) => ts.Visitor = (callback, contextVarName) => {\n return (node: ts.Node) => {\n if (ts.isReturnStatement(node) && node.expression) {\n if (\n ts.isCallExpression(node.expression) &&\n ts.isPropertyAccessExpression(node.expression.expression)\n ) {\n const propAccess = node.expression.expression;\n if (\n ts.isIdentifier(propAccess.expression) &&\n propAccess.expression.text === contextVarName\n ) {\n let contentType = 'application/json';\n const callerMethod = propAccess.name.text;\n if (callerMethod === 'body') {\n contentType = 'application/octet-stream';\n }\n const [body, statusCode, headers] = node.expression.arguments;\n callback(body, statusCode, headers, contentType);\n }\n }\n }\n return ts.forEachChild(node, handlerVisitor(callback, contextVarName));\n };\n};\n\nfunction toResponses(handler: ts.ArrowFunction, deriver: TypeDeriver) {\n const contextVarName = handler.parameters[0].name.getText();\n const responsesList: ResponseItem[] = [];\n const visit = handlerVisitor((node, statusCode, headers, contentType) => {\n responsesList.push({\n headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],\n contentType,\n statusCode: statusCode ? resolveStatusCode(statusCode) : '200',\n response: deriver.serializeNode(node),\n });\n }, contextVarName);\n visit(handler.body);\n return responsesList;\n}\n\nfunction resolveStatusCode(node: ts.Node) {\n if (ts.isNumericLiteral(node)) {\n return node.text;\n }\n throw new Error(`Could not resolve status code`);\n}\n\nexport function responseAnalyzer(\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) {\n return toResponses(handler, deriver);\n}\n"],
5
+ "mappings": ";AAAA,OAAO,WAAW;AAClB,OAAO,QAAQ;AAIf,IAAM,SAAS,MAAM,cAAc;AAEnC,IAAM,iBAQY,CAAC,UAAU,mBAAmB;AAC9C,SAAO,CAAC,SAAkB;AACxB,QAAI,GAAG,kBAAkB,IAAI,KAAK,KAAK,YAAY;AACjD,UACE,GAAG,iBAAiB,KAAK,UAAU,KACnC,GAAG,2BAA2B,KAAK,WAAW,UAAU,GACxD;AACA,cAAM,aAAa,KAAK,WAAW;AACnC,YACE,GAAG,aAAa,WAAW,UAAU,KACrC,WAAW,WAAW,SAAS,gBAC/B;AACA,cAAI,cAAc;AAClB,gBAAM,eAAe,WAAW,KAAK;AACrC,cAAI,iBAAiB,QAAQ;AAC3B,0BAAc;AAAA,UAChB;AACA,gBAAM,CAAC,MAAM,YAAY,OAAO,IAAI,KAAK,WAAW;AACpD,mBAAS,MAAM,YAAY,SAAS,WAAW;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAO,GAAG,aAAa,MAAM,eAAe,UAAU,cAAc,CAAC;AAAA,EACvE;AACF;AAEA,SAAS,YAAY,SAA2B,SAAsB;AACpE,QAAM,iBAAiB,QAAQ,WAAW,CAAC,EAAE,KAAK,QAAQ;AAC1D,QAAM,gBAAgC,CAAC;AACvC,QAAM,QAAQ,eAAe,CAAC,MAAM,YAAY,SAAS,gBAAgB;AACvE,kBAAc,KAAK;AAAA,MACjB,SAAS,UAAU,OAAO,KAAK,QAAQ,cAAc,OAAO,CAAC,IAAI,CAAC;AAAA,MAClE;AAAA,MACA,YAAY,aAAa,kBAAkB,UAAU,IAAI;AAAA,MACzD,UAAU,QAAQ,cAAc,IAAI;AAAA,IACtC,CAAC;AAAA,EACH,GAAG,cAAc;AACjB,QAAM,QAAQ,IAAI;AAClB,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAe;AACxC,MAAI,GAAG,iBAAiB,IAAI,GAAG;AAC7B,WAAO,KAAK;AAAA,EACd;AACA,QAAM,IAAI,MAAM,+BAA+B;AACjD;AAEO,SAAS,iBACd,SACA,SACA;AACA,SAAO,YAAY,SAAS,OAAO;AACrC;",
6
+ "names": []
7
7
  }
@@ -1,7 +1,2 @@
1
- import type { ComponentsObject } from 'openapi3-ts/oas31';
2
- export declare function serialize(tsconfigPath: string): Promise<{
3
- paths: import("openapi3-ts/oas31").PathsObject;
4
- components: ComponentsObject;
5
- }>;
6
- export type Serialized = ReturnType<typeof serialize>;
1
+ export {};
7
2
  //# sourceMappingURL=hono.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/lib/hono.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAsK1D,wBAAsB,SAAS,CAAC,YAAY,EAAE,MAAM;;;GAyBnD;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../src/lib/hono.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import ts from 'typescript';
2
+ import type { ResponseItem, TypeDeriver } from '@sdk-it/core';
3
+ export declare function responseAnalyzer(handler: ts.ArrowFunction, deriver: TypeDeriver): ResponseItem[];
4
+ //# sourceMappingURL=response-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-analyzer.d.ts","sourceRoot":"","sources":["../../src/lib/response-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AA4D9D,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,EAAE,CAAC,aAAa,EACzB,OAAO,EAAE,WAAW,kBAGrB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/hono",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -21,11 +21,11 @@
21
21
  "!**/*.tsbuildinfo"
22
22
  ],
23
23
  "dependencies": {
24
- "@sdk-it/core": "0.1.1",
24
+ "@sdk-it/core": "0.2.0",
25
25
  "debug": "^4.4.0",
26
26
  "openapi3-ts": "^4.4.0",
27
27
  "stringcase": "^4.3.1",
28
- "typescript": "~5.7.2"
28
+ "typescript": "^5.7.2"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/debug": "^4.1.12"