@gandalan/weblibs 1.5.23 → 1.5.25
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/index.d.ts +3189 -256
- package/package.json +1 -1
- package/scripts/generate-root-dto-typedefs.mjs +865 -54
|
@@ -26,6 +26,7 @@ const businessRootMarkerStart = "// BEGIN GENERATED ROOT BUSINESS TYPEDEFS";
|
|
|
26
26
|
const businessRootMarkerEnd = "// END GENERATED ROOT BUSINESS TYPEDEFS";
|
|
27
27
|
|
|
28
28
|
const simpleImportTypePattern = /^import\((?:"|').+(?:"|')\)\.[A-Za-z0-9_$]+$/;
|
|
29
|
+
const returnTypeOfCreateApiPattern = /^ReturnType<\s*typeof\s+(create[A-Za-z0-9_$]+Api)\s*>$/;
|
|
29
30
|
|
|
30
31
|
const rawType = (js, ts = js) => ({ kind: "raw", js, ts });
|
|
31
32
|
const refType = (name) => rawType(name);
|
|
@@ -356,6 +357,711 @@ function normalizeJSDocBlock(block) {
|
|
|
356
357
|
.trim();
|
|
357
358
|
}
|
|
358
359
|
|
|
360
|
+
function skipQuotedString(source, startIndex, quoteCharacter) {
|
|
361
|
+
let index = startIndex + 1;
|
|
362
|
+
|
|
363
|
+
while (index < source.length) {
|
|
364
|
+
const character = source[index];
|
|
365
|
+
|
|
366
|
+
if (character === "\\") {
|
|
367
|
+
index += 2;
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
if (character === quoteCharacter) {
|
|
372
|
+
return index + 1;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
index += 1;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return source.length;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function skipBlockComment(source, startIndex) {
|
|
382
|
+
const endIndex = source.indexOf("*/", startIndex + 2);
|
|
383
|
+
return endIndex === -1 ? source.length : endIndex + 2;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function skipLineComment(source, startIndex) {
|
|
387
|
+
const endIndex = source.indexOf("\n", startIndex + 2);
|
|
388
|
+
return endIndex === -1 ? source.length : endIndex + 1;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function findMatchingDelimiter(source, startIndex, openCharacter, closeCharacter) {
|
|
392
|
+
let depth = 1;
|
|
393
|
+
|
|
394
|
+
for (let index = startIndex + 1; index < source.length; index += 1) {
|
|
395
|
+
const character = source[index];
|
|
396
|
+
const nextCharacter = source[index + 1];
|
|
397
|
+
|
|
398
|
+
if (character === "\"" || character === "'") {
|
|
399
|
+
index = skipQuotedString(source, index, character) - 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (character === "`") {
|
|
404
|
+
index = skipTemplateLiteral(source, index) - 1;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (character === "/" && nextCharacter === "*") {
|
|
409
|
+
index = skipBlockComment(source, index) - 1;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (character === "/" && nextCharacter === "/") {
|
|
414
|
+
index = skipLineComment(source, index) - 1;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (character === openCharacter) {
|
|
419
|
+
depth += 1;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (character === closeCharacter) {
|
|
424
|
+
depth -= 1;
|
|
425
|
+
|
|
426
|
+
if (depth === 0) {
|
|
427
|
+
return index;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return -1;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
function skipTemplateLiteral(source, startIndex) {
|
|
436
|
+
let index = startIndex + 1;
|
|
437
|
+
|
|
438
|
+
while (index < source.length) {
|
|
439
|
+
const character = source[index];
|
|
440
|
+
|
|
441
|
+
if (character === "\\") {
|
|
442
|
+
index += 2;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
if (character === "`") {
|
|
447
|
+
return index + 1;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (character === "$" && source[index + 1] === "{") {
|
|
451
|
+
const closingIndex = findMatchingDelimiter(source, index + 1, "{", "}");
|
|
452
|
+
|
|
453
|
+
if (closingIndex === -1) {
|
|
454
|
+
return source.length;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
index = closingIndex + 1;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
index += 1;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
return source.length;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function skipWhitespace(value, startIndex) {
|
|
468
|
+
let index = startIndex;
|
|
469
|
+
|
|
470
|
+
while (index < value.length && /\s/u.test(value[index])) {
|
|
471
|
+
index += 1;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return index;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function skipWhitespaceAndComments(source, startIndex) {
|
|
478
|
+
let index = startIndex;
|
|
479
|
+
|
|
480
|
+
while (index < source.length) {
|
|
481
|
+
index = skipWhitespace(source, index);
|
|
482
|
+
|
|
483
|
+
if (source.startsWith("/**", index) || source.startsWith("/*", index)) {
|
|
484
|
+
index = skipBlockComment(source, index);
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (source.startsWith("//", index)) {
|
|
489
|
+
index = skipLineComment(source, index);
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return index;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function isIdentifierStart(character) {
|
|
500
|
+
return /[A-Za-z_$]/u.test(character);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function isIdentifierPart(character) {
|
|
504
|
+
return /[A-Za-z0-9_$]/u.test(character);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function buildFunctionTypeExpressionFromJSDoc(block) {
|
|
508
|
+
const normalizedBlock = normalizeJSDocBlock(block);
|
|
509
|
+
const params = extractParamEntries(normalizedBlock);
|
|
510
|
+
const returns = extractReturnsEntry(normalizedBlock)?.typeExpression ?? "void";
|
|
511
|
+
|
|
512
|
+
return `(${params.map((param) => `${param.name}${param.optional ? "?" : ""}: ${param.typeExpression}`).join(", ")}) => ${returns}`;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function buildObjectLiteralTypeExpression(properties) {
|
|
516
|
+
return `{ ${properties.map((property) => `${property.name}${property.optional ? "?" : ""}: ${property.typeExpression}`).join("; ")} }`;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function parseFunctionParameterTypes(jsDocBlock) {
|
|
520
|
+
if (!jsDocBlock) {
|
|
521
|
+
return new Map();
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const normalizedBlock = normalizeJSDocBlock(jsDocBlock);
|
|
525
|
+
const params = extractParamEntries(normalizedBlock);
|
|
526
|
+
|
|
527
|
+
return new Map(params.map((param) => [param.name, param.typeExpression]));
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function readLeadingJSDoc(source, startIndex) {
|
|
531
|
+
let index = startIndex;
|
|
532
|
+
let jsDocBlock = null;
|
|
533
|
+
|
|
534
|
+
while (index < source.length) {
|
|
535
|
+
index = skipWhitespace(source, index);
|
|
536
|
+
|
|
537
|
+
if (source.startsWith("/**", index)) {
|
|
538
|
+
const endIndex = skipBlockComment(source, index);
|
|
539
|
+
jsDocBlock = source.slice(index, endIndex);
|
|
540
|
+
index = endIndex;
|
|
541
|
+
continue;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (source.startsWith("/*", index)) {
|
|
545
|
+
index = skipBlockComment(source, index);
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (source.startsWith("//", index)) {
|
|
550
|
+
index = skipLineComment(source, index);
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
jsDocBlock,
|
|
559
|
+
nextIndex: index
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function findExpressionEnd(source, startIndex) {
|
|
564
|
+
let braceDepth = 0;
|
|
565
|
+
let bracketDepth = 0;
|
|
566
|
+
let parenDepth = 0;
|
|
567
|
+
|
|
568
|
+
for (let index = startIndex; index < source.length; index += 1) {
|
|
569
|
+
const character = source[index];
|
|
570
|
+
const nextCharacter = source[index + 1];
|
|
571
|
+
|
|
572
|
+
if (character === "\"" || character === "'") {
|
|
573
|
+
index = skipQuotedString(source, index, character) - 1;
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
if (character === "`") {
|
|
578
|
+
index = skipTemplateLiteral(source, index) - 1;
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
if (character === "/" && nextCharacter === "*") {
|
|
583
|
+
index = skipBlockComment(source, index) - 1;
|
|
584
|
+
continue;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if (character === "/" && nextCharacter === "/") {
|
|
588
|
+
index = skipLineComment(source, index) - 1;
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (character === "{") {
|
|
593
|
+
braceDepth += 1;
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (character === "}") {
|
|
598
|
+
if (braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
599
|
+
return index;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
if (character === "[") {
|
|
607
|
+
bracketDepth += 1;
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (character === "]") {
|
|
612
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (character === "(") {
|
|
617
|
+
parenDepth += 1;
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (character === ")") {
|
|
622
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (character === "," && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
627
|
+
return index;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return source.length;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function inferTypeExpressionFromInitializer(initializerSource, scopeTypeMap) {
|
|
635
|
+
const trimmedInitializer = initializerSource.trim();
|
|
636
|
+
|
|
637
|
+
if (!trimmedInitializer) {
|
|
638
|
+
return "any";
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (scopeTypeMap.has(trimmedInitializer)) {
|
|
642
|
+
return scopeTypeMap.get(trimmedInitializer);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (trimmedInitializer === "null") {
|
|
646
|
+
return "null";
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (trimmedInitializer === "true" || trimmedInitializer === "false") {
|
|
650
|
+
return "boolean";
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (/^[-+]?\d+(?:\.\d+)?$/u.test(trimmedInitializer)) {
|
|
654
|
+
return "number";
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if ((trimmedInitializer.startsWith("\"") && trimmedInitializer.endsWith("\"")) || (trimmedInitializer.startsWith("'") && trimmedInitializer.endsWith("'"))) {
|
|
658
|
+
return "string";
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
return "any";
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function parseObjectLiteralProperties(objectSource, scopeTypeMap) {
|
|
665
|
+
if (!objectSource.startsWith("{")) {
|
|
666
|
+
throw new Error("Expected object literal source to start with '{'.");
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
const properties = [];
|
|
670
|
+
let index = 1;
|
|
671
|
+
|
|
672
|
+
while (index < objectSource.length) {
|
|
673
|
+
const { jsDocBlock, nextIndex } = readLeadingJSDoc(objectSource, index);
|
|
674
|
+
index = nextIndex;
|
|
675
|
+
|
|
676
|
+
if (objectSource[index] === "}") {
|
|
677
|
+
break;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
let propertyName = null;
|
|
681
|
+
|
|
682
|
+
if (objectSource.startsWith("async", index) && !isIdentifierPart(objectSource[index + 5] ?? "")) {
|
|
683
|
+
index = skipWhitespace(objectSource, index + 5);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (objectSource[index] === "\"" || objectSource[index] === "'") {
|
|
687
|
+
const quoteCharacter = objectSource[index];
|
|
688
|
+
const endIndex = skipQuotedString(objectSource, index, quoteCharacter);
|
|
689
|
+
propertyName = objectSource.slice(index + 1, endIndex - 1);
|
|
690
|
+
index = endIndex;
|
|
691
|
+
} else if (isIdentifierStart(objectSource[index] ?? "")) {
|
|
692
|
+
const nameStart = index;
|
|
693
|
+
index += 1;
|
|
694
|
+
|
|
695
|
+
while (index < objectSource.length && isIdentifierPart(objectSource[index])) {
|
|
696
|
+
index += 1;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
propertyName = objectSource.slice(nameStart, index);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
if (!propertyName) {
|
|
703
|
+
index += 1;
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
index = skipWhitespaceAndComments(objectSource, index);
|
|
708
|
+
|
|
709
|
+
let typeExpression = "any";
|
|
710
|
+
let optional = false;
|
|
711
|
+
|
|
712
|
+
if (objectSource[index] === ":") {
|
|
713
|
+
index = skipWhitespaceAndComments(objectSource, index + 1);
|
|
714
|
+
|
|
715
|
+
if (objectSource[index] === "{") {
|
|
716
|
+
const objectEndIndex = findMatchingDelimiter(objectSource, index, "{", "}");
|
|
717
|
+
|
|
718
|
+
if (objectEndIndex === -1) {
|
|
719
|
+
throw new Error(`Could not find end of nested object literal for property ${propertyName}`);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const nestedProperties = parseObjectLiteralProperties(objectSource.slice(index, objectEndIndex + 1), scopeTypeMap);
|
|
723
|
+
typeExpression = buildObjectLiteralTypeExpression(nestedProperties);
|
|
724
|
+
index = objectEndIndex + 1;
|
|
725
|
+
} else {
|
|
726
|
+
const expressionEndIndex = findExpressionEnd(objectSource, index);
|
|
727
|
+
const initializerSource = objectSource.slice(index, expressionEndIndex);
|
|
728
|
+
typeExpression = jsDocBlock ? buildFunctionTypeExpressionFromJSDoc(jsDocBlock) : inferTypeExpressionFromInitializer(initializerSource, scopeTypeMap);
|
|
729
|
+
index = expressionEndIndex;
|
|
730
|
+
}
|
|
731
|
+
} else if (objectSource[index] === "(") {
|
|
732
|
+
const paramsEndIndex = findMatchingDelimiter(objectSource, index, "(", ")");
|
|
733
|
+
|
|
734
|
+
if (paramsEndIndex === -1) {
|
|
735
|
+
throw new Error(`Could not find end of parameter list for property ${propertyName}`);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
index = skipWhitespaceAndComments(objectSource, paramsEndIndex + 1);
|
|
739
|
+
|
|
740
|
+
if (objectSource[index] === "{") {
|
|
741
|
+
const methodEndIndex = findMatchingDelimiter(objectSource, index, "{", "}");
|
|
742
|
+
|
|
743
|
+
if (methodEndIndex === -1) {
|
|
744
|
+
throw new Error(`Could not find end of method body for property ${propertyName}`);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
index = methodEndIndex + 1;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
typeExpression = jsDocBlock ? buildFunctionTypeExpressionFromJSDoc(jsDocBlock) : "(...args: any[]) => any";
|
|
751
|
+
} else {
|
|
752
|
+
typeExpression = scopeTypeMap.get(propertyName) ?? "any";
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
properties.push({
|
|
756
|
+
name: propertyName,
|
|
757
|
+
optional,
|
|
758
|
+
typeExpression
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
index = skipWhitespaceAndComments(objectSource, index);
|
|
762
|
+
|
|
763
|
+
if (objectSource[index] === ",") {
|
|
764
|
+
index += 1;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
return properties;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
function getNearestLeadingJSDoc(source, startIndex) {
|
|
772
|
+
let cursor = startIndex;
|
|
773
|
+
|
|
774
|
+
while (cursor > 0 && /\s/u.test(source[cursor - 1])) {
|
|
775
|
+
cursor -= 1;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
if (!source.startsWith("*/", cursor - 2)) {
|
|
779
|
+
return null;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const blockStartIndex = source.lastIndexOf("/**", cursor - 2);
|
|
783
|
+
return blockStartIndex === -1 ? null : source.slice(blockStartIndex, cursor);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
function extractCreateFunctionInfo(source, createFunctionName) {
|
|
787
|
+
const functionPattern = new RegExp(`export\\s+(?:async\\s+)?function\\s+${createFunctionName}\\s*\\(`);
|
|
788
|
+
const functionMatch = functionPattern.exec(source);
|
|
789
|
+
|
|
790
|
+
if (functionMatch) {
|
|
791
|
+
const functionIndex = functionMatch.index;
|
|
792
|
+
const functionBodyStartIndex = source.indexOf("{", functionIndex);
|
|
793
|
+
const functionBodyEndIndex = functionBodyStartIndex === -1 ? -1 : findMatchingDelimiter(source, functionBodyStartIndex, "{", "}");
|
|
794
|
+
|
|
795
|
+
if (functionBodyStartIndex === -1 || functionBodyEndIndex === -1) {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
return {
|
|
800
|
+
jsDocBlock: getNearestLeadingJSDoc(source, functionIndex),
|
|
801
|
+
bodySource: source.slice(functionBodyStartIndex + 1, functionBodyEndIndex)
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
const constPattern = new RegExp(`export\\s+const\\s+${createFunctionName}\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*=>\\s*\\{`);
|
|
806
|
+
const constMatch = constPattern.exec(source);
|
|
807
|
+
|
|
808
|
+
if (!constMatch) {
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
const arrowBodyStartIndex = source.indexOf("{", constMatch.index);
|
|
813
|
+
const arrowBodyEndIndex = arrowBodyStartIndex === -1 ? -1 : findMatchingDelimiter(source, arrowBodyStartIndex, "{", "}");
|
|
814
|
+
|
|
815
|
+
if (arrowBodyStartIndex === -1 || arrowBodyEndIndex === -1) {
|
|
816
|
+
return null;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
return {
|
|
820
|
+
jsDocBlock: getNearestLeadingJSDoc(source, constMatch.index),
|
|
821
|
+
bodySource: source.slice(arrowBodyStartIndex + 1, arrowBodyEndIndex)
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
function extractTopLevelReturnedObjectSource(functionBodySource, createFunctionName) {
|
|
826
|
+
let braceDepth = 0;
|
|
827
|
+
let bracketDepth = 0;
|
|
828
|
+
let parenDepth = 0;
|
|
829
|
+
|
|
830
|
+
for (let index = 0; index < functionBodySource.length; index += 1) {
|
|
831
|
+
const character = functionBodySource[index];
|
|
832
|
+
const nextCharacter = functionBodySource[index + 1];
|
|
833
|
+
|
|
834
|
+
if (character === "\"" || character === "'") {
|
|
835
|
+
index = skipQuotedString(functionBodySource, index, character) - 1;
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (character === "`") {
|
|
840
|
+
index = skipTemplateLiteral(functionBodySource, index) - 1;
|
|
841
|
+
continue;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
if (character === "/" && nextCharacter === "*") {
|
|
845
|
+
index = skipBlockComment(functionBodySource, index) - 1;
|
|
846
|
+
continue;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (character === "/" && nextCharacter === "/") {
|
|
850
|
+
index = skipLineComment(functionBodySource, index) - 1;
|
|
851
|
+
continue;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (character === "{") {
|
|
855
|
+
braceDepth += 1;
|
|
856
|
+
continue;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
if (character === "}") {
|
|
860
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (character === "[") {
|
|
865
|
+
bracketDepth += 1;
|
|
866
|
+
continue;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (character === "]") {
|
|
870
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
if (character === "(") {
|
|
875
|
+
parenDepth += 1;
|
|
876
|
+
continue;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
if (character === ")") {
|
|
880
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
if (braceDepth === 0 && bracketDepth === 0 && parenDepth === 0 && functionBodySource.startsWith("return", index) && !isIdentifierPart(functionBodySource[index - 1] ?? "") && !isIdentifierPart(functionBodySource[index + 6] ?? "")) {
|
|
885
|
+
const objectStartIndex = skipWhitespaceAndComments(functionBodySource, index + 6);
|
|
886
|
+
|
|
887
|
+
if (functionBodySource[objectStartIndex] !== "{") {
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
const objectEndIndex = findMatchingDelimiter(functionBodySource, objectStartIndex, "{", "}");
|
|
892
|
+
|
|
893
|
+
if (objectEndIndex === -1) {
|
|
894
|
+
throw new Error(`Could not find end of returned object literal for ${createFunctionName}`);
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
return functionBodySource.slice(objectStartIndex, objectEndIndex + 1);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
throw new Error(`Could not find top-level returned object literal for ${createFunctionName}`);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
function inferReturnTypeObjectEntry(source, filePath, typeName, createFunctionName) {
|
|
905
|
+
const functionInfo = extractCreateFunctionInfo(source, createFunctionName);
|
|
906
|
+
|
|
907
|
+
if (!functionInfo) {
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
const returnedObjectSource = extractTopLevelReturnedObjectSource(functionInfo.bodySource, createFunctionName);
|
|
912
|
+
const scopeTypeMap = parseFunctionParameterTypes(functionInfo.jsDocBlock);
|
|
913
|
+
const properties = parseObjectLiteralProperties(returnedObjectSource, scopeTypeMap);
|
|
914
|
+
|
|
915
|
+
return {
|
|
916
|
+
kind: "object",
|
|
917
|
+
name: typeName,
|
|
918
|
+
properties,
|
|
919
|
+
filePath
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function parseBracketedType(rest) {
|
|
924
|
+
if (!rest.startsWith("{")) {
|
|
925
|
+
return null;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
let braceDepth = 0;
|
|
929
|
+
let closingBraceIndex = -1;
|
|
930
|
+
|
|
931
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
932
|
+
const character = rest[index];
|
|
933
|
+
|
|
934
|
+
if (character === "{") {
|
|
935
|
+
braceDepth += 1;
|
|
936
|
+
} else if (character === "}") {
|
|
937
|
+
braceDepth -= 1;
|
|
938
|
+
|
|
939
|
+
if (braceDepth === 0) {
|
|
940
|
+
closingBraceIndex = index;
|
|
941
|
+
break;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
if (closingBraceIndex === -1) {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return {
|
|
951
|
+
typeExpression: rest.slice(1, closingBraceIndex).trim(),
|
|
952
|
+
remainder: rest.slice(closingBraceIndex + 1).trim()
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
function parseTagWithType(line, tagName) {
|
|
957
|
+
const marker = `@${tagName}`;
|
|
958
|
+
const tagIndex = line.indexOf(marker);
|
|
959
|
+
|
|
960
|
+
if (tagIndex === -1) {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const parsed = parseBracketedType(line.slice(tagIndex + marker.length).trimStart());
|
|
965
|
+
|
|
966
|
+
if (!parsed) {
|
|
967
|
+
return null;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return parsed;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
function parseNameToken(remainder) {
|
|
974
|
+
const nameMatch = remainder.match(/^(\[[^\]]+\]|[^\s-]+)/);
|
|
975
|
+
|
|
976
|
+
if (!nameMatch) {
|
|
977
|
+
return null;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const rawName = nameMatch[1];
|
|
981
|
+
const optional = rawName.startsWith("[") && rawName.endsWith("]");
|
|
982
|
+
const normalizedName = optional ? rawName.slice(1, -1).replace(/=.*/, "") : rawName;
|
|
983
|
+
const description = remainder.slice(nameMatch[0].length).trim().replace(/^-/u, "").trim();
|
|
984
|
+
|
|
985
|
+
return {
|
|
986
|
+
name: normalizedName,
|
|
987
|
+
optional,
|
|
988
|
+
description
|
|
989
|
+
};
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
function extractPropertyEntries(normalizedBlock) {
|
|
993
|
+
const properties = [];
|
|
994
|
+
|
|
995
|
+
for (const line of normalizedBlock.split("\n")) {
|
|
996
|
+
if (!line.includes("@property")) {
|
|
997
|
+
continue;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
const parsedTag = parseTagWithType(line, "property");
|
|
1001
|
+
|
|
1002
|
+
if (!parsedTag) {
|
|
1003
|
+
continue;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const parsedName = parseNameToken(parsedTag.remainder);
|
|
1007
|
+
|
|
1008
|
+
if (!parsedName) {
|
|
1009
|
+
continue;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
properties.push({
|
|
1013
|
+
name: parsedName.name,
|
|
1014
|
+
optional: parsedName.optional,
|
|
1015
|
+
description: parsedName.description,
|
|
1016
|
+
typeExpression: parsedTag.typeExpression
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
return properties;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
function extractParamEntries(normalizedBlock) {
|
|
1024
|
+
const params = [];
|
|
1025
|
+
|
|
1026
|
+
for (const line of normalizedBlock.split("\n")) {
|
|
1027
|
+
if (!line.includes("@param")) {
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
const parsedTag = parseTagWithType(line, "param");
|
|
1032
|
+
|
|
1033
|
+
if (!parsedTag) {
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
const parsedName = parseNameToken(parsedTag.remainder);
|
|
1038
|
+
|
|
1039
|
+
if (!parsedName) {
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
params.push({
|
|
1044
|
+
name: parsedName.name,
|
|
1045
|
+
optional: parsedName.optional,
|
|
1046
|
+
typeExpression: parsedTag.typeExpression
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
return params;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
function extractReturnsEntry(normalizedBlock) {
|
|
1054
|
+
for (const line of normalizedBlock.split("\n")) {
|
|
1055
|
+
if (!line.includes("@returns") && !line.includes("@return")) {
|
|
1056
|
+
continue;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
return parseTagWithType(line, line.includes("@returns") ? "returns" : "return");
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
359
1065
|
function extractTypedefEntry(normalizedBlock) {
|
|
360
1066
|
const typedefIndex = normalizedBlock.indexOf("@typedef");
|
|
361
1067
|
|
|
@@ -399,10 +1105,13 @@ function extractTypedefEntry(normalizedBlock) {
|
|
|
399
1105
|
return null;
|
|
400
1106
|
}
|
|
401
1107
|
|
|
1108
|
+
const properties = extractPropertyEntries(normalizedBlock);
|
|
1109
|
+
|
|
402
1110
|
return {
|
|
403
|
-
kind: "typedef",
|
|
1111
|
+
kind: typeExpression === "Object" && properties.length > 0 ? "object" : "typedef",
|
|
404
1112
|
name: nameMatch[1],
|
|
405
|
-
typeExpression
|
|
1113
|
+
typeExpression,
|
|
1114
|
+
properties
|
|
406
1115
|
};
|
|
407
1116
|
}
|
|
408
1117
|
|
|
@@ -416,7 +1125,9 @@ function extractCallbackEntry(normalizedBlock) {
|
|
|
416
1125
|
return {
|
|
417
1126
|
kind: "callback",
|
|
418
1127
|
name: callbackMatch[1],
|
|
419
|
-
typeExpression: null
|
|
1128
|
+
typeExpression: null,
|
|
1129
|
+
params: extractParamEntries(normalizedBlock),
|
|
1130
|
+
returns: extractReturnsEntry(normalizedBlock)?.typeExpression ?? "void"
|
|
420
1131
|
};
|
|
421
1132
|
}
|
|
422
1133
|
|
|
@@ -431,6 +1142,17 @@ function extractPublicTypeEntries(source, filePath) {
|
|
|
431
1142
|
const typedefEntry = extractTypedefEntry(block);
|
|
432
1143
|
|
|
433
1144
|
if (typedefEntry) {
|
|
1145
|
+
const inferredCreateApiName = typedefEntry.typeExpression.match(returnTypeOfCreateApiPattern)?.[1] ?? null;
|
|
1146
|
+
|
|
1147
|
+
if (inferredCreateApiName) {
|
|
1148
|
+
const inferredObjectEntry = inferReturnTypeObjectEntry(source, filePath, typedefEntry.name, inferredCreateApiName);
|
|
1149
|
+
|
|
1150
|
+
if (inferredObjectEntry) {
|
|
1151
|
+
entries.push(inferredObjectEntry);
|
|
1152
|
+
continue;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
434
1156
|
if (!isSimpleImportAlias(typedefEntry.typeExpression)) {
|
|
435
1157
|
entries.push({ ...typedefEntry, filePath });
|
|
436
1158
|
}
|
|
@@ -448,6 +1170,135 @@ function extractPublicTypeEntries(source, filePath) {
|
|
|
448
1170
|
return entries;
|
|
449
1171
|
}
|
|
450
1172
|
|
|
1173
|
+
function splitTopLevel(text, delimiterCharacter) {
|
|
1174
|
+
const parts = [];
|
|
1175
|
+
let current = "";
|
|
1176
|
+
let angleDepth = 0;
|
|
1177
|
+
let braceDepth = 0;
|
|
1178
|
+
let bracketDepth = 0;
|
|
1179
|
+
let parenDepth = 0;
|
|
1180
|
+
|
|
1181
|
+
for (const character of text) {
|
|
1182
|
+
if (character === "<") {
|
|
1183
|
+
angleDepth += 1;
|
|
1184
|
+
} else if (character === ">") {
|
|
1185
|
+
angleDepth = Math.max(0, angleDepth - 1);
|
|
1186
|
+
} else if (character === "{") {
|
|
1187
|
+
braceDepth += 1;
|
|
1188
|
+
} else if (character === "}") {
|
|
1189
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
1190
|
+
} else if (character === "[") {
|
|
1191
|
+
bracketDepth += 1;
|
|
1192
|
+
} else if (character === "]") {
|
|
1193
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
1194
|
+
} else if (character === "(") {
|
|
1195
|
+
parenDepth += 1;
|
|
1196
|
+
} else if (character === ")") {
|
|
1197
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
if (character === delimiterCharacter && angleDepth === 0 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
1201
|
+
parts.push(current.trim());
|
|
1202
|
+
current = "";
|
|
1203
|
+
continue;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
current += character;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
if (current.trim()) {
|
|
1210
|
+
parts.push(current.trim());
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
return parts;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
function replaceObjectGenerics(typeExpression, transformTypeExpression) {
|
|
1217
|
+
let result = "";
|
|
1218
|
+
|
|
1219
|
+
for (let index = 0; index < typeExpression.length; index += 1) {
|
|
1220
|
+
if (!typeExpression.startsWith("Object<", index)) {
|
|
1221
|
+
result += typeExpression[index];
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
let angleDepth = 0;
|
|
1226
|
+
let closingIndex = -1;
|
|
1227
|
+
|
|
1228
|
+
for (let cursor = index + "Object".length; cursor < typeExpression.length; cursor += 1) {
|
|
1229
|
+
const character = typeExpression[cursor];
|
|
1230
|
+
|
|
1231
|
+
if (character === "<") {
|
|
1232
|
+
angleDepth += 1;
|
|
1233
|
+
} else if (character === ">") {
|
|
1234
|
+
angleDepth -= 1;
|
|
1235
|
+
|
|
1236
|
+
if (angleDepth === 0) {
|
|
1237
|
+
closingIndex = cursor;
|
|
1238
|
+
break;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
if (closingIndex === -1) {
|
|
1244
|
+
result += typeExpression[index];
|
|
1245
|
+
continue;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
const genericContent = typeExpression.slice(index + "Object<".length, closingIndex);
|
|
1249
|
+
const genericParts = splitTopLevel(genericContent, ",");
|
|
1250
|
+
|
|
1251
|
+
if (genericParts.length === 2) {
|
|
1252
|
+
result += `Record<${transformTypeExpression(genericParts[0])}, ${transformTypeExpression(genericParts[1])}>`;
|
|
1253
|
+
} else {
|
|
1254
|
+
result += "object";
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
index = closingIndex;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
return result;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
function transformTypeExpressionForDts(typeExpression, availableTypeNames) {
|
|
1264
|
+
const normalizedExpression = typeExpression.trim();
|
|
1265
|
+
|
|
1266
|
+
if (normalizedExpression === "*") {
|
|
1267
|
+
return "any";
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
let transformedExpression = normalizedExpression.replace(
|
|
1271
|
+
/import\((?:"|')[^"']+(?:"|')\)\.([A-Za-z0-9_$]+)(\[[^\]]+\])?/g,
|
|
1272
|
+
(fullMatch, typeName, suffix = "") => availableTypeNames.has(typeName) ? `${typeName}${suffix}` : fullMatch
|
|
1273
|
+
);
|
|
1274
|
+
|
|
1275
|
+
transformedExpression = replaceObjectGenerics(transformedExpression, (innerExpression) => transformTypeExpressionForDts(innerExpression, availableTypeNames));
|
|
1276
|
+
transformedExpression = transformedExpression.replace(/\bObject\b/g, "object");
|
|
1277
|
+
transformedExpression = transformedExpression.replace(/\bfunction\b/g, "Function");
|
|
1278
|
+
|
|
1279
|
+
return transformedExpression;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
function renderTypeEntryAsDts(entry, availableTypeNames) {
|
|
1283
|
+
if (entry.kind === "object") {
|
|
1284
|
+
const lines = [`export type ${entry.name} = {`];
|
|
1285
|
+
|
|
1286
|
+
for (const property of entry.properties) {
|
|
1287
|
+
lines.push(` ${property.name}${property.optional ? "?" : ""}: ${transformTypeExpressionForDts(property.typeExpression, availableTypeNames)};`);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
lines.push("};", "");
|
|
1291
|
+
return lines;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
if (entry.kind === "callback") {
|
|
1295
|
+
const params = entry.params.map((param) => `${param.name}${param.optional ? "?" : ""}: ${transformTypeExpressionForDts(param.typeExpression, availableTypeNames)}`).join(", ");
|
|
1296
|
+
return [`export type ${entry.name} = (${params}) => ${transformTypeExpressionForDts(entry.returns, availableTypeNames)};`, ""];
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
return [`export type ${entry.name} = ${transformTypeExpressionForDts(entry.typeExpression, availableTypeNames)};`, ""];
|
|
1300
|
+
}
|
|
1301
|
+
|
|
451
1302
|
function buildTypeExportMap(typeEntries) {
|
|
452
1303
|
const exportMap = new Map();
|
|
453
1304
|
|
|
@@ -647,61 +1498,20 @@ function replaceGeneratedBlock(source, startMarker, endMarker, generatedBlock, t
|
|
|
647
1498
|
return `${before}${generatedBlock}${after}`;
|
|
648
1499
|
}
|
|
649
1500
|
|
|
650
|
-
function buildRootDts(
|
|
651
|
-
const dtoAliasNames = new Set(dtoAliases.map((alias) => alias.name));
|
|
1501
|
+
function buildRootDts(publicTypeEntries) {
|
|
652
1502
|
const lines = [
|
|
653
1503
|
"export * from \"./index.js\";",
|
|
654
1504
|
""
|
|
655
1505
|
];
|
|
656
1506
|
|
|
657
|
-
const
|
|
658
|
-
|
|
659
|
-
for (const directory of sourceDirectories) {
|
|
660
|
-
sourceFiles.push(...allJsFilesByDirectory.get(directory));
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
const discoveredTypeEntries = [];
|
|
664
|
-
|
|
665
|
-
for (const filePath of sourceFiles) {
|
|
666
|
-
const source = sourceByFilePath.get(filePath);
|
|
667
|
-
discoveredTypeEntries.push(...extractPublicTypeEntries(source, filePath));
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
const canonicalizedTypeEntries = discoveredTypeEntries.filter((entry) => {
|
|
671
|
-
const relativeFilePath = toPosixRelativePath(entry.filePath);
|
|
672
|
-
const isDtoLeafFile = relativeFilePath.startsWith("api/dtos/") && relativeFilePath !== "api/dtos/index.js";
|
|
673
|
-
|
|
674
|
-
if (isDtoLeafFile && dtoAliasNames.has(entry.name)) {
|
|
675
|
-
return false;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
return true;
|
|
679
|
-
});
|
|
680
|
-
|
|
681
|
-
const typeExportMap = buildTypeExportMap(canonicalizedTypeEntries);
|
|
1507
|
+
const typeExportMap = buildTypeExportMap(publicTypeEntries);
|
|
682
1508
|
const sortedEntries = [...typeExportMap.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
1509
|
+
const availableTypeNames = new Set(sortedEntries.map((entry) => entry.name));
|
|
683
1510
|
|
|
684
1511
|
for (const entry of sortedEntries) {
|
|
685
|
-
|
|
686
|
-
lines.push(`export type ${entry.name} = import("./api/dtos/index.js").${entry.name};`);
|
|
687
|
-
dtoAliasNames.delete(entry.name);
|
|
688
|
-
continue;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
const relativeImportPath = `./${toPosixRelativePath(entry.filePath)}`;
|
|
692
|
-
const dtsImportPath = toRelativeDtsImportPath(rootDtsPath, entry.filePath);
|
|
693
|
-
lines.push(`export type ${entry.name} = import("${dtsImportPath}").${entry.name};`);
|
|
1512
|
+
lines.push(...renderTypeEntryAsDts(entry, availableTypeNames));
|
|
694
1513
|
}
|
|
695
1514
|
|
|
696
|
-
for (const alias of dtoAliases) {
|
|
697
|
-
if (!dtoAliasNames.has(alias.name)) {
|
|
698
|
-
continue;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
lines.push(`export type ${alias.name} = import("./api/dtos/index.js").${alias.name};`);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
lines.push("");
|
|
705
1515
|
return `${lines.join("\n")}\n`;
|
|
706
1516
|
}
|
|
707
1517
|
|
|
@@ -725,6 +1535,12 @@ for (const filePath of [rootIndexPath, ...dtoLeafFiles, ...businessLeafFiles, ..
|
|
|
725
1535
|
const dtoEntries = buildTypeExportMap(dtoLeafFiles.flatMap((filePath) => extractPublicTypeEntries(sourceByFilePath.get(filePath), filePath)));
|
|
726
1536
|
const dtoAliases = buildDtoAliases(dtoEntries);
|
|
727
1537
|
const businessAliases = buildBusinessAliases(businessLeafFiles, sourceByFilePath);
|
|
1538
|
+
const publicTypeEntries = [
|
|
1539
|
+
...dtoLeafFiles.flatMap((filePath) => extractPublicTypeEntries(sourceByFilePath.get(filePath), filePath)),
|
|
1540
|
+
...businessLeafFiles.flatMap((filePath) => extractPublicTypeEntries(sourceByFilePath.get(filePath), filePath)),
|
|
1541
|
+
...otherApiJsFiles.flatMap((filePath) => extractPublicTypeEntries(sourceByFilePath.get(filePath), filePath)),
|
|
1542
|
+
...uiLeafFiles.filter((filePath) => path.extname(filePath) === ".js").flatMap((filePath) => extractPublicTypeEntries(sourceByFilePath.get(filePath), filePath))
|
|
1543
|
+
];
|
|
728
1544
|
|
|
729
1545
|
const generatedDtoIndexSource = buildDtoIndexSource(dtoAliases);
|
|
730
1546
|
const generatedBusinessIndexSource = buildBusinessIndexSource(businessAliases);
|
|
@@ -768,12 +1584,7 @@ const updatedRootIndexSource = replaceGeneratedBlock(rootIndexWithDtoAliases, bu
|
|
|
768
1584
|
await writeFile(rootIndexPath, updatedRootIndexSource);
|
|
769
1585
|
sourceByFilePath.set(rootIndexPath, updatedRootIndexSource);
|
|
770
1586
|
|
|
771
|
-
const
|
|
772
|
-
["api", [...dtoLeafFiles, ...businessLeafFiles, ...otherApiJsFiles].sort()],
|
|
773
|
-
["ui", uiLeafFiles.filter((filePath) => path.extname(filePath) === ".js").sort()]
|
|
774
|
-
]);
|
|
775
|
-
|
|
776
|
-
const generatedRootDts = buildRootDts(dtoAliases, sourceByFilePath, allJsFilesByDirectory);
|
|
1587
|
+
const generatedRootDts = buildRootDts(publicTypeEntries);
|
|
777
1588
|
await writeFile(rootDtsPath, generatedRootDts);
|
|
778
1589
|
|
|
779
1590
|
console.log(`Updated ${toPosixRelativePath(dtoIndexPath)} with ${dtoAliases.length} generated DTO aliases.`);
|