@aiready/doc-drift 0.14.14 → 0.14.16
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/.turbo/turbo-build.log +13 -13
- package/.turbo/turbo-format-check.log +2 -2
- package/.turbo/turbo-lint$colon$fix.log +2 -0
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +38 -6
- package/.turbo/turbo-type-check.log +1 -1
- package/dist/chunk-35XBIDVM.mjs +347 -0
- package/dist/chunk-57NUPDIO.mjs +357 -0
- package/dist/chunk-IQBAXGOK.mjs +373 -0
- package/dist/cli.js +266 -35
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +0 -7
- package/dist/index.d.ts +0 -7
- package/dist/index.js +266 -35
- package/dist/index.mjs +1 -1
- package/package.json +5 -3
- package/src/analyzer.ts +28 -56
- package/src/constants.ts +214 -0
- package/src/heuristics.ts +53 -0
package/dist/index.js
CHANGED
|
@@ -32,13 +32,258 @@ var import_core2 = require("@aiready/core");
|
|
|
32
32
|
// src/analyzer.ts
|
|
33
33
|
var import_core = require("@aiready/core");
|
|
34
34
|
var import_fs = require("fs");
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var DESCRIPTIVE_PARAMS = /* @__PURE__ */ new Set([
|
|
38
|
+
"data",
|
|
39
|
+
"item",
|
|
40
|
+
"value",
|
|
41
|
+
"key",
|
|
42
|
+
"index",
|
|
43
|
+
"id",
|
|
44
|
+
"name",
|
|
45
|
+
"type",
|
|
46
|
+
"config",
|
|
47
|
+
"options",
|
|
48
|
+
"params",
|
|
49
|
+
"args",
|
|
50
|
+
"input",
|
|
51
|
+
"output",
|
|
52
|
+
"result",
|
|
53
|
+
"response",
|
|
54
|
+
"request",
|
|
55
|
+
"callback",
|
|
56
|
+
"handler",
|
|
57
|
+
"event",
|
|
58
|
+
"error",
|
|
59
|
+
"message",
|
|
60
|
+
"context",
|
|
61
|
+
"file",
|
|
62
|
+
"path",
|
|
63
|
+
"url",
|
|
64
|
+
"source",
|
|
65
|
+
"target",
|
|
66
|
+
"content",
|
|
67
|
+
"body",
|
|
68
|
+
"payload",
|
|
69
|
+
"user",
|
|
70
|
+
"userid",
|
|
71
|
+
"user_id",
|
|
72
|
+
"starttime",
|
|
73
|
+
"endtime",
|
|
74
|
+
"duration",
|
|
75
|
+
"timeout",
|
|
76
|
+
"retry",
|
|
77
|
+
"count",
|
|
78
|
+
"limit",
|
|
79
|
+
"offset",
|
|
80
|
+
"page",
|
|
81
|
+
"size",
|
|
82
|
+
"length",
|
|
83
|
+
"width",
|
|
84
|
+
"height",
|
|
85
|
+
"depth",
|
|
86
|
+
"color",
|
|
87
|
+
"background",
|
|
88
|
+
"foreground",
|
|
89
|
+
"border",
|
|
90
|
+
"margin",
|
|
91
|
+
"padding",
|
|
92
|
+
"position",
|
|
93
|
+
"top",
|
|
94
|
+
"bottom",
|
|
95
|
+
"left",
|
|
96
|
+
"right",
|
|
97
|
+
"center",
|
|
98
|
+
"start",
|
|
99
|
+
"end",
|
|
100
|
+
"begin",
|
|
101
|
+
"finish",
|
|
102
|
+
"complete",
|
|
103
|
+
"pending",
|
|
104
|
+
"active",
|
|
105
|
+
"inactive",
|
|
106
|
+
"enabled",
|
|
107
|
+
"disabled",
|
|
108
|
+
"visible",
|
|
109
|
+
"hidden",
|
|
110
|
+
"open",
|
|
111
|
+
"closed",
|
|
112
|
+
"locked",
|
|
113
|
+
"unlocked",
|
|
114
|
+
"read",
|
|
115
|
+
"write",
|
|
116
|
+
"append",
|
|
117
|
+
"prepend",
|
|
118
|
+
"insert",
|
|
119
|
+
"replace",
|
|
120
|
+
"merge",
|
|
121
|
+
"split",
|
|
122
|
+
"join",
|
|
123
|
+
"filter",
|
|
124
|
+
"map",
|
|
125
|
+
"reduce",
|
|
126
|
+
"find",
|
|
127
|
+
"sort",
|
|
128
|
+
"reverse",
|
|
129
|
+
"unique",
|
|
130
|
+
"flatten",
|
|
131
|
+
"compact",
|
|
132
|
+
"chunk",
|
|
133
|
+
"zip",
|
|
134
|
+
"unzip",
|
|
135
|
+
"completed",
|
|
136
|
+
"failed",
|
|
137
|
+
"healthy",
|
|
138
|
+
"high",
|
|
139
|
+
"medium",
|
|
140
|
+
"low",
|
|
141
|
+
"running",
|
|
142
|
+
"stopped",
|
|
143
|
+
"title",
|
|
144
|
+
"subtitle",
|
|
145
|
+
"label",
|
|
146
|
+
"description",
|
|
147
|
+
"version",
|
|
148
|
+
"timestamp",
|
|
149
|
+
"date",
|
|
150
|
+
"time",
|
|
151
|
+
"status",
|
|
152
|
+
"mode",
|
|
153
|
+
"action",
|
|
154
|
+
"effect",
|
|
155
|
+
"resource",
|
|
156
|
+
"principal",
|
|
157
|
+
"statement",
|
|
158
|
+
"sid",
|
|
159
|
+
"allow",
|
|
160
|
+
"deny",
|
|
161
|
+
"roi",
|
|
162
|
+
"unifiedbudget",
|
|
163
|
+
"filepath",
|
|
164
|
+
"rootdir",
|
|
165
|
+
"fp",
|
|
166
|
+
"email",
|
|
167
|
+
"username",
|
|
168
|
+
"password",
|
|
169
|
+
"token",
|
|
170
|
+
"secret",
|
|
171
|
+
"apikey",
|
|
172
|
+
"api_key",
|
|
173
|
+
"baseurl",
|
|
174
|
+
"base_url",
|
|
175
|
+
"endpoint",
|
|
176
|
+
"method",
|
|
177
|
+
"headers",
|
|
178
|
+
"queryparams",
|
|
179
|
+
"query_params",
|
|
180
|
+
"bodyparams",
|
|
181
|
+
"body_params",
|
|
182
|
+
"formdata",
|
|
183
|
+
"form_data",
|
|
184
|
+
"filename",
|
|
185
|
+
"file_name",
|
|
186
|
+
"filetype",
|
|
187
|
+
"file_type",
|
|
188
|
+
"filesize",
|
|
189
|
+
"file_size",
|
|
190
|
+
"filecontent",
|
|
191
|
+
"file_content",
|
|
192
|
+
"fileurl",
|
|
193
|
+
"file_url",
|
|
194
|
+
"fileid",
|
|
195
|
+
"file_id",
|
|
196
|
+
"filekey",
|
|
197
|
+
"file_key",
|
|
198
|
+
"filepath",
|
|
199
|
+
"file_path",
|
|
200
|
+
"filedir",
|
|
201
|
+
"file_dir",
|
|
202
|
+
"fileext",
|
|
203
|
+
"file_ext",
|
|
204
|
+
"filebase",
|
|
205
|
+
"file_base",
|
|
206
|
+
"filenamewithoutext",
|
|
207
|
+
"file_name_without_ext",
|
|
208
|
+
"filedirname",
|
|
209
|
+
"file_dirname",
|
|
210
|
+
"filebasename",
|
|
211
|
+
"file_basename",
|
|
212
|
+
"fileextname",
|
|
213
|
+
"file_extname",
|
|
214
|
+
"fileroot",
|
|
215
|
+
"file_root",
|
|
216
|
+
"filesep",
|
|
217
|
+
"file_sep",
|
|
218
|
+
"filejoin",
|
|
219
|
+
"file_join",
|
|
220
|
+
"fileresolve",
|
|
221
|
+
"file_resolve",
|
|
222
|
+
"filenormalize",
|
|
223
|
+
"file_normalize",
|
|
224
|
+
"exp",
|
|
225
|
+
"ctx",
|
|
226
|
+
"options",
|
|
227
|
+
"done",
|
|
228
|
+
"next",
|
|
229
|
+
"reject",
|
|
230
|
+
"resolve",
|
|
231
|
+
"error",
|
|
232
|
+
"err",
|
|
233
|
+
"req",
|
|
234
|
+
"res",
|
|
235
|
+
"event",
|
|
236
|
+
"payload",
|
|
237
|
+
"metadata",
|
|
238
|
+
"params",
|
|
239
|
+
"props",
|
|
240
|
+
"state",
|
|
241
|
+
"dispatch",
|
|
242
|
+
"action",
|
|
243
|
+
"config",
|
|
244
|
+
"directory",
|
|
245
|
+
"useroptions",
|
|
246
|
+
"resultslength",
|
|
247
|
+
"totalissues",
|
|
248
|
+
"totaltokencost",
|
|
249
|
+
"elapsedtime"
|
|
250
|
+
]);
|
|
251
|
+
|
|
252
|
+
// src/heuristics.ts
|
|
253
|
+
function getMissingParams(exp) {
|
|
254
|
+
if (exp.type !== "function" || !exp.parameters || !exp.documentation) {
|
|
255
|
+
return [];
|
|
256
|
+
}
|
|
257
|
+
const docContent = exp.documentation.content;
|
|
258
|
+
const params = exp.parameters;
|
|
259
|
+
return params.filter((p) => {
|
|
260
|
+
if (DESCRIPTIVE_PARAMS.has(p.toLowerCase())) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
const regex = new RegExp(`\\b${p}\\b`);
|
|
264
|
+
return !regex.test(docContent);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function isUndocumentedComplexity(exp) {
|
|
268
|
+
if (exp.documentation) return false;
|
|
269
|
+
if (!exp.loc) return false;
|
|
270
|
+
const lines = exp.loc.end.line - exp.loc.start.line;
|
|
271
|
+
return lines > 20;
|
|
272
|
+
}
|
|
273
|
+
function hasTemporalDrift(bodyModified, docModified) {
|
|
274
|
+
if (bodyModified <= 0 || docModified <= 0) return false;
|
|
275
|
+
const DRIFT_THRESHOLD_SECONDS = 24 * 60 * 60;
|
|
276
|
+
return bodyModified - docModified > DRIFT_THRESHOLD_SECONDS;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/analyzer.ts
|
|
35
280
|
async function analyzeDocDrift(options) {
|
|
36
281
|
const files = await (0, import_core.scanFiles)(options);
|
|
37
282
|
const issues = [];
|
|
38
283
|
let uncommentedExports = 0;
|
|
39
284
|
let totalExports = 0;
|
|
40
285
|
let outdatedComments = 0;
|
|
41
|
-
let
|
|
286
|
+
let undocumentedComplexityCount = 0;
|
|
42
287
|
let actualDrift = 0;
|
|
43
288
|
let processed = 0;
|
|
44
289
|
for (const file of files) {
|
|
@@ -67,33 +312,22 @@ async function analyzeDocDrift(options) {
|
|
|
67
312
|
totalExports++;
|
|
68
313
|
if (!exp.documentation) {
|
|
69
314
|
uncommentedExports++;
|
|
70
|
-
if (exp
|
|
71
|
-
const lines = exp.loc.end.line - exp.loc.start.line;
|
|
72
|
-
if (lines > 20) undocumentedComplexity++;
|
|
73
|
-
}
|
|
315
|
+
if (isUndocumentedComplexity(exp)) undocumentedComplexityCount++;
|
|
74
316
|
} else {
|
|
75
317
|
const doc = exp.documentation;
|
|
76
|
-
const
|
|
77
|
-
if (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
318
|
+
const missingParams = getMissingParams(exp);
|
|
319
|
+
if (missingParams.length > 0) {
|
|
320
|
+
outdatedComments++;
|
|
321
|
+
issues.push({
|
|
322
|
+
type: import_core.IssueType.DocDrift,
|
|
323
|
+
severity: import_core.Severity.Major,
|
|
324
|
+
message: `Documentation mismatch: function parameters (${missingParams.join(", ")}) are not mentioned in the docs.`,
|
|
325
|
+
location: { file, line: exp.loc?.start.line || 1 }
|
|
82
326
|
});
|
|
83
|
-
if (missingParams.length > 0) {
|
|
84
|
-
outdatedComments++;
|
|
85
|
-
issues.push({
|
|
86
|
-
type: import_core.IssueType.DocDrift,
|
|
87
|
-
severity: import_core.Severity.Major,
|
|
88
|
-
message: `Documentation mismatch: function parameters (${missingParams.join(", ")}) are not mentioned in the docs.`,
|
|
89
|
-
location: { file, line: exp.loc?.start.line || 1 }
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
327
|
}
|
|
93
328
|
if (exp.loc && doc.loc) {
|
|
94
|
-
if (!fileLineStamps)
|
|
329
|
+
if (!fileLineStamps)
|
|
95
330
|
fileLineStamps = (0, import_core.getFileCommitTimestamps)(file);
|
|
96
|
-
}
|
|
97
331
|
const bodyModified = (0, import_core.getLineRangeLastModifiedCached)(
|
|
98
332
|
fileLineStamps,
|
|
99
333
|
exp.loc.start.line,
|
|
@@ -104,17 +338,14 @@ async function analyzeDocDrift(options) {
|
|
|
104
338
|
doc.loc.start.line,
|
|
105
339
|
doc.loc.end.line
|
|
106
340
|
);
|
|
107
|
-
if (bodyModified
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
location: { file, line: doc.loc.start.line }
|
|
116
|
-
});
|
|
117
|
-
}
|
|
341
|
+
if (hasTemporalDrift(bodyModified, docModified)) {
|
|
342
|
+
actualDrift++;
|
|
343
|
+
issues.push({
|
|
344
|
+
type: import_core.IssueType.DocDrift,
|
|
345
|
+
severity: import_core.Severity.Major,
|
|
346
|
+
message: `Documentation drift: logic was modified on ${new Date(bodyModified * 1e3).toLocaleDateString()} but documentation was last updated on ${new Date(docModified * 1e3).toLocaleDateString()}.`,
|
|
347
|
+
location: { file, line: doc.loc.start.line }
|
|
348
|
+
});
|
|
118
349
|
}
|
|
119
350
|
}
|
|
120
351
|
}
|
|
@@ -129,7 +360,7 @@ async function analyzeDocDrift(options) {
|
|
|
129
360
|
uncommentedExports,
|
|
130
361
|
totalExports,
|
|
131
362
|
outdatedComments,
|
|
132
|
-
undocumentedComplexity,
|
|
363
|
+
undocumentedComplexity: undocumentedComplexityCount,
|
|
133
364
|
actualDrift
|
|
134
365
|
});
|
|
135
366
|
return {
|
|
@@ -144,7 +375,7 @@ async function analyzeDocDrift(options) {
|
|
|
144
375
|
uncommentedExports,
|
|
145
376
|
totalExports,
|
|
146
377
|
outdatedComments,
|
|
147
|
-
undocumentedComplexity,
|
|
378
|
+
undocumentedComplexity: undocumentedComplexityCount,
|
|
148
379
|
actualDrift
|
|
149
380
|
},
|
|
150
381
|
recommendations: riskResult.recommendations
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/doc-drift",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.16",
|
|
4
4
|
"description": "AI-Readiness: Documentation Drift Detection",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"commander": "^14.0.0",
|
|
11
11
|
"glob": "^13.0.0",
|
|
12
12
|
"picocolors": "^1.0.0",
|
|
13
|
-
"@aiready/core": "0.24.
|
|
13
|
+
"@aiready/core": "0.24.19"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^24.0.0",
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
"test:watch": "vitest",
|
|
34
34
|
"lint": "eslint src --ext .ts",
|
|
35
35
|
"type-check": "tsc --noEmit",
|
|
36
|
-
"format-check": "prettier --check . --ignore-path ../../.prettierignore"
|
|
36
|
+
"format-check": "prettier --check . --ignore-path ../../.prettierignore",
|
|
37
|
+
"format": "prettier --write . --ignore-path ../../.prettierignore",
|
|
38
|
+
"lint:fix": "eslint . --fix"
|
|
37
39
|
}
|
|
38
40
|
}
|
package/src/analyzer.ts
CHANGED
|
@@ -10,33 +10,27 @@ import {
|
|
|
10
10
|
} from '@aiready/core';
|
|
11
11
|
import type { DocDriftOptions, DocDriftReport, DocDriftIssue } from './types';
|
|
12
12
|
import { readFileSync } from 'fs';
|
|
13
|
+
import {
|
|
14
|
+
getMissingParams,
|
|
15
|
+
isUndocumentedComplexity,
|
|
16
|
+
hasTemporalDrift,
|
|
17
|
+
} from './heuristics';
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* Analyzes documentation drift across a set of files.
|
|
16
|
-
* This tool detects:
|
|
17
|
-
* 1. Missing documentation for complex functions/classes.
|
|
18
|
-
* 2. Signature mismatches (parameters not mentioned in docs).
|
|
19
|
-
* 3. Temporal drift (logic changed after documentation was last updated).
|
|
20
|
-
*
|
|
21
|
-
* @param options - Analysis configuration including include/exclude patterns and drift thresholds.
|
|
22
|
-
* @returns A comprehensive report with drift scores and specific issues.
|
|
23
21
|
*/
|
|
24
22
|
export async function analyzeDocDrift(
|
|
25
23
|
options: DocDriftOptions
|
|
26
24
|
): Promise<DocDriftReport> {
|
|
27
|
-
// Use core scanFiles which respects .gitignore recursively
|
|
28
25
|
const files = await scanFiles(options);
|
|
29
26
|
const issues: DocDriftIssue[] = [];
|
|
30
|
-
// const staleSeconds = staleMonths * 30 * 24 * 60 * 60; // Unused, removed
|
|
31
27
|
|
|
32
28
|
let uncommentedExports = 0;
|
|
33
29
|
let totalExports = 0;
|
|
34
30
|
let outdatedComments = 0;
|
|
35
|
-
let
|
|
31
|
+
let undocumentedComplexityCount = 0;
|
|
36
32
|
let actualDrift = 0;
|
|
37
33
|
|
|
38
|
-
// const now = Math.floor(Date.now() / 1000); // Unused, removed
|
|
39
|
-
|
|
40
34
|
let processed = 0;
|
|
41
35
|
for (const file of files) {
|
|
42
36
|
processed++;
|
|
@@ -59,79 +53,57 @@ export async function analyzeDocDrift(
|
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
try {
|
|
62
|
-
// Initialize parser (it's a singleton in core, but ensures WASM is loaded)
|
|
63
56
|
await parser.initialize();
|
|
64
57
|
const parseResult = parser.parse(code, file);
|
|
65
58
|
|
|
66
59
|
let fileLineStamps: Record<number, number> | undefined;
|
|
67
60
|
|
|
68
61
|
for (const exp of parseResult.exports) {
|
|
69
|
-
// Only analyze functions and classes for documentation drift
|
|
70
62
|
if (exp.type === 'function' || exp.type === 'class') {
|
|
71
63
|
totalExports++;
|
|
72
64
|
|
|
73
65
|
if (!exp.documentation) {
|
|
74
66
|
uncommentedExports++;
|
|
75
|
-
|
|
76
|
-
// Complexity check (heuristic based on line count if range available)
|
|
77
|
-
if (exp.loc) {
|
|
78
|
-
const lines = exp.loc.end.line - exp.loc.start.line;
|
|
79
|
-
if (lines > 20) undocumentedComplexity++;
|
|
80
|
-
}
|
|
67
|
+
if (isUndocumentedComplexity(exp)) undocumentedComplexityCount++;
|
|
81
68
|
} else {
|
|
82
69
|
const doc = exp.documentation;
|
|
83
|
-
const docContent = doc.content;
|
|
84
70
|
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
71
|
+
// Check for missing parameters in documentation
|
|
72
|
+
const missingParams = getMissingParams(exp);
|
|
73
|
+
if (missingParams.length > 0) {
|
|
74
|
+
outdatedComments++;
|
|
75
|
+
issues.push({
|
|
76
|
+
type: IssueType.DocDrift,
|
|
77
|
+
severity: Severity.Major,
|
|
78
|
+
message: `Documentation mismatch: function parameters (${missingParams.join(', ')}) are not mentioned in the docs.`,
|
|
79
|
+
location: { file, line: exp.loc?.start.line || 1 },
|
|
92
80
|
});
|
|
93
|
-
|
|
94
|
-
if (missingParams.length > 0) {
|
|
95
|
-
outdatedComments++;
|
|
96
|
-
issues.push({
|
|
97
|
-
type: IssueType.DocDrift,
|
|
98
|
-
severity: Severity.Major,
|
|
99
|
-
message: `Documentation mismatch: function parameters (${missingParams.join(', ')}) are not mentioned in the docs.`,
|
|
100
|
-
location: { file, line: exp.loc?.start.line || 1 },
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
81
|
}
|
|
104
82
|
|
|
105
|
-
//
|
|
83
|
+
// Check for temporal drift
|
|
106
84
|
if (exp.loc && doc.loc) {
|
|
107
|
-
if (!fileLineStamps)
|
|
85
|
+
if (!fileLineStamps)
|
|
108
86
|
fileLineStamps = getFileCommitTimestamps(file);
|
|
109
|
-
}
|
|
110
87
|
|
|
111
88
|
const bodyModified = getLineRangeLastModifiedCached(
|
|
112
89
|
fileLineStamps,
|
|
113
90
|
exp.loc.start.line,
|
|
114
91
|
exp.loc.end.line
|
|
115
92
|
);
|
|
116
|
-
|
|
117
93
|
const docModified = getLineRangeLastModifiedCached(
|
|
118
94
|
fileLineStamps,
|
|
119
95
|
doc.loc.start.line,
|
|
120
96
|
doc.loc.end.line
|
|
121
97
|
);
|
|
122
98
|
|
|
123
|
-
if (bodyModified
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
message: `Documentation drift: logic was modified on ${new Date(bodyModified * 1000).toLocaleDateString()} but documentation was last updated on ${new Date(docModified * 1000).toLocaleDateString()}.`,
|
|
132
|
-
location: { file, line: doc.loc.start.line },
|
|
133
|
-
});
|
|
134
|
-
}
|
|
99
|
+
if (hasTemporalDrift(bodyModified, docModified)) {
|
|
100
|
+
actualDrift++;
|
|
101
|
+
issues.push({
|
|
102
|
+
type: IssueType.DocDrift,
|
|
103
|
+
severity: Severity.Major,
|
|
104
|
+
message: `Documentation drift: logic was modified on ${new Date(bodyModified * 1000).toLocaleDateString()} but documentation was last updated on ${new Date(docModified * 1000).toLocaleDateString()}.`,
|
|
105
|
+
location: { file, line: doc.loc.start.line },
|
|
106
|
+
});
|
|
135
107
|
}
|
|
136
108
|
}
|
|
137
109
|
}
|
|
@@ -147,7 +119,7 @@ export async function analyzeDocDrift(
|
|
|
147
119
|
uncommentedExports,
|
|
148
120
|
totalExports,
|
|
149
121
|
outdatedComments,
|
|
150
|
-
undocumentedComplexity,
|
|
122
|
+
undocumentedComplexity: undocumentedComplexityCount,
|
|
151
123
|
actualDrift,
|
|
152
124
|
});
|
|
153
125
|
|
|
@@ -163,7 +135,7 @@ export async function analyzeDocDrift(
|
|
|
163
135
|
uncommentedExports,
|
|
164
136
|
totalExports,
|
|
165
137
|
outdatedComments,
|
|
166
|
-
undocumentedComplexity,
|
|
138
|
+
undocumentedComplexity: undocumentedComplexityCount,
|
|
167
139
|
actualDrift,
|
|
168
140
|
},
|
|
169
141
|
recommendations: riskResult.recommendations,
|