versioned-d.ts-tools 0.7.0 → 0.7.1
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 +12 -9
- package/dist/dts-utilities.js +112 -87
- package/dist/whats-new.d.ts +18 -1
- package/dist/whats-new.js +39 -21
- package/package.json +1 -1
package/dist/dts-utilities.d.ts
CHANGED
|
@@ -13,6 +13,15 @@ export interface WhatsNewConfig {
|
|
|
13
13
|
linkConfigs?: LinkConfig[];
|
|
14
14
|
replacements?: any[];
|
|
15
15
|
}
|
|
16
|
+
export interface MarkdownOptions {
|
|
17
|
+
relativePath: string;
|
|
18
|
+
linkConfigs?: LinkConfig[];
|
|
19
|
+
excludedFieldNames?: string[];
|
|
20
|
+
excludedClassPatterns?: string[];
|
|
21
|
+
excludedFieldPatterns?: string[];
|
|
22
|
+
includeStaticFields?: boolean;
|
|
23
|
+
includeEnums?: boolean;
|
|
24
|
+
}
|
|
16
25
|
export declare const DEFAULT_LINK_CONFIGS: LinkConfig[];
|
|
17
26
|
declare enum ClassType {
|
|
18
27
|
Class = "Class",
|
|
@@ -54,18 +63,12 @@ export declare class APISet {
|
|
|
54
63
|
/**
|
|
55
64
|
* Generates markdown documentation for API differences.
|
|
56
65
|
* By default, all classes and fields are included in the output.
|
|
57
|
-
* Exclusions must be explicitly configured via the
|
|
66
|
+
* Exclusions must be explicitly configured via the options.
|
|
58
67
|
*
|
|
59
|
-
* @param
|
|
60
|
-
* @param linkConfigs - Link configuration templates (defaults to built-in Office configs)
|
|
61
|
-
* @param excludedFieldNames - Array of field names to exclude (no defaults)
|
|
62
|
-
* @param excludedClassPatterns - Array of regex patterns for classes to exclude (no defaults)
|
|
63
|
-
* @param excludedFieldPatterns - Array of regex patterns for fields to exclude (no defaults)
|
|
64
|
-
* @param includeStaticFields - Whether to include static fields (default: true)
|
|
65
|
-
* @param includeEnums - Whether to include enums (default: true)
|
|
68
|
+
* @param options - Configuration options for markdown generation
|
|
66
69
|
* @returns Markdown table string
|
|
67
70
|
*/
|
|
68
|
-
getAsMarkdown(
|
|
71
|
+
getAsMarkdown(options: MarkdownOptions): string;
|
|
69
72
|
sort(): void;
|
|
70
73
|
}
|
|
71
74
|
export declare function parseDTS(fileName: string, fileContents: string): APISet;
|
package/dist/dts-utilities.js
CHANGED
|
@@ -65,6 +65,21 @@ function buildLinkFromTemplate(template, relativePath, className, field) {
|
|
|
65
65
|
}
|
|
66
66
|
return result;
|
|
67
67
|
}
|
|
68
|
+
// Helper functions for pattern matching optimization
|
|
69
|
+
function compilePatterns(patterns) {
|
|
70
|
+
if (!patterns || patterns.length === 0) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
return patterns.map(pattern => {
|
|
74
|
+
try {
|
|
75
|
+
return new RegExp(pattern);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.warn(`Invalid regex pattern "${pattern}": ${error.message}`);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}).filter(Boolean);
|
|
82
|
+
}
|
|
68
83
|
// Default configurations for known Office applications
|
|
69
84
|
exports.DEFAULT_LINK_CONFIGS = [
|
|
70
85
|
{
|
|
@@ -80,10 +95,26 @@ exports.DEFAULT_LINK_CONFIGS = [
|
|
|
80
95
|
classMemberTemplate: "/{basePath}.{className}#{hostName}-{fileName}-{className}-{fieldName}{suffix}"
|
|
81
96
|
}
|
|
82
97
|
];
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
98
|
+
// Parsing context to encapsulate state during DTS parsing
|
|
99
|
+
class ParsingContext {
|
|
100
|
+
constructor() {
|
|
101
|
+
this.topClass = null;
|
|
102
|
+
this.lastItem = null;
|
|
103
|
+
this.globalFunctionsClass = null;
|
|
104
|
+
}
|
|
105
|
+
reset() {
|
|
106
|
+
this.topClass = null;
|
|
107
|
+
this.lastItem = null;
|
|
108
|
+
this.globalFunctionsClass = null;
|
|
109
|
+
}
|
|
110
|
+
ensureGlobalFunctionsClass(allClasses) {
|
|
111
|
+
if (this.globalFunctionsClass === null) {
|
|
112
|
+
this.globalFunctionsClass = new ClassStruct("<global>", "", ClassType.Interface);
|
|
113
|
+
allClasses.addClass(this.globalFunctionsClass);
|
|
114
|
+
}
|
|
115
|
+
return this.globalFunctionsClass;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
87
118
|
var ClassType;
|
|
88
119
|
(function (ClassType) {
|
|
89
120
|
ClassType["Class"] = "Class";
|
|
@@ -138,26 +169,11 @@ class APISet {
|
|
|
138
169
|
this.api.push(clas);
|
|
139
170
|
}
|
|
140
171
|
containsClass(clas) {
|
|
141
|
-
|
|
142
|
-
this.api.forEach((element) => {
|
|
143
|
-
if (element.declarationString === clas.declarationString) {
|
|
144
|
-
found = true;
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
return found;
|
|
172
|
+
return this.api.some(element => element.declarationString === clas.declarationString);
|
|
148
173
|
}
|
|
149
174
|
containsField(clas, field) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (element.declarationString === clas.declarationString) {
|
|
153
|
-
element.fields.forEach((thisField) => {
|
|
154
|
-
if (thisField.declarationString === field.declarationString) {
|
|
155
|
-
found = true;
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
return found;
|
|
175
|
+
const targetClass = this.api.find(element => element.declarationString === clas.declarationString);
|
|
176
|
+
return targetClass ? targetClass.fields.some(thisField => thisField.declarationString === field.declarationString) : false;
|
|
161
177
|
}
|
|
162
178
|
// finds the new fields and classes
|
|
163
179
|
diff(other) {
|
|
@@ -203,19 +219,24 @@ class APISet {
|
|
|
203
219
|
/**
|
|
204
220
|
* Generates markdown documentation for API differences.
|
|
205
221
|
* By default, all classes and fields are included in the output.
|
|
206
|
-
* Exclusions must be explicitly configured via the
|
|
222
|
+
* Exclusions must be explicitly configured via the options.
|
|
207
223
|
*
|
|
208
|
-
* @param
|
|
209
|
-
* @param linkConfigs - Link configuration templates (defaults to built-in Office configs)
|
|
210
|
-
* @param excludedFieldNames - Array of field names to exclude (no defaults)
|
|
211
|
-
* @param excludedClassPatterns - Array of regex patterns for classes to exclude (no defaults)
|
|
212
|
-
* @param excludedFieldPatterns - Array of regex patterns for fields to exclude (no defaults)
|
|
213
|
-
* @param includeStaticFields - Whether to include static fields (default: true)
|
|
214
|
-
* @param includeEnums - Whether to include enums (default: true)
|
|
224
|
+
* @param options - Configuration options for markdown generation
|
|
215
225
|
* @returns Markdown table string
|
|
216
226
|
*/
|
|
217
|
-
getAsMarkdown(
|
|
227
|
+
getAsMarkdown(options) {
|
|
228
|
+
const finalOptions = {
|
|
229
|
+
linkConfigs: exports.DEFAULT_LINK_CONFIGS,
|
|
230
|
+
excludedFieldNames: [],
|
|
231
|
+
excludedClassPatterns: [],
|
|
232
|
+
excludedFieldPatterns: [],
|
|
233
|
+
includeStaticFields: true,
|
|
234
|
+
includeEnums: false,
|
|
235
|
+
...options // Spread user options to override defaults
|
|
236
|
+
};
|
|
218
237
|
this.sort();
|
|
238
|
+
// Pre-compile regex patterns for better performance (class patterns only)
|
|
239
|
+
const compiledClassPatterns = compilePatterns(finalOptions.excludedClassPatterns);
|
|
219
240
|
// table header
|
|
220
241
|
let output = "| Class | Fields | Description |\n|:---|:---|:---|\n";
|
|
221
242
|
this.api.forEach((clas) => {
|
|
@@ -223,17 +244,9 @@ class APISet {
|
|
|
223
244
|
// - Enums (configurable via includeEnums, default: true - enums included by default).
|
|
224
245
|
// - Classes matching excluded patterns (configurable, no defaults - all classes included unless explicitly excluded)
|
|
225
246
|
const className = clas.getClassName();
|
|
226
|
-
const isExcludedByPattern =
|
|
227
|
-
try {
|
|
228
|
-
return new RegExp(pattern).test(className);
|
|
229
|
-
}
|
|
230
|
-
catch (error) {
|
|
231
|
-
console.warn(`Invalid regex pattern "${pattern}": ${error.message}`);
|
|
232
|
-
return false;
|
|
233
|
-
}
|
|
234
|
-
});
|
|
247
|
+
const isExcludedByPattern = compiledClassPatterns.some(regex => regex.test(className));
|
|
235
248
|
const isEnum = clas.type === ClassType.Enum;
|
|
236
|
-
if ((includeEnums || !isEnum) && !isExcludedByPattern) {
|
|
249
|
+
if ((finalOptions.includeEnums || !isEnum) && !isExcludedByPattern) {
|
|
237
250
|
const className = clas.getClassName();
|
|
238
251
|
// Special handling for <global> - no link
|
|
239
252
|
if (className === "<global>") {
|
|
@@ -241,7 +254,7 @@ class APISet {
|
|
|
241
254
|
}
|
|
242
255
|
else {
|
|
243
256
|
output += "|[" + className + "]("
|
|
244
|
-
+ buildClassLink(relativePath, className, linkConfigs) + ")|";
|
|
257
|
+
+ buildClassLink(finalOptions.relativePath, className, finalOptions.linkConfigs) + ")|";
|
|
245
258
|
}
|
|
246
259
|
// Ignore the following:
|
|
247
260
|
// - Fields matching excluded patterns (configurable, no defaults - all fields included unless explicitly excluded)
|
|
@@ -249,7 +262,8 @@ class APISet {
|
|
|
249
262
|
// - Static fields (configurable via includeStaticFields, default: true - static fields included by default)
|
|
250
263
|
let filteredFields = clas.fields.filter((field) => {
|
|
251
264
|
// Check if field matches any excluded pattern
|
|
252
|
-
|
|
265
|
+
// Note: Test against field declaration string, just like the original code
|
|
266
|
+
const isExcludedByPattern = (finalOptions.excludedFieldPatterns || []).some(pattern => {
|
|
253
267
|
try {
|
|
254
268
|
return new RegExp(pattern, 'g').test(field.declarationString);
|
|
255
269
|
}
|
|
@@ -261,8 +275,8 @@ class APISet {
|
|
|
261
275
|
// Check if field is static and should be excluded
|
|
262
276
|
const isStaticField = field.declarationString.includes("static ");
|
|
263
277
|
return (!isExcludedByPattern &&
|
|
264
|
-
!excludedFieldNames.includes(field.name) &&
|
|
265
|
-
(includeStaticFields || !isStaticField));
|
|
278
|
+
!(finalOptions.excludedFieldNames || []).includes(field.name) &&
|
|
279
|
+
(finalOptions.includeStaticFields || !isStaticField));
|
|
266
280
|
});
|
|
267
281
|
let first = true;
|
|
268
282
|
if (filteredFields.length > 0) {
|
|
@@ -297,7 +311,7 @@ class APISet {
|
|
|
297
311
|
newItemText = newItemText.replace(/[\s][\s]+/g, " ").replace(/\( /g, "(").replace(/ \)/g, ")").replace(/,\)/g, ")").replace(/([\w]\??: )\\\| /g, "$1"); // dprint formatting quirks
|
|
298
312
|
newItemText = newItemText.replace(/\<any\>/g, "");
|
|
299
313
|
let tableLine = "[" + newItemText + "]("
|
|
300
|
-
+ buildFieldLink(relativePath, className, field, linkConfigs) + ")|";
|
|
314
|
+
+ buildFieldLink(finalOptions.relativePath, className, field, finalOptions.linkConfigs) + ")|";
|
|
301
315
|
tableLine += removeAtLink(extractFirstSentenceFromComment(field.comment));
|
|
302
316
|
output += tableLine + "|\n";
|
|
303
317
|
});
|
|
@@ -344,18 +358,33 @@ function extractFirstSentenceFromComment(commentText) {
|
|
|
344
358
|
function removeAtLink(commentText) {
|
|
345
359
|
// Replace links with the format "{@link Foo}" with "Foo".
|
|
346
360
|
commentText = commentText.replace(/{@link ([^|]*?)}/gm, "$1");
|
|
347
|
-
// Replace links with the format "{@link
|
|
348
|
-
commentText = commentText.replace(/{@link ([^}]*?) \| (
|
|
361
|
+
// Replace links with the format "{@link URL | text}" with just the text part.
|
|
362
|
+
commentText = commentText.replace(/{@link ([^}]*?) \| ([^}]*?)}/gm, "$2");
|
|
349
363
|
return commentText;
|
|
350
364
|
}
|
|
365
|
+
// Cache for compiled link config patterns to avoid recompilation
|
|
366
|
+
const linkConfigCache = new Map();
|
|
367
|
+
function getCompiledLinkConfigs(linkConfigs) {
|
|
368
|
+
if (!linkConfigCache.has(linkConfigs)) {
|
|
369
|
+
const compiled = linkConfigs.map(config => ({
|
|
370
|
+
config,
|
|
371
|
+
regex: new RegExp(config.pathPattern)
|
|
372
|
+
}));
|
|
373
|
+
linkConfigCache.set(linkConfigs, compiled);
|
|
374
|
+
}
|
|
375
|
+
return linkConfigCache.get(linkConfigs);
|
|
376
|
+
}
|
|
377
|
+
function findMatchingLinkConfig(relativePath, linkConfigs = exports.DEFAULT_LINK_CONFIGS) {
|
|
378
|
+
const compiledConfigs = getCompiledLinkConfigs(linkConfigs);
|
|
379
|
+
const matchingConfig = compiledConfigs.find(({ regex }) => regex.test(relativePath));
|
|
380
|
+
return matchingConfig ? matchingConfig.config : exports.DEFAULT_LINK_CONFIGS[exports.DEFAULT_LINK_CONFIGS.length - 1];
|
|
381
|
+
}
|
|
351
382
|
function buildClassLink(relativePath, className, linkConfigs = exports.DEFAULT_LINK_CONFIGS) {
|
|
352
|
-
|
|
353
|
-
const config = linkConfigs.find(config => new RegExp(config.pathPattern).test(relativePath)) || exports.DEFAULT_LINK_CONFIGS[exports.DEFAULT_LINK_CONFIGS.length - 1]; // fallback to last config
|
|
383
|
+
const config = findMatchingLinkConfig(relativePath, linkConfigs);
|
|
354
384
|
return buildLinkFromTemplate(config.classTemplate, relativePath, className);
|
|
355
385
|
}
|
|
356
386
|
function buildFieldLink(relativePath, className, field, linkConfigs = exports.DEFAULT_LINK_CONFIGS) {
|
|
357
|
-
|
|
358
|
-
const config = linkConfigs.find(config => new RegExp(config.pathPattern).test(relativePath)) || exports.DEFAULT_LINK_CONFIGS[exports.DEFAULT_LINK_CONFIGS.length - 1]; // fallback to last config
|
|
387
|
+
const config = findMatchingLinkConfig(relativePath, linkConfigs);
|
|
359
388
|
// Use appropriate template based on whether it's a global function or class member
|
|
360
389
|
if (className.trim() === "<global>") {
|
|
361
390
|
return buildLinkFromTemplate(config.globalFunctionTemplate, relativePath, className, field);
|
|
@@ -365,43 +394,42 @@ function buildFieldLink(relativePath, className, field, linkConfigs = exports.DE
|
|
|
365
394
|
}
|
|
366
395
|
}
|
|
367
396
|
function parseDTS(fileName, fileContents) {
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
globalFunctionsClass = null;
|
|
397
|
+
// Create parsing context to encapsulate state
|
|
398
|
+
const context = new ParsingContext();
|
|
399
|
+
context.reset();
|
|
372
400
|
const node = ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES2015, true);
|
|
373
401
|
const allClasses = new APISet();
|
|
374
|
-
parseDTSInternal(node, allClasses);
|
|
402
|
+
parseDTSInternal(node, allClasses, context);
|
|
375
403
|
return allClasses;
|
|
376
404
|
}
|
|
377
|
-
function parseDTSInternal(node, allClasses) {
|
|
405
|
+
function parseDTSInternal(node, allClasses, context) {
|
|
378
406
|
switch (node.kind) {
|
|
379
407
|
case ts.SyntaxKind.InterfaceDeclaration:
|
|
380
|
-
parseDTSTopLevelItem(node, allClasses, ClassType.Interface);
|
|
408
|
+
parseDTSTopLevelItem(node, allClasses, ClassType.Interface, context);
|
|
381
409
|
break;
|
|
382
410
|
case ts.SyntaxKind.ClassDeclaration:
|
|
383
|
-
parseDTSTopLevelItem(node, allClasses, ClassType.Class);
|
|
411
|
+
parseDTSTopLevelItem(node, allClasses, ClassType.Class, context);
|
|
384
412
|
break;
|
|
385
413
|
case ts.SyntaxKind.EnumDeclaration:
|
|
386
|
-
parseDTSTopLevelItem(node, allClasses, ClassType.Enum);
|
|
414
|
+
parseDTSTopLevelItem(node, allClasses, ClassType.Enum, context);
|
|
387
415
|
break;
|
|
388
416
|
case ts.SyntaxKind.FunctionDeclaration:
|
|
389
|
-
parseDTSGlobalFunctionItem(node, allClasses);
|
|
417
|
+
parseDTSGlobalFunctionItem(node, allClasses, context);
|
|
390
418
|
break;
|
|
391
419
|
case ts.SyntaxKind.PropertySignature:
|
|
392
|
-
parseDTSFieldItem(node, FieldType.Property);
|
|
420
|
+
parseDTSFieldItem(node, FieldType.Property, context);
|
|
393
421
|
break;
|
|
394
422
|
case ts.SyntaxKind.PropertyDeclaration:
|
|
395
|
-
parseDTSFieldItem(node, FieldType.Property);
|
|
423
|
+
parseDTSFieldItem(node, FieldType.Property, context);
|
|
396
424
|
break;
|
|
397
425
|
case ts.SyntaxKind.EnumMember:
|
|
398
|
-
parseDTSFieldItem(node, FieldType.Enum);
|
|
426
|
+
parseDTSFieldItem(node, FieldType.Enum, context);
|
|
399
427
|
break;
|
|
400
428
|
case ts.SyntaxKind.MethodSignature:
|
|
401
|
-
parseDTSFieldItem(node, FieldType.Method);
|
|
429
|
+
parseDTSFieldItem(node, FieldType.Method, context);
|
|
402
430
|
break;
|
|
403
431
|
case ts.SyntaxKind.MethodDeclaration:
|
|
404
|
-
parseDTSFieldItem(node, FieldType.Method);
|
|
432
|
+
parseDTSFieldItem(node, FieldType.Method, context);
|
|
405
433
|
break;
|
|
406
434
|
case ts.SyntaxKind.TypeLiteral:
|
|
407
435
|
return;
|
|
@@ -409,39 +437,36 @@ function parseDTSInternal(node, allClasses) {
|
|
|
409
437
|
// the compiler parses comments after the class/field, therefore this connects to the previous item
|
|
410
438
|
if (node.getText().indexOf("/**") >= 0 &&
|
|
411
439
|
node.getText().indexOf("*/") >= 0 &&
|
|
412
|
-
lastItem !== null &&
|
|
413
|
-
lastItem.comment === "") {
|
|
440
|
+
context.lastItem !== null &&
|
|
441
|
+
context.lastItem.comment === "") {
|
|
414
442
|
// clean up spacing as best we can for the diffed d.ts
|
|
415
|
-
lastItem.comment = node.getText().replace(/ \*/g, "*");
|
|
416
|
-
if (lastItem.comment.indexOf("@eventproperty") >= 0) {
|
|
443
|
+
context.lastItem.comment = node.getText().replace(/ \*/g, "*");
|
|
444
|
+
if (context.lastItem.comment.indexOf("@eventproperty") >= 0) {
|
|
417
445
|
// events are indistinguishable from properties aside from this tag
|
|
418
|
-
lastItem.type = FieldType.Event;
|
|
446
|
+
context.lastItem.type = FieldType.Event;
|
|
419
447
|
}
|
|
420
448
|
}
|
|
421
449
|
}
|
|
422
450
|
node.getChildren().forEach((element) => {
|
|
423
|
-
parseDTSInternal(element, allClasses);
|
|
451
|
+
parseDTSInternal(element, allClasses, context);
|
|
424
452
|
});
|
|
425
453
|
}
|
|
426
|
-
function parseDTSTopLevelItem(node, allClasses, type) {
|
|
427
|
-
topClass = new ClassStruct("export " + type.toLowerCase() + " " + node.name.text, "", type);
|
|
428
|
-
allClasses.addClass(topClass);
|
|
429
|
-
lastItem = topClass;
|
|
454
|
+
function parseDTSTopLevelItem(node, allClasses, type, context) {
|
|
455
|
+
context.topClass = new ClassStruct("export " + type.toLowerCase() + " " + node.name.text, "", type);
|
|
456
|
+
allClasses.addClass(context.topClass);
|
|
457
|
+
context.lastItem = context.topClass;
|
|
430
458
|
}
|
|
431
|
-
function parseDTSFieldItem(node, type) {
|
|
459
|
+
function parseDTSFieldItem(node, type, context) {
|
|
432
460
|
const newField = new FieldStruct(node.getText(), "", type, node.name.getText());
|
|
433
|
-
topClass.fields.push(newField);
|
|
434
|
-
lastItem = newField;
|
|
461
|
+
context.topClass.fields.push(newField);
|
|
462
|
+
context.lastItem = newField;
|
|
435
463
|
}
|
|
436
|
-
function parseDTSGlobalFunctionItem(node, allClasses) {
|
|
464
|
+
function parseDTSGlobalFunctionItem(node, allClasses, context) {
|
|
437
465
|
// Create a "<global>" class to hold top-level functions if it doesn't exist
|
|
438
|
-
|
|
439
|
-
globalFunctionsClass = new ClassStruct("<global>", "", ClassType.Interface);
|
|
440
|
-
allClasses.addClass(globalFunctionsClass);
|
|
441
|
-
}
|
|
466
|
+
const globalClass = context.ensureGlobalFunctionsClass(allClasses);
|
|
442
467
|
const functionName = node.name ? node.name.getText() : "anonymous";
|
|
443
468
|
const newFunction = new FieldStruct(node.getText(), "", FieldType.Function, functionName);
|
|
444
|
-
|
|
445
|
-
lastItem = newFunction;
|
|
469
|
+
globalClass.fields.push(newFunction);
|
|
470
|
+
context.lastItem = newFunction;
|
|
446
471
|
}
|
|
447
472
|
//# sourceMappingURL=dts-utilities.js.map
|
package/dist/whats-new.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { LinkConfig } from './dts-utilities';
|
|
3
|
-
export
|
|
3
|
+
export interface WhatsNewOptions {
|
|
4
|
+
newDtsPath: string;
|
|
5
|
+
oldDtsPath: string;
|
|
6
|
+
outputPath: string;
|
|
7
|
+
relativePath: string;
|
|
8
|
+
linkConfigs?: LinkConfig[];
|
|
9
|
+
configFilePath?: string;
|
|
10
|
+
excludedFieldNames?: string[];
|
|
11
|
+
excludedClassPatterns?: string[];
|
|
12
|
+
excludedFieldPatterns?: string[];
|
|
13
|
+
includeStaticFields?: boolean;
|
|
14
|
+
includeEnums?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generates "what's new" documentation by comparing two TypeScript definition files.
|
|
18
|
+
* @param options - Configuration options for the generation
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateWhatsNew(options: WhatsNewOptions): void;
|
package/dist/whats-new.js
CHANGED
|
@@ -75,46 +75,58 @@ function loadWhatsNewConfig(configFilePath) {
|
|
|
75
75
|
return {};
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Generates "what's new" documentation by comparing two TypeScript definition files.
|
|
80
|
+
* @param options - Configuration options for the generation
|
|
81
|
+
*/
|
|
82
|
+
function generateWhatsNew(options) {
|
|
79
83
|
// Load configuration from file if provided
|
|
80
|
-
let effectiveLinkConfigs = linkConfigs;
|
|
81
|
-
let effectiveExcludedFieldNames = excludedFieldNames;
|
|
82
|
-
let effectiveExcludedClassPatterns = excludedClassPatterns;
|
|
83
|
-
let effectiveExcludedFieldPatterns = excludedFieldPatterns;
|
|
84
|
-
let effectiveIncludeStaticFields = includeStaticFields;
|
|
85
|
-
let effectiveIncludeEnums = includeEnums;
|
|
86
|
-
if (configFilePath && (!linkConfigs || !excludedFieldNames || !excludedClassPatterns || !excludedFieldPatterns || includeStaticFields === undefined || includeEnums === undefined)) {
|
|
87
|
-
const config = loadWhatsNewConfig(configFilePath);
|
|
88
|
-
if (!linkConfigs && config.linkConfigs) {
|
|
84
|
+
let effectiveLinkConfigs = options.linkConfigs;
|
|
85
|
+
let effectiveExcludedFieldNames = options.excludedFieldNames;
|
|
86
|
+
let effectiveExcludedClassPatterns = options.excludedClassPatterns;
|
|
87
|
+
let effectiveExcludedFieldPatterns = options.excludedFieldPatterns;
|
|
88
|
+
let effectiveIncludeStaticFields = options.includeStaticFields;
|
|
89
|
+
let effectiveIncludeEnums = options.includeEnums;
|
|
90
|
+
if (options.configFilePath && (!options.linkConfigs || !options.excludedFieldNames || !options.excludedClassPatterns || !options.excludedFieldPatterns || options.includeStaticFields === undefined || options.includeEnums === undefined)) {
|
|
91
|
+
const config = loadWhatsNewConfig(options.configFilePath);
|
|
92
|
+
if (!options.linkConfigs && config.linkConfigs) {
|
|
89
93
|
effectiveLinkConfigs = config.linkConfigs;
|
|
90
94
|
}
|
|
91
|
-
if (!excludedFieldNames && config.excludedFieldNames) {
|
|
95
|
+
if (!options.excludedFieldNames && config.excludedFieldNames) {
|
|
92
96
|
effectiveExcludedFieldNames = config.excludedFieldNames;
|
|
93
97
|
}
|
|
94
|
-
if (!excludedClassPatterns && config.excludedClassPatterns) {
|
|
98
|
+
if (!options.excludedClassPatterns && config.excludedClassPatterns) {
|
|
95
99
|
effectiveExcludedClassPatterns = config.excludedClassPatterns;
|
|
96
100
|
}
|
|
97
|
-
if (!excludedFieldPatterns && config.excludedFieldPatterns) {
|
|
101
|
+
if (!options.excludedFieldPatterns && config.excludedFieldPatterns) {
|
|
98
102
|
effectiveExcludedFieldPatterns = config.excludedFieldPatterns;
|
|
99
103
|
}
|
|
100
|
-
if (includeStaticFields === undefined && config.includeStaticFields !== undefined) {
|
|
104
|
+
if (options.includeStaticFields === undefined && config.includeStaticFields !== undefined) {
|
|
101
105
|
effectiveIncludeStaticFields = config.includeStaticFields;
|
|
102
106
|
}
|
|
103
|
-
if (includeEnums === undefined) {
|
|
107
|
+
if (options.includeEnums === undefined) {
|
|
104
108
|
// Default to true when loading from config (inclusive by default)
|
|
105
109
|
effectiveIncludeEnums = config.includeEnums !== undefined ? config.includeEnums : true;
|
|
106
110
|
}
|
|
107
111
|
}
|
|
108
112
|
// read whole files
|
|
109
|
-
let wholeRelease = fsx.readFileSync(oldDtsPath).toString();
|
|
110
|
-
let wholePreview = fsx.readFileSync(newDtsPath).toString();
|
|
113
|
+
let wholeRelease = fsx.readFileSync(options.oldDtsPath).toString();
|
|
114
|
+
let wholePreview = fsx.readFileSync(options.newDtsPath).toString();
|
|
111
115
|
const releaseAPI = (0, dts_utilities_1.parseDTS)("release", wholeRelease);
|
|
112
116
|
const previewAPI = (0, dts_utilities_1.parseDTS)("preview", wholePreview);
|
|
113
117
|
const diffAPI = previewAPI.diff(releaseAPI);
|
|
114
|
-
if (!fsx.existsSync(outputPath + ".md")) {
|
|
115
|
-
fsx.createFileSync(outputPath + ".md");
|
|
118
|
+
if (!fsx.existsSync(options.outputPath + ".md")) {
|
|
119
|
+
fsx.createFileSync(options.outputPath + ".md");
|
|
116
120
|
}
|
|
117
|
-
fsx.writeFileSync(outputPath + ".md", diffAPI.getAsMarkdown(
|
|
121
|
+
fsx.writeFileSync(options.outputPath + ".md", diffAPI.getAsMarkdown({
|
|
122
|
+
relativePath: options.relativePath,
|
|
123
|
+
linkConfigs: effectiveLinkConfigs,
|
|
124
|
+
excludedFieldNames: effectiveExcludedFieldNames,
|
|
125
|
+
excludedClassPatterns: effectiveExcludedClassPatterns,
|
|
126
|
+
excludedFieldPatterns: effectiveExcludedFieldPatterns,
|
|
127
|
+
includeStaticFields: effectiveIncludeStaticFields,
|
|
128
|
+
includeEnums: effectiveIncludeEnums
|
|
129
|
+
}));
|
|
118
130
|
}
|
|
119
131
|
// CLI entry point
|
|
120
132
|
if (require.main === module) {
|
|
@@ -134,7 +146,13 @@ if (require.main === module) {
|
|
|
134
146
|
console.log(`Using configuration file: ${configFilePath}`);
|
|
135
147
|
}
|
|
136
148
|
tryCatch(async () => {
|
|
137
|
-
generateWhatsNew(
|
|
149
|
+
generateWhatsNew({
|
|
150
|
+
newDtsPath,
|
|
151
|
+
oldDtsPath,
|
|
152
|
+
outputPath,
|
|
153
|
+
relativePath,
|
|
154
|
+
configFilePath
|
|
155
|
+
});
|
|
138
156
|
});
|
|
139
157
|
}
|
|
140
158
|
async function tryCatch(call) {
|