versioned-d.ts-tools 0.7.4 → 0.8.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/dts-utilities.d.ts +1 -0
- package/dist/dts-utilities.js +85 -16
- package/dist/whats-new.js +2 -1
- package/package.json +1 -1
package/dist/dts-utilities.d.ts
CHANGED
package/dist/dts-utilities.js
CHANGED
|
@@ -45,17 +45,43 @@ const ts = __importStar(require("typescript"));
|
|
|
45
45
|
// {suffix} - "-member(1)" for methods/functions, "-member" for properties
|
|
46
46
|
// Default link builder using templates
|
|
47
47
|
function buildLinkFromTemplate(template, relativePath, className, field) {
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
// Handle relativePath with or without a dot
|
|
49
|
+
const lastDotIndex = relativePath.lastIndexOf(".");
|
|
50
|
+
const basePath = lastDotIndex >= 0
|
|
51
|
+
? relativePath.substring(0, lastDotIndex)
|
|
52
|
+
: relativePath;
|
|
53
|
+
// Extract hostName - the part after /api/ (e.g., "outlook" from "javascript/api/outlook")
|
|
54
|
+
let hostName = "";
|
|
55
|
+
if (relativePath.includes("/api/")) {
|
|
56
|
+
const afterApi = relativePath.substring(relativePath.indexOf("/api/") + 5);
|
|
57
|
+
// If there's a slash after /api/, take up to that slash; otherwise take the whole thing or up to the dot
|
|
58
|
+
const nextSlashIndex = afterApi.indexOf("/");
|
|
59
|
+
if (nextSlashIndex >= 0) {
|
|
60
|
+
hostName = afterApi.substring(0, nextSlashIndex);
|
|
61
|
+
}
|
|
62
|
+
else if (lastDotIndex >= 0) {
|
|
63
|
+
hostName = afterApi.substring(0, afterApi.indexOf("."));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
hostName = afterApi;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const lastSlashIndex = relativePath.lastIndexOf("/");
|
|
70
|
+
const fileName = lastDotIndex >= 0
|
|
71
|
+
? relativePath.substring(lastSlashIndex + 1, lastDotIndex)
|
|
72
|
+
: relativePath.substring(lastSlashIndex + 1);
|
|
53
73
|
let result = template
|
|
54
74
|
.replace(/{basePath}/g, basePath)
|
|
55
75
|
.replace(/{hostName}/g, hostName)
|
|
56
76
|
.replace(/{fileName}/g, fileName);
|
|
57
77
|
if (className && className !== "<global>") {
|
|
58
|
-
|
|
78
|
+
const lowerClassName = className.toLowerCase();
|
|
79
|
+
// For classes that already have namespace prefix (e.g., Office.MailboxEnums.ActionType),
|
|
80
|
+
// remove "office." from template since it's already in the className
|
|
81
|
+
if (lowerClassName.startsWith("office.")) {
|
|
82
|
+
result = result.replace(/\/office\.{className}/g, "/{className}");
|
|
83
|
+
}
|
|
84
|
+
result = result.replace(/{className}/g, lowerClassName);
|
|
59
85
|
}
|
|
60
86
|
if (field) {
|
|
61
87
|
const suffix = (field.type === FieldType.Method || field.type === FieldType.Function) ? "-member(1)" : "-member";
|
|
@@ -85,8 +111,9 @@ exports.DEFAULT_LINK_CONFIGS = [
|
|
|
85
111
|
{
|
|
86
112
|
pathPattern: ".*", // matches any path as fallback
|
|
87
113
|
globalFunctionTemplate: "/{basePath}#{hostName}-{fileName}-{fieldName}-function(1)",
|
|
88
|
-
classTemplate: "/{basePath}.{className}",
|
|
89
|
-
classMemberTemplate: "/{basePath}.{className}#{hostName}-
|
|
114
|
+
classTemplate: "/{basePath}/office.{className}",
|
|
115
|
+
classMemberTemplate: "/{basePath}/office.{className}#{hostName}-office-{className}-{fieldName}{suffix}",
|
|
116
|
+
enumTemplate: "/{basePath}/office.{className}"
|
|
90
117
|
}
|
|
91
118
|
];
|
|
92
119
|
// Parsing context to encapsulate state during DTS parsing
|
|
@@ -95,11 +122,19 @@ class ParsingContext {
|
|
|
95
122
|
this.topClass = null;
|
|
96
123
|
this.lastItem = null;
|
|
97
124
|
this.globalFunctionsClass = null;
|
|
125
|
+
this.namespaceStack = [];
|
|
98
126
|
}
|
|
99
127
|
reset() {
|
|
100
128
|
this.topClass = null;
|
|
101
129
|
this.lastItem = null;
|
|
102
130
|
this.globalFunctionsClass = null;
|
|
131
|
+
this.namespaceStack = [];
|
|
132
|
+
}
|
|
133
|
+
getFullyQualifiedName(name) {
|
|
134
|
+
if (this.namespaceStack.length === 0) {
|
|
135
|
+
return name;
|
|
136
|
+
}
|
|
137
|
+
return this.namespaceStack.join(".") + "." + name;
|
|
103
138
|
}
|
|
104
139
|
ensureGlobalFunctionsClass(allClasses) {
|
|
105
140
|
if (this.globalFunctionsClass === null) {
|
|
@@ -413,8 +448,12 @@ class APISet {
|
|
|
413
448
|
output += "|*global*|";
|
|
414
449
|
}
|
|
415
450
|
else {
|
|
416
|
-
|
|
417
|
-
|
|
451
|
+
// For enums, display only the simple name but use full qualified name in the link
|
|
452
|
+
const displayName = isEnum && className.includes(".")
|
|
453
|
+
? className.substring(className.lastIndexOf(".") + 1)
|
|
454
|
+
: className;
|
|
455
|
+
output += "|[" + displayName + "]("
|
|
456
|
+
+ buildClassLink(finalOptions.relativePath, className, finalOptions.linkConfigs, isEnum) + ")|";
|
|
418
457
|
}
|
|
419
458
|
// Ignore the following:
|
|
420
459
|
// - Fields matching excluded patterns (configurable, no defaults - all fields included unless explicitly excluded)
|
|
@@ -432,7 +471,11 @@ class APISet {
|
|
|
432
471
|
}
|
|
433
472
|
// remove unnecessary parts of the declaration string
|
|
434
473
|
let newItemText = field.declarationString.replace(/;/g, "");
|
|
435
|
-
if (field.type === FieldType.
|
|
474
|
+
if (field.type === FieldType.Enum) {
|
|
475
|
+
// For enum members, just use the field name as-is
|
|
476
|
+
newItemText = field.name;
|
|
477
|
+
}
|
|
478
|
+
else if (field.type === FieldType.Property) {
|
|
436
479
|
// Remove the optional modifier and type.
|
|
437
480
|
newItemText = newItemText.replace(/\?/g, "");
|
|
438
481
|
newItemText = newItemText.substring(0, newItemText.indexOf(":"));
|
|
@@ -453,8 +496,16 @@ class APISet {
|
|
|
453
496
|
newItemText = newItemText.replace(/\|/g, "\\|").replace(/\n|\t/gm, "");
|
|
454
497
|
newItemText = newItemText.replace(/[\s][\s]+/g, " ").replace(/\( /g, "(").replace(/ \)/g, ")").replace(/,\)/g, ")").replace(/([\w]\??: )\\\| /g, "$1"); // dprint formatting quirks
|
|
455
498
|
newItemText = newItemText.replace(/\<any\>/g, "");
|
|
456
|
-
|
|
457
|
-
|
|
499
|
+
newItemText = newItemText.replace(/</g, "\\<").replace(/>/g, "\\>"); // escape angle brackets for markdown
|
|
500
|
+
let tableLine;
|
|
501
|
+
if (isEnum) {
|
|
502
|
+
// Enum fields are plain text (no link)
|
|
503
|
+
tableLine = newItemText + "|";
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
tableLine = "[" + newItemText + "]("
|
|
507
|
+
+ buildFieldLink(finalOptions.relativePath, className, field, finalOptions.linkConfigs) + ")|";
|
|
508
|
+
}
|
|
458
509
|
tableLine += removeAtLink(extractFirstSentenceFromComment(field.comment));
|
|
459
510
|
output += tableLine + "|\n";
|
|
460
511
|
});
|
|
@@ -523,9 +574,11 @@ function findMatchingLinkConfig(relativePath, linkConfigs = exports.DEFAULT_LINK
|
|
|
523
574
|
const matchingConfig = compiledConfigs.find(({ regex }) => regex.test(relativePath));
|
|
524
575
|
return matchingConfig ? matchingConfig.config : exports.DEFAULT_LINK_CONFIGS[exports.DEFAULT_LINK_CONFIGS.length - 1];
|
|
525
576
|
}
|
|
526
|
-
function buildClassLink(relativePath, className, linkConfigs = exports.DEFAULT_LINK_CONFIGS) {
|
|
577
|
+
function buildClassLink(relativePath, className, linkConfigs = exports.DEFAULT_LINK_CONFIGS, isEnum = false) {
|
|
527
578
|
const config = findMatchingLinkConfig(relativePath, linkConfigs);
|
|
528
|
-
|
|
579
|
+
// Use enumTemplate for enums if available, otherwise fall back to classTemplate
|
|
580
|
+
const template = isEnum && config.enumTemplate ? config.enumTemplate : config.classTemplate;
|
|
581
|
+
return buildLinkFromTemplate(template, relativePath, className);
|
|
529
582
|
}
|
|
530
583
|
function buildFieldLink(relativePath, className, field, linkConfigs = exports.DEFAULT_LINK_CONFIGS) {
|
|
531
584
|
const config = findMatchingLinkConfig(relativePath, linkConfigs);
|
|
@@ -577,6 +630,18 @@ function parseDTSInternal(node, allClasses, context) {
|
|
|
577
630
|
break;
|
|
578
631
|
case ts.SyntaxKind.TypeLiteral:
|
|
579
632
|
return;
|
|
633
|
+
case ts.SyntaxKind.ModuleDeclaration:
|
|
634
|
+
// Handle namespace - push to stack, process children, then pop
|
|
635
|
+
const moduleNode = node;
|
|
636
|
+
if (moduleNode.name && ts.isIdentifier(moduleNode.name)) {
|
|
637
|
+
context.namespaceStack.push(moduleNode.name.text);
|
|
638
|
+
node.getChildren().forEach((element) => {
|
|
639
|
+
parseDTSInternal(element, allClasses, context);
|
|
640
|
+
});
|
|
641
|
+
context.namespaceStack.pop();
|
|
642
|
+
return; // Already processed children
|
|
643
|
+
}
|
|
644
|
+
break;
|
|
580
645
|
default:
|
|
581
646
|
// the compiler parses comments after the class/field, therefore this connects to the previous item
|
|
582
647
|
if (node.getText().indexOf("/**") >= 0 &&
|
|
@@ -596,7 +661,11 @@ function parseDTSInternal(node, allClasses, context) {
|
|
|
596
661
|
});
|
|
597
662
|
}
|
|
598
663
|
function parseDTSTopLevelItem(node, allClasses, type, context) {
|
|
599
|
-
|
|
664
|
+
// Use fully qualified name for enums to preserve namespace path (e.g., Office.MailboxEnums.ActionType)
|
|
665
|
+
const qualifiedName = type === ClassType.Enum
|
|
666
|
+
? context.getFullyQualifiedName(node.name.text)
|
|
667
|
+
: node.name.text;
|
|
668
|
+
context.topClass = new ClassStruct("export " + type.toLowerCase() + " " + qualifiedName, "", type);
|
|
600
669
|
allClasses.addClass(context.topClass);
|
|
601
670
|
context.lastItem = context.topClass;
|
|
602
671
|
}
|
package/dist/whats-new.js
CHANGED
|
@@ -57,7 +57,8 @@ function loadWhatsNewConfig(configFilePath) {
|
|
|
57
57
|
pathPattern: item.pathPattern,
|
|
58
58
|
globalFunctionTemplate: item.globalFunctionTemplate,
|
|
59
59
|
classTemplate: item.classTemplate,
|
|
60
|
-
classMemberTemplate: item.classMemberTemplate
|
|
60
|
+
classMemberTemplate: item.classMemberTemplate,
|
|
61
|
+
enumTemplate: item.enumTemplate // Optional: defaults to classTemplate if not provided
|
|
61
62
|
};
|
|
62
63
|
});
|
|
63
64
|
}
|