@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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.14.13 build /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.14.15 build /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > tsup src/index.ts src/cli.ts --format cjs,esm --dts
5
5
 
6
6
  CLI Building entry: src/cli.ts, src/index.ts
@@ -9,16 +9,16 @@
9
9
  CLI Target: es2020
10
10
  CJS Build start
11
11
  ESM Build start
12
- CJS dist/cli.js 6.71 KB
13
- CJS dist/index.js 6.04 KB
14
- CJS ⚡️ Build success in 101ms
15
- ESM dist/index.mjs 989.00 B
12
+ CJS dist/index.js 9.11 KB
13
+ CJS dist/cli.js 9.79 KB
14
+ CJS ⚡️ Build success in 286ms
16
15
  ESM dist/cli.mjs 1.07 KB
17
- ESM dist/chunk-GZDN7B4K.mjs 4.40 KB
18
- ESM ⚡️ Build success in 105ms
19
- DTS Build start
20
- DTS ⚡️ Build success in 7374ms
21
- DTS dist/cli.d.ts 108.00 B
22
- DTS dist/index.d.ts 2.48 KB
23
- DTS dist/cli.d.mts 108.00 B
24
- DTS dist/index.d.mts 2.48 KB
16
+ ESM dist/index.mjs 989.00 B
17
+ ESM dist/chunk-IQBAXGOK.mjs 7.48 KB
18
+ ESM ⚡️ Build success in 287ms
19
+ DTS Build start
20
+ DTS ⚡️ Build success in 3510ms
21
+ DTS dist/cli.d.ts 108.00 B
22
+ DTS dist/index.d.ts 2.09 KB
23
+ DTS dist/cli.d.mts 108.00 B
24
+ DTS dist/index.d.mts 2.09 KB
@@ -1,7 +1,7 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.14.13 format-check /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.14.15 format-check /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > prettier --check . --ignore-path ../../.prettierignore
5
5
 
6
6
  Checking formatting...
7
- package.jsonREADME.mdsrc/__tests__/analyzer.test.tssrc/__tests__/provider.test.tssrc/__tests__/scoring.test.tssrc/analyzer.tssrc/cli.tssrc/index.tssrc/provider.tssrc/scoring.tssrc/types.tstsconfig.jsonAll matched files use Prettier code style!
7
+ package.jsonREADME.mdsrc/__tests__/analyzer.test.tssrc/__tests__/provider.test.tssrc/__tests__/scoring.test.tssrc/analyzer.tssrc/cli.tssrc/constants.tssrc/heuristics.tssrc/index.tssrc/provider.tssrc/scoring.tssrc/types.tstsconfig.jsonAll matched files use Prettier code style!
@@ -0,0 +1,2 @@
1
+
2
+ 
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.14.13 lint /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.14.15 lint /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > eslint src --ext .ts
5
5
 
@@ -1,19 +1,51 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.14.13 test /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.14.15 test /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/doc-drift
8
8
 
9
+ [?2026h
10
+  ❯ src/__tests__/analyzer.test.ts [queued]
11
+
12
+  Test Files 0 passed (3)
13
+  Tests 0 passed (0)
14
+  Start at 23:35:29
15
+  Duration 213ms
16
+ [?2026l[?2026h
17
+  ❯ src/__tests__/analyzer.test.ts [queued]
18
+  ❯ src/__tests__/provider.test.ts [queued]
19
+  ❯ src/__tests__/scoring.test.ts [queued]
20
+
21
+  Test Files 0 passed (3)
22
+  Tests 0 passed (0)
23
+  Start at 23:35:29
24
+  Duration 1.01s
25
+ [?2026l[?2026h
26
+  ❯ src/__tests__/analyzer.test.ts [queued]
27
+  ❯ src/__tests__/provider.test.ts [queued]
28
+  ❯ src/__tests__/scoring.test.ts 0/2
29
+
30
+  Test Files 0 passed (3)
31
+  Tests 0 passed (2)
32
+  Start at 23:35:29
33
+  Duration 1.31s
34
+ [?2026l[?2026h ✓ src/__tests__/scoring.test.ts (2 tests) 2ms
9
35
  ✓ src/__tests__/provider.test.ts (2 tests) 5ms
10
- ✓ src/__tests__/scoring.test.ts (2 tests) 2ms
11
- ✓ src/__tests__/analyzer.test.ts (1 test) 310ms
12
- ✓ detects missing param documentation and uncommented complexity  304ms
36
+
37
+
38
+  ❯ src/__tests__/analyzer.test.ts 1/1
39
+
40
+  Test Files 2 passed (3)
41
+  Tests 5 passed (5)
42
+  Start at 23:35:29
43
+  Duration 1.41s
44
+ [?2026l ✓ src/__tests__/analyzer.test.ts (1 test) 40ms
13
45
 
14
46
   Test Files  3 passed (3)
15
47
   Tests  5 passed (5)
16
-  Start at  20:52:15
17
-  Duration  6.39s (transform 2.68s, setup 0ms, import 14.19s, tests 316ms, environment 0ms)
48
+  Start at  23:35:29
49
+  Duration  1.51s (transform 823ms, setup 0ms, import 3.20s, tests 47ms, environment 0ms)
18
50
 
19
51
  [?25h
@@ -1,5 +1,5 @@
1
1
 
2
2
  
3
- > @aiready/doc-drift@0.14.13 type-check /Users/pengcao/projects/aiready/packages/doc-drift
3
+ > @aiready/doc-drift@0.14.15 type-check /Users/pengcao/projects/aiready/packages/doc-drift
4
4
  > tsc --noEmit
5
5
 
@@ -0,0 +1,347 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/analyzer.ts
9
+ import {
10
+ scanFiles,
11
+ calculateDocDrift,
12
+ getFileCommitTimestamps,
13
+ getLineRangeLastModifiedCached,
14
+ Severity,
15
+ IssueType,
16
+ emitProgress,
17
+ getParser
18
+ } from "@aiready/core";
19
+ import { readFileSync } from "fs";
20
+
21
+ // src/constants.ts
22
+ var DESCRIPTIVE_PARAMS = /* @__PURE__ */ new Set([
23
+ "data",
24
+ "item",
25
+ "value",
26
+ "key",
27
+ "index",
28
+ "id",
29
+ "name",
30
+ "type",
31
+ "config",
32
+ "options",
33
+ "params",
34
+ "args",
35
+ "input",
36
+ "output",
37
+ "result",
38
+ "response",
39
+ "request",
40
+ "callback",
41
+ "handler",
42
+ "event",
43
+ "error",
44
+ "message",
45
+ "context",
46
+ "file",
47
+ "path",
48
+ "url",
49
+ "source",
50
+ "target",
51
+ "content",
52
+ "body",
53
+ "payload",
54
+ "user",
55
+ "userid",
56
+ "user_id",
57
+ "starttime",
58
+ "endtime",
59
+ "duration",
60
+ "timeout",
61
+ "retry",
62
+ "count",
63
+ "limit",
64
+ "offset",
65
+ "page",
66
+ "size",
67
+ "length",
68
+ "width",
69
+ "height",
70
+ "depth",
71
+ "color",
72
+ "background",
73
+ "foreground",
74
+ "border",
75
+ "margin",
76
+ "padding",
77
+ "position",
78
+ "top",
79
+ "bottom",
80
+ "left",
81
+ "right",
82
+ "center",
83
+ "start",
84
+ "end",
85
+ "begin",
86
+ "finish",
87
+ "complete",
88
+ "pending",
89
+ "active",
90
+ "inactive",
91
+ "enabled",
92
+ "disabled",
93
+ "visible",
94
+ "hidden",
95
+ "open",
96
+ "closed",
97
+ "locked",
98
+ "unlocked",
99
+ "read",
100
+ "write",
101
+ "append",
102
+ "prepend",
103
+ "insert",
104
+ "replace",
105
+ "merge",
106
+ "split",
107
+ "join",
108
+ "filter",
109
+ "map",
110
+ "reduce",
111
+ "find",
112
+ "sort",
113
+ "reverse",
114
+ "unique",
115
+ "flatten",
116
+ "compact",
117
+ "chunk",
118
+ "zip",
119
+ "unzip",
120
+ "completed",
121
+ "failed",
122
+ "healthy",
123
+ "high",
124
+ "medium",
125
+ "low",
126
+ "running",
127
+ "stopped",
128
+ "title",
129
+ "subtitle",
130
+ "label",
131
+ "description",
132
+ "version",
133
+ "timestamp",
134
+ "date",
135
+ "time",
136
+ "status",
137
+ "mode",
138
+ "action",
139
+ "effect",
140
+ "resource",
141
+ "principal",
142
+ "statement",
143
+ "sid",
144
+ "allow",
145
+ "deny",
146
+ "roi",
147
+ "unifiedbudget",
148
+ "filepath",
149
+ "rootdir",
150
+ "fp",
151
+ "email",
152
+ "username",
153
+ "password",
154
+ "token",
155
+ "secret",
156
+ "apikey",
157
+ "api_key",
158
+ "baseurl",
159
+ "base_url",
160
+ "endpoint",
161
+ "method",
162
+ "headers",
163
+ "queryparams",
164
+ "query_params",
165
+ "bodyparams",
166
+ "body_params",
167
+ "formdata",
168
+ "form_data",
169
+ "filename",
170
+ "file_name",
171
+ "filetype",
172
+ "file_type",
173
+ "filesize",
174
+ "file_size",
175
+ "filecontent",
176
+ "file_content",
177
+ "fileurl",
178
+ "file_url",
179
+ "fileid",
180
+ "file_id",
181
+ "filekey",
182
+ "file_key",
183
+ "filepath",
184
+ "file_path",
185
+ "filedir",
186
+ "file_dir",
187
+ "fileext",
188
+ "file_ext",
189
+ "filebase",
190
+ "file_base",
191
+ "filenamewithoutext",
192
+ "file_name_without_ext",
193
+ "filedirname",
194
+ "file_dirname",
195
+ "filebasename",
196
+ "file_basename",
197
+ "fileextname",
198
+ "file_extname",
199
+ "fileroot",
200
+ "file_root",
201
+ "filesep",
202
+ "file_sep",
203
+ "filejoin",
204
+ "file_join",
205
+ "fileresolve",
206
+ "file_resolve",
207
+ "filenormalize",
208
+ "file_normalize"
209
+ ]);
210
+
211
+ // src/heuristics.ts
212
+ function getMissingParams(exp) {
213
+ if (exp.type !== "function" || !exp.parameters || !exp.documentation) {
214
+ return [];
215
+ }
216
+ const docContent = exp.documentation.content;
217
+ const params = exp.parameters;
218
+ return params.filter((p) => {
219
+ if (DESCRIPTIVE_PARAMS.has(p.toLowerCase())) {
220
+ return false;
221
+ }
222
+ const regex = new RegExp(`\\b${p}\\b`);
223
+ return !regex.test(docContent);
224
+ });
225
+ }
226
+ function isUndocumentedComplexity(exp) {
227
+ if (exp.documentation) return false;
228
+ if (!exp.loc) return false;
229
+ const lines = exp.loc.end.line - exp.loc.start.line;
230
+ return lines > 20;
231
+ }
232
+ function hasTemporalDrift(bodyModified, docModified) {
233
+ if (bodyModified <= 0 || docModified <= 0) return false;
234
+ const DRIFT_THRESHOLD_SECONDS = 24 * 60 * 60;
235
+ return bodyModified - docModified > DRIFT_THRESHOLD_SECONDS;
236
+ }
237
+
238
+ // src/analyzer.ts
239
+ async function analyzeDocDrift(options) {
240
+ const files = await scanFiles(options);
241
+ const issues = [];
242
+ let uncommentedExports = 0;
243
+ let totalExports = 0;
244
+ let outdatedComments = 0;
245
+ let undocumentedComplexityCount = 0;
246
+ let actualDrift = 0;
247
+ let processed = 0;
248
+ for (const file of files) {
249
+ processed++;
250
+ emitProgress(
251
+ processed,
252
+ files.length,
253
+ "doc-drift",
254
+ "analyzing files",
255
+ options.onProgress
256
+ );
257
+ const parser = await getParser(file);
258
+ if (!parser) continue;
259
+ let code;
260
+ try {
261
+ code = readFileSync(file, "utf-8");
262
+ } catch {
263
+ continue;
264
+ }
265
+ try {
266
+ await parser.initialize();
267
+ const parseResult = parser.parse(code, file);
268
+ let fileLineStamps;
269
+ for (const exp of parseResult.exports) {
270
+ if (exp.type === "function" || exp.type === "class") {
271
+ totalExports++;
272
+ if (!exp.documentation) {
273
+ uncommentedExports++;
274
+ if (isUndocumentedComplexity(exp)) undocumentedComplexityCount++;
275
+ } else {
276
+ const doc = exp.documentation;
277
+ const missingParams = getMissingParams(exp);
278
+ if (missingParams.length > 0) {
279
+ outdatedComments++;
280
+ issues.push({
281
+ type: IssueType.DocDrift,
282
+ severity: Severity.Major,
283
+ message: `Documentation mismatch: function parameters (${missingParams.join(", ")}) are not mentioned in the docs.`,
284
+ location: { file, line: exp.loc?.start.line || 1 }
285
+ });
286
+ }
287
+ if (exp.loc && doc.loc) {
288
+ if (!fileLineStamps)
289
+ fileLineStamps = getFileCommitTimestamps(file);
290
+ const bodyModified = getLineRangeLastModifiedCached(
291
+ fileLineStamps,
292
+ exp.loc.start.line,
293
+ exp.loc.end.line
294
+ );
295
+ const docModified = getLineRangeLastModifiedCached(
296
+ fileLineStamps,
297
+ doc.loc.start.line,
298
+ doc.loc.end.line
299
+ );
300
+ if (hasTemporalDrift(bodyModified, docModified)) {
301
+ actualDrift++;
302
+ issues.push({
303
+ type: IssueType.DocDrift,
304
+ severity: Severity.Major,
305
+ message: `Documentation drift: logic was modified on ${new Date(bodyModified * 1e3).toLocaleDateString()} but documentation was last updated on ${new Date(docModified * 1e3).toLocaleDateString()}.`,
306
+ location: { file, line: doc.loc.start.line }
307
+ });
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+ } catch (error) {
314
+ console.warn(`Doc-drift: Failed to parse ${file}: ${error}`);
315
+ continue;
316
+ }
317
+ }
318
+ const riskResult = calculateDocDrift({
319
+ uncommentedExports,
320
+ totalExports,
321
+ outdatedComments,
322
+ undocumentedComplexity: undocumentedComplexityCount,
323
+ actualDrift
324
+ });
325
+ return {
326
+ summary: {
327
+ filesAnalyzed: files.length,
328
+ functionsAnalyzed: totalExports,
329
+ score: riskResult.score,
330
+ rating: riskResult.rating
331
+ },
332
+ issues,
333
+ rawData: {
334
+ uncommentedExports,
335
+ totalExports,
336
+ outdatedComments,
337
+ undocumentedComplexity: undocumentedComplexityCount,
338
+ actualDrift
339
+ },
340
+ recommendations: riskResult.recommendations
341
+ };
342
+ }
343
+
344
+ export {
345
+ __require,
346
+ analyzeDocDrift
347
+ };