jsdoczoom 0.4.11 → 0.4.13

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.
Files changed (61) hide show
  1. package/dist/{src/drilldown.js → drilldown.js} +9 -6
  2. package/package.json +2 -2
  3. package/dist/test/barrel.test.js +0 -77
  4. package/dist/test/cache.test.js +0 -222
  5. package/dist/test/cli.test.js +0 -479
  6. package/dist/test/drilldown-barrel.test.js +0 -383
  7. package/dist/test/drilldown.test.js +0 -469
  8. package/dist/test/errors.test.js +0 -26
  9. package/dist/test/eslint-engine.test.js +0 -130
  10. package/dist/test/eslint-plugin.test.js +0 -291
  11. package/dist/test/file-discovery.test.js +0 -72
  12. package/dist/test/jsdoc-parser.test.js +0 -353
  13. package/dist/test/lint.test.js +0 -413
  14. package/dist/test/selector.test.js +0 -93
  15. package/dist/test/type-declarations.test.js +0 -321
  16. package/dist/test/validate.test.js +0 -361
  17. package/types/test/barrel.test.d.ts +0 -1
  18. package/types/test/cache.test.d.ts +0 -8
  19. package/types/test/cli.test.d.ts +0 -1
  20. package/types/test/drilldown-barrel.test.d.ts +0 -1
  21. package/types/test/drilldown.test.d.ts +0 -1
  22. package/types/test/errors.test.d.ts +0 -1
  23. package/types/test/eslint-engine.test.d.ts +0 -6
  24. package/types/test/eslint-plugin.test.d.ts +0 -1
  25. package/types/test/file-discovery.test.d.ts +0 -1
  26. package/types/test/jsdoc-parser.test.d.ts +0 -1
  27. package/types/test/lint.test.d.ts +0 -9
  28. package/types/test/selector.test.d.ts +0 -1
  29. package/types/test/type-declarations.test.d.ts +0 -1
  30. package/types/test/validate.test.d.ts +0 -1
  31. /package/dist/{src/barrel.js → barrel.js} +0 -0
  32. /package/dist/{src/cache.js → cache.js} +0 -0
  33. /package/dist/{src/cli.js → cli.js} +0 -0
  34. /package/dist/{src/errors.js → errors.js} +0 -0
  35. /package/dist/{src/eslint-engine.js → eslint-engine.js} +0 -0
  36. /package/dist/{src/eslint-plugin.js → eslint-plugin.js} +0 -0
  37. /package/dist/{src/file-discovery.js → file-discovery.js} +0 -0
  38. /package/dist/{src/index.js → index.js} +0 -0
  39. /package/dist/{src/jsdoc-parser.js → jsdoc-parser.js} +0 -0
  40. /package/dist/{src/lint.js → lint.js} +0 -0
  41. /package/dist/{src/selector.js → selector.js} +0 -0
  42. /package/dist/{src/skill-text.js → skill-text.js} +0 -0
  43. /package/dist/{src/type-declarations.js → type-declarations.js} +0 -0
  44. /package/dist/{src/types.js → types.js} +0 -0
  45. /package/dist/{src/validate.js → validate.js} +0 -0
  46. /package/types/{src/barrel.d.ts → barrel.d.ts} +0 -0
  47. /package/types/{src/cache.d.ts → cache.d.ts} +0 -0
  48. /package/types/{src/cli.d.ts → cli.d.ts} +0 -0
  49. /package/types/{src/drilldown.d.ts → drilldown.d.ts} +0 -0
  50. /package/types/{src/errors.d.ts → errors.d.ts} +0 -0
  51. /package/types/{src/eslint-engine.d.ts → eslint-engine.d.ts} +0 -0
  52. /package/types/{src/eslint-plugin.d.ts → eslint-plugin.d.ts} +0 -0
  53. /package/types/{src/file-discovery.d.ts → file-discovery.d.ts} +0 -0
  54. /package/types/{src/index.d.ts → index.d.ts} +0 -0
  55. /package/types/{src/jsdoc-parser.d.ts → jsdoc-parser.d.ts} +0 -0
  56. /package/types/{src/lint.d.ts → lint.d.ts} +0 -0
  57. /package/types/{src/selector.d.ts → selector.d.ts} +0 -0
  58. /package/types/{src/skill-text.d.ts → skill-text.d.ts} +0 -0
  59. /package/types/{src/type-declarations.d.ts → type-declarations.d.ts} +0 -0
  60. /package/types/{src/types.d.ts → types.d.ts} +0 -0
  61. /package/types/{src/validate.d.ts → validate.d.ts} +0 -0
@@ -1,383 +0,0 @@
1
- import { dirname, resolve } from "node:path";
2
- import { fileURLToPath } from "node:url";
3
- import { describe, expect, it } from "vitest";
4
- import { drilldown } from "../src/drilldown.js";
5
-
6
- /**
7
- * Verifies barrel gating behavior in glob mode: barrels with summaries
8
- * gate children at depths 1 and 2, transition at depth 3 revealing children,
9
- * and barrels without summaries pass through as regular files. Covers nested
10
- * barrels, zero-child barrels, null-skip at barrel L2, and alphabetical ordering.
11
- *
12
- * @summary Tests for barrel gating and transition behavior in drilldown glob mode
13
- */
14
- const __dirname = dirname(fileURLToPath(import.meta.url));
15
- const fixturesDir = resolve(__dirname, "fixtures");
16
- /** Cache disabled for test isolation. */
17
- const NO_CACHE = { enabled: false, directory: "" };
18
- function globSelector(pattern, depth) {
19
- return { type: "glob", pattern, depth };
20
- }
21
- function pathSelector(pattern, depth) {
22
- return { type: "path", pattern, depth };
23
- }
24
- function isOutputItem(entry) {
25
- return "text" in entry;
26
- }
27
- function hasNextId(entry) {
28
- return "next_id" in entry;
29
- }
30
- /** Extract the key (next_id or id) from an entry. */
31
- function entryKey(entry) {
32
- if ("next_id" in entry) return entry.next_id;
33
- return entry.id;
34
- }
35
- function pathFromEntry(entry) {
36
- const key = entryKey(entry);
37
- const atIndex = key.lastIndexOf("@");
38
- return atIndex === -1 ? key : key.substring(0, atIndex);
39
- }
40
- describe("drilldown with barrels", () => {
41
- // barrel-basic has:
42
- // index.ts with 1 @summary + description: summary="Barrel overview", description="Basic barrel module."
43
- // helper.ts with 1 @summary + description: summary="Helper overview", description="Helper utilities."
44
- // utils.ts with 1 @summary + description: summary="Utils overview", description="Utility functions."
45
- it("glob access returns barrel summaries first", async () => {
46
- const basicDir = resolve(fixturesDir, "barrel-basic");
47
- const results = await drilldown(
48
- globSelector("**/*.ts", 1),
49
- basicDir,
50
- true,
51
- 100,
52
- NO_CACHE,
53
- );
54
- // At depth 1, barrel has summaries so it gates children.
55
- // Only the barrel's own L1 summary should appear.
56
- expect(results.items).toHaveLength(1);
57
- const entry = results.items[0];
58
- expect(isOutputItem(entry)).toBe(true);
59
- expect(hasNextId(entry)).toBe(true);
60
- if (hasNextId(entry)) {
61
- expect(pathFromEntry(entry)).toBe(".");
62
- expect(entry.text).toBe("Barrel overview");
63
- expect(entry.children).toBeDefined();
64
- expect(entry.children).toContain("helper.ts");
65
- expect(entry.children).toContain("utils.ts");
66
- }
67
- });
68
- it("glob drill-down reveals children after barrel levels exhausted", async () => {
69
- const basicDir = resolve(fixturesDir, "barrel-basic");
70
- // barrel-basic/index.ts has @summary + description → gates for 2 depths
71
- // At depth 3, barrel transitions. Children appear at depth 3-2=1.
72
- const results = await drilldown(
73
- globSelector("**/*.ts", 3),
74
- basicDir,
75
- true,
76
- 100,
77
- NO_CACHE,
78
- );
79
- // Children: helper.ts and utils.ts — each at their L1
80
- const paths = results.items.map((r) => pathFromEntry(r));
81
- expect(paths).toContain("helper.ts");
82
- expect(paths).toContain("utils.ts");
83
- });
84
- it("barrel itself absent from output at transition depth", async () => {
85
- const basicDir = resolve(fixturesDir, "barrel-basic");
86
- // At depth 3, barrel transitions
87
- const results = await drilldown(
88
- globSelector("**/*.ts", 3),
89
- basicDir,
90
- true,
91
- 100,
92
- NO_CACHE,
93
- );
94
- const paths = results.items.map((r) => pathFromEntry(r));
95
- expect(paths).not.toContain(".");
96
- });
97
- it("children appear at their shallowest summary level", async () => {
98
- const basicDir = resolve(fixturesDir, "barrel-basic");
99
- // barrel gates for 2 depths. At depth 3, children appear at depth 1.
100
- const results = await drilldown(
101
- globSelector("**/*.ts", 3),
102
- basicDir,
103
- true,
104
- 100,
105
- NO_CACHE,
106
- );
107
- const helperEntry = results.items.find(
108
- (r) => hasNextId(r) && r.next_id.startsWith("helper.ts@"),
109
- );
110
- expect(helperEntry).toBeDefined();
111
- if (helperEntry && hasNextId(helperEntry)) {
112
- expect(helperEntry.next_id).toBe("helper.ts@2");
113
- expect(helperEntry.text).toBe("Helper overview");
114
- }
115
- const utilsEntry = results.items.find(
116
- (r) => hasNextId(r) && r.next_id.startsWith("utils.ts@"),
117
- );
118
- expect(utilsEntry).toBeDefined();
119
- if (utilsEntry && hasNextId(utilsEntry)) {
120
- expect(utilsEntry.next_id).toBe("utils.ts@2");
121
- expect(utilsEntry.text).toBe("Utils overview");
122
- }
123
- });
124
- it("direct path access follows leaf rules (no gating)", async () => {
125
- const basicDir = resolve(fixturesDir, "barrel-basic");
126
- // Access the barrel directly via path — should follow normal leaf rules
127
- // Barrel id uses directory path instead of index.ts
128
- const results = await drilldown(
129
- pathSelector("index.ts", 1),
130
- basicDir,
131
- true,
132
- 100,
133
- NO_CACHE,
134
- );
135
- expect(results.items).toHaveLength(1);
136
- const entry = results.items[0];
137
- expect(isOutputItem(entry)).toBe(true);
138
- expect(hasNextId(entry)).toBe(true);
139
- if (hasNextId(entry)) {
140
- expect(pathFromEntry(entry)).toBe(".");
141
- expect(entry.next_id).toBe(".@2");
142
- expect(entry.text).toBe("Barrel overview");
143
- }
144
- });
145
- it("barrel with 0 summaries — barrel and children both appear in glob results", async () => {
146
- const zeroSumDir = resolve(fixturesDir, "barrel-zero-summaries");
147
- // index.ts has no summaries, so it's not a gating tree node.
148
- // Both the barrel and child.ts appear directly.
149
- const results = await drilldown(
150
- globSelector("**/*.ts", 1),
151
- zeroSumDir,
152
- true,
153
- 100,
154
- NO_CACHE,
155
- );
156
- const paths = results.items.map((r) => pathFromEntry(r));
157
- expect(paths).toContain("child.ts");
158
- // The barrel itself appears as a regular file (no gating), id uses directory
159
- expect(paths).toContain(".");
160
- });
161
- it("barrel with summary gates for two depths then reveals children", async () => {
162
- const rootDir = resolve(fixturesDir, "barrel-root");
163
- // barrel-root/index.ts has 1 @summary + description
164
- // At depth 1, barrel gates: only barrel summary shown
165
- const results1 = await drilldown(
166
- globSelector("**/*.ts", 1),
167
- rootDir,
168
- true,
169
- 100,
170
- NO_CACHE,
171
- );
172
- const paths1 = results1.items.map((r) => pathFromEntry(r));
173
- expect(paths1).toContain(".");
174
- expect(paths1).not.toContain("sibling.ts");
175
- const barrelEntry1 = results1.items.find(
176
- (r) => hasNextId(r) && pathFromEntry(r) === ".",
177
- );
178
- expect(barrelEntry1).toBeDefined();
179
- if (barrelEntry1 && hasNextId(barrelEntry1)) {
180
- expect(barrelEntry1.children).toBeDefined();
181
- expect(barrelEntry1.children).toContain("sibling.ts");
182
- }
183
- // At depth 2, barrel still gates: barrel description shown
184
- const results2 = await drilldown(
185
- globSelector("**/*.ts", 2),
186
- rootDir,
187
- true,
188
- 100,
189
- NO_CACHE,
190
- );
191
- const paths2 = results2.items.map((r) => pathFromEntry(r));
192
- expect(paths2).toContain(".");
193
- expect(paths2).not.toContain("sibling.ts");
194
- const barrelEntry = results2.items.find(
195
- (r) => hasNextId(r) && r.next_id.startsWith(".@"),
196
- );
197
- expect(barrelEntry).toBeDefined();
198
- if (barrelEntry && hasNextId(barrelEntry)) {
199
- expect(barrelEntry.next_id).toBe(".@3");
200
- expect(barrelEntry.text).toBe("Root barrel.");
201
- expect(barrelEntry.children).toBeDefined();
202
- expect(barrelEntry.children).toContain("sibling.ts");
203
- }
204
- // At depth 3, barrel transitions: children appear
205
- const results3 = await drilldown(
206
- globSelector("**/*.ts", 3),
207
- rootDir,
208
- true,
209
- 100,
210
- NO_CACHE,
211
- );
212
- const paths3 = results3.items.map((r) => pathFromEntry(r));
213
- expect(paths3).not.toContain(".");
214
- expect(paths3).toContain("sibling.ts");
215
- expect(paths3).toContain("nested");
216
- });
217
- it("barrel with zero children returns empty items at transition", async () => {
218
- const zeroChildDir = resolve(fixturesDir, "barrel-zero-children");
219
- // barrel-zero-children/index.ts has 1 @summary + description
220
- // At depth 1, the barrel summary is shown
221
- const results1 = await drilldown(
222
- globSelector("**/*.ts", 1),
223
- zeroChildDir,
224
- true,
225
- 100,
226
- NO_CACHE,
227
- );
228
- expect(results1.items).toHaveLength(1);
229
- const entry1 = results1.items[0];
230
- if (entry1 && hasNextId(entry1)) {
231
- expect(entry1.children).toEqual([]);
232
- }
233
- // At depth 2, barrel still gates: barrel description shown
234
- const results2 = await drilldown(
235
- globSelector("**/*.ts", 2),
236
- zeroChildDir,
237
- true,
238
- 100,
239
- NO_CACHE,
240
- );
241
- expect(results2.items).toHaveLength(1);
242
- const barrelEntry = results2.items[0];
243
- if (barrelEntry && hasNextId(barrelEntry)) {
244
- expect(barrelEntry.next_id).toBe(".@3");
245
- expect(barrelEntry.text).toBe("Lonely barrel.");
246
- expect(barrelEntry.children).toEqual([]);
247
- }
248
- // At depth 3 (transition), barrel disappears and there are no children
249
- const results3 = await drilldown(
250
- globSelector("**/*.ts", 3),
251
- zeroChildDir,
252
- true,
253
- 100,
254
- NO_CACHE,
255
- );
256
- expect(results3.items).toHaveLength(0);
257
- });
258
- it("nested barrel child appears as regular item with directory id (when revealed)", async () => {
259
- const nestedDir = resolve(fixturesDir, "barrel-nested");
260
- // barrel-nested/index.ts has 1 @summary + description
261
- // At depth 3, parent barrel transitions. Children: leaf.ts, sub/index.ts
262
- // sub/index.ts is itself a barrel but appears as a regular item at this level
263
- const results = await drilldown(
264
- globSelector("**/*.ts", 3),
265
- nestedDir,
266
- true,
267
- 100,
268
- NO_CACHE,
269
- );
270
- const subBarrel = results.items.find(
271
- (r) => hasNextId(r) && r.next_id.startsWith("sub@"),
272
- );
273
- expect(subBarrel).toBeDefined();
274
- if (subBarrel && hasNextId(subBarrel)) {
275
- // The sub-barrel at depth 1 shows its own summary, id uses directory
276
- expect(subBarrel.next_id).toBe("sub@2");
277
- expect(subBarrel.text).toBe("Sub overview");
278
- }
279
- });
280
- it("children ordered alphabetically", async () => {
281
- const basicDir = resolve(fixturesDir, "barrel-basic");
282
- // At barrel transition depth (3), children appear sorted
283
- const results = await drilldown(
284
- globSelector("**/*.ts", 3),
285
- basicDir,
286
- true,
287
- 100,
288
- NO_CACHE,
289
- );
290
- const paths = results.items.map((r) => pathFromEntry(r));
291
- const sorted = [...paths].sort();
292
- expect(paths).toEqual(sorted);
293
- });
294
- it("root-level barrel gates sibling files and child barrels", async () => {
295
- const rootDir = resolve(fixturesDir, "barrel-root");
296
- // At depth 1, only barrel summary shown
297
- const results = await drilldown(
298
- globSelector("**/*.ts", 1),
299
- rootDir,
300
- true,
301
- 100,
302
- NO_CACHE,
303
- );
304
- // Only the root barrel should appear
305
- expect(results.items).toHaveLength(1);
306
- const entry = results.items[0];
307
- expect(isOutputItem(entry)).toBe(true);
308
- if (isOutputItem(entry) && hasNextId(entry)) {
309
- expect(pathFromEntry(entry)).toBe(".");
310
- expect(entry.text).toBe("Root overview");
311
- expect(entry.children).toBeDefined();
312
- expect(entry.children).toContain("sibling.ts");
313
- }
314
- // At transition depth (3), sibling and child barrel appear
315
- const results3 = await drilldown(
316
- globSelector("**/*.ts", 3),
317
- rootDir,
318
- true,
319
- 100,
320
- NO_CACHE,
321
- );
322
- const paths3 = results3.items.map((r) => pathFromEntry(r));
323
- expect(paths3).toContain("sibling.ts");
324
- expect(paths3).toContain("nested");
325
- expect(paths3).not.toContain(".");
326
- });
327
- it("barrel at depth 2 shows description", async () => {
328
- const basicDir = resolve(fixturesDir, "barrel-basic");
329
- // barrel-basic/index.ts has @summary + description
330
- // At depth 2, barrel still gates: shows its description (L2)
331
- const results = await drilldown(
332
- globSelector("**/*.ts", 2),
333
- basicDir,
334
- true,
335
- 100,
336
- NO_CACHE,
337
- );
338
- expect(results.items).toHaveLength(1);
339
- const entry = results.items[0];
340
- expect(isOutputItem(entry)).toBe(true);
341
- expect(hasNextId(entry)).toBe(true);
342
- if (hasNextId(entry)) {
343
- expect(entry.next_id).toBe(".@3");
344
- expect(entry.text).toBe("Basic barrel module.");
345
- expect(entry.children).toBeDefined();
346
- expect(entry.children).toContain("helper.ts");
347
- expect(entry.children).toContain("utils.ts");
348
- }
349
- });
350
- it("barrel with summary but no description null-skips at depth 2", async () => {
351
- const summaryOnlyDir = resolve(fixturesDir, "barrel-summary-only");
352
- // barrel-summary-only/index.ts has @summary but no description
353
- // At depth 1, barrel gates: shows its summary
354
- const results1 = await drilldown(
355
- globSelector("**/*.ts", 1),
356
- summaryOnlyDir,
357
- true,
358
- 100,
359
- NO_CACHE,
360
- );
361
- expect(results1.items).toHaveLength(1);
362
- const entry1 = results1.items[0];
363
- expect(isOutputItem(entry1)).toBe(true);
364
- expect(hasNextId(entry1)).toBe(true);
365
- if (hasNextId(entry1)) {
366
- expect(entry1.next_id).toBe(".@2");
367
- expect(entry1.text).toBe("Summary-only barrel");
368
- expect(entry1.children).toBeDefined();
369
- expect(entry1.children).toContain("child.ts");
370
- }
371
- // At depth 2, no description → null-skip to transition, children appear
372
- const results2 = await drilldown(
373
- globSelector("**/*.ts", 2),
374
- summaryOnlyDir,
375
- true,
376
- 100,
377
- NO_CACHE,
378
- );
379
- const paths2 = results2.items.map((r) => pathFromEntry(r));
380
- expect(paths2).not.toContain(".");
381
- expect(paths2).toContain("child.ts");
382
- });
383
- });