@pubinfo-pr/devtools 0.203.1 → 0.203.2

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 (35) hide show
  1. package/dist/client/assets/Navbar-D8ux538U.css +18 -0
  2. package/dist/client/assets/Navbar-DCdslOKs.js +219 -0
  3. package/dist/client/assets/PanelGrids-Bq_2z9g3.js +9 -0
  4. package/dist/client/assets/SelectTabs-Chnu7x16.js +171 -0
  5. package/dist/client/assets/_plugin-vue_export-helper-D8E0syuh.js +6 -0
  6. package/dist/client/assets/component-Qe9twpoz.js +468 -0
  7. package/dist/client/assets/{core-DZ0_U_pO.js → core-D6JqxgYq.js} +134 -133
  8. package/dist/client/assets/{engine-oniguruma-Cxk0otvy.js → engine-oniguruma-n-bafM3H.js} +8 -8
  9. package/dist/client/assets/{fetch-Df05JmPt.js → fetch-CwAFBmMG.js} +122 -6
  10. package/dist/client/assets/import-DV9l8S2T.js +375 -0
  11. package/dist/client/assets/{index-Cn9-H915.js → index-ByOJyids.js} +1174 -1123
  12. package/dist/client/assets/index-DNthkvua.css +443 -0
  13. package/dist/client/assets/issue-BHrGN1_d.css +10 -0
  14. package/dist/client/assets/issue-MdUzHAB3.js +130 -0
  15. package/dist/client/assets/pages-D4LiKgxN.js +285 -0
  16. package/dist/client/assets/pages-DQ8FtB9Y.css +17 -0
  17. package/dist/client/assets/{server-router-8PynUpe5.css → server-router-B1AB70as.css} +0 -18
  18. package/dist/client/assets/{server-router-BHD-n_Wi.js → server-router-DuEpkdvh.js} +26 -238
  19. package/dist/client/assets/vue-DZSPIjN6.js +27 -0
  20. package/dist/client/component.svg +1 -0
  21. package/dist/client/import.svg +1 -0
  22. package/dist/client/index.html +2 -2
  23. package/dist/client/issue.svg +1 -0
  24. package/dist/client/logo.svg +1 -0
  25. package/dist/constants.d.mts +1 -2
  26. package/dist/dirs.mjs +15 -1
  27. package/dist/index.d.mts +0 -15
  28. package/dist/index.mjs +1968 -52
  29. package/dist/panel/index.d.mts +1 -0
  30. package/dist/panel/index.mjs +75 -3776
  31. package/package.json +29 -18
  32. package/dist/client/assets/index-Blntvu93.css +0 -443
  33. package/dist/client/assets/pages-BdQpgtx4.js +0 -20
  34. package/dist/client/assets/vue-Be3tcD1h.js +0 -27
  35. package/dist/dirs2.mjs +0 -17
@@ -0,0 +1,468 @@
1
+ import { B as withCtx, D as onBeforeUnmount, G as isRef, M as renderSlot, N as resolveComponent, Y as ref, b as defineComponent, f as computed, g as createElementBlock, h as createCommentVNode, it as toDisplayString, j as renderList, k as openBlock, m as createBlock, nt as normalizeClass, p as createBaseVNode, tt as unref, u as Fragment, v as createTextVNode, y as createVNode } from "./index-ByOJyids.js";
2
+ import { a as Icon_default, i as SectionBlock_default, r as Button_default, t as Navbar_default } from "./Navbar-DCdslOKs.js";
3
+ import { l as useClipboard, n as componentUsageFetch, o as Badge_default } from "./fetch-CwAFBmMG.js";
4
+ import { n as FilepathItem_default, t as SelectTabs_default } from "./SelectTabs-Chnu7x16.js";
5
+ var NUMBER_CHAR_RE = /\d/;
6
+ var STR_SPLITTERS = [
7
+ "-",
8
+ "_",
9
+ "/",
10
+ "."
11
+ ];
12
+ function isUppercase(char = "") {
13
+ if (NUMBER_CHAR_RE.test(char)) return;
14
+ return char !== char.toLowerCase();
15
+ }
16
+ function splitByCase(str, separators) {
17
+ const splitters = separators ?? STR_SPLITTERS;
18
+ const parts = [];
19
+ if (!str || typeof str !== "string") return parts;
20
+ let buff = "";
21
+ let previousUpper;
22
+ let previousSplitter;
23
+ for (const char of str) {
24
+ const isSplitter = splitters.includes(char);
25
+ if (isSplitter === true) {
26
+ parts.push(buff);
27
+ buff = "";
28
+ previousUpper = void 0;
29
+ continue;
30
+ }
31
+ const isUpper = isUppercase(char);
32
+ if (previousSplitter === false) {
33
+ if (previousUpper === false && isUpper === true) {
34
+ parts.push(buff);
35
+ buff = char;
36
+ previousUpper = isUpper;
37
+ continue;
38
+ }
39
+ if (previousUpper === true && isUpper === false && buff.length > 1) {
40
+ const lastChar = buff.at(-1);
41
+ parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
42
+ buff = lastChar + char;
43
+ previousUpper = isUpper;
44
+ continue;
45
+ }
46
+ }
47
+ buff += char;
48
+ previousUpper = isUpper;
49
+ previousSplitter = isSplitter;
50
+ }
51
+ parts.push(buff);
52
+ return parts;
53
+ }
54
+ function upperFirst(str) {
55
+ return str ? str[0].toUpperCase() + str.slice(1) : "";
56
+ }
57
+ function pascalCase(str, opts) {
58
+ return str ? (Array.isArray(str) ? str : splitByCase(str)).map((p) => upperFirst(opts?.normalize ? p.toLowerCase() : p)).join("") : "";
59
+ }
60
+ var _hoisted_1$3 = { class: "text-sm font-mono" };
61
+ var ComponentName_default = /* @__PURE__ */ defineComponent({
62
+ __name: "ComponentName",
63
+ props: { component: {} },
64
+ setup(__props) {
65
+ const props = __props;
66
+ const name = computed(() => props.component.pascalName || pascalCase(props.component.name || props.component.kebabName || ""));
67
+ return (_ctx, _cache) => {
68
+ return openBlock(), createElementBlock("code", _hoisted_1$3, [
69
+ _cache[0] || (_cache[0] = createBaseVNode("span", { class: "mr1 op20" }, "<", -1)),
70
+ createTextVNode(toDisplayString(name.value), 1),
71
+ _cache[1] || (_cache[1] = createBaseVNode("span", { class: "ml1 op20" }, "/>", -1))
72
+ ]);
73
+ };
74
+ }
75
+ });
76
+ var _hoisted_1$2 = { class: "flex flex-col gap-1 items-start of-hidden" };
77
+ var _hoisted_2$2 = { class: "flex gap-2 items-center px-3" };
78
+ var _hoisted_3$1 = {
79
+ key: 0,
80
+ class: "border-t n-border-base max-h-60 w-full of-auto px3 py3"
81
+ };
82
+ var _hoisted_4$1 = { "text-sm": "" };
83
+ var _hoisted_5$1 = { "text-primary": "" };
84
+ var _hoisted_6$1 = {
85
+ key: 0,
86
+ flex: "~ col gap-2",
87
+ "items-start": "",
88
+ pt3: "",
89
+ "text-sm": "",
90
+ op75: ""
91
+ };
92
+ var ComponentDetails_default = /* @__PURE__ */ defineComponent({
93
+ __name: "ComponentDetails",
94
+ props: {
95
+ component: {},
96
+ dependents: {},
97
+ locations: {}
98
+ },
99
+ setup(__props) {
100
+ const props = __props;
101
+ const referenceEntries = computed(() => {
102
+ const rawLocations = props.locations ?? props.component.locations ?? [];
103
+ if (rawLocations.length) return rawLocations.map((location) => ({
104
+ filepath: location.file,
105
+ line: location.line,
106
+ column: location.column
107
+ }));
108
+ return (props.dependents ?? props.component.dependents ?? []).map((filepath) => ({ filepath }));
109
+ });
110
+ const sortedReferenceEntries = computed(() => {
111
+ return [...referenceEntries.value].sort((a, b) => {
112
+ if (a.filepath === b.filepath) return (a.line ?? 0) - (b.line ?? 0);
113
+ return a.filepath.localeCompare(b.filepath);
114
+ });
115
+ });
116
+ const referencesCount = computed(() => sortedReferenceEntries.value.length);
117
+ const showDependentsPanel = computed(() => referencesCount.value > 0);
118
+ const componentNameForCopy = computed(() => {
119
+ if (props.component.pascalName) return props.component.pascalName;
120
+ if (props.component.name) return props.component.name;
121
+ if (props.component.kebabName) return pascalCase(props.component.kebabName);
122
+ return "";
123
+ });
124
+ const { copy: copyToClipboard } = useClipboard({ legacy: true });
125
+ const copyState = ref("idle");
126
+ let copyResetHandle;
127
+ const canCopyName = computed(() => Boolean(componentNameForCopy.value));
128
+ const nameCopyTooltip = computed(() => {
129
+ if (!canCopyName.value) return "Component name unavailable";
130
+ if (copyState.value === "copied") return "Copied component name";
131
+ if (copyState.value === "error") return "Failed to copy name";
132
+ return "Copy component name";
133
+ });
134
+ const nameCopyLabel = computed(() => {
135
+ if (copyState.value === "copied") return "Copied";
136
+ if (copyState.value === "error") return "Retry";
137
+ return "Copy";
138
+ });
139
+ const nameCopyIcon = computed(() => {
140
+ if (copyState.value === "copied") return "i-carbon-checkmark";
141
+ if (copyState.value === "error") return "i-carbon-warning-alt";
142
+ return "i-carbon-copy";
143
+ });
144
+ function resetCopyState() {
145
+ if (copyResetHandle) clearTimeout(copyResetHandle);
146
+ copyResetHandle = setTimeout(() => {
147
+ copyState.value = "idle";
148
+ copyResetHandle = void 0;
149
+ }, 2e3);
150
+ }
151
+ async function copyComponentName() {
152
+ if (!componentNameForCopy.value || !canCopyName.value) return;
153
+ try {
154
+ await copyToClipboard(componentNameForCopy.value);
155
+ copyState.value = "copied";
156
+ } catch (error) {
157
+ console.error("Failed to copy component name:", error);
158
+ copyState.value = "error";
159
+ } finally {
160
+ resetCopyState();
161
+ }
162
+ }
163
+ onBeforeUnmount(() => {
164
+ if (copyResetHandle) clearTimeout(copyResetHandle);
165
+ });
166
+ return (_ctx, _cache) => {
167
+ const _component_ComponentName = ComponentName_default;
168
+ const _component_Badge = Badge_default;
169
+ const _component_FilepathItem = FilepathItem_default;
170
+ return openBlock(), createElementBlock("div", _hoisted_1$2, [
171
+ createBaseVNode("div", _hoisted_2$2, [
172
+ createVNode(_component_ComponentName, { component: __props.component }, null, 8, ["component"]),
173
+ __props.component.meta?.docs && typeof __props.component.meta.docs === "string" ? (openBlock(), createBlock(unref(Button_default), {
174
+ key: 0,
175
+ title: "Open docs",
176
+ class: "flex-none n-xs",
177
+ to: __props.component.meta.docs,
178
+ target: "_blank",
179
+ icon: "i-carbon-catalog"
180
+ }, {
181
+ default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode(" Docs ", -1)])]),
182
+ _: 1
183
+ }, 8, ["to"])) : createCommentVNode("", true),
184
+ createVNode(unref(Button_default), {
185
+ class: "flex-none n-xs",
186
+ disabled: !canCopyName.value,
187
+ icon: nameCopyIcon.value,
188
+ title: nameCopyTooltip.value,
189
+ onClick: copyComponentName
190
+ }, {
191
+ default: withCtx(() => [createTextVNode(toDisplayString(nameCopyLabel.value), 1)]),
192
+ _: 1
193
+ }, 8, [
194
+ "disabled",
195
+ "icon",
196
+ "title"
197
+ ]),
198
+ __props.component.meta?.category ? (openBlock(), createBlock(_component_Badge, {
199
+ key: 1,
200
+ class: "n-blue",
201
+ title: `Category: ${__props.component.meta.category}`
202
+ }, {
203
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.component.meta.category), 1)]),
204
+ _: 1
205
+ }, 8, ["title"])) : createCommentVNode("", true),
206
+ __props.component.global ? (openBlock(), createBlock(_component_Badge, {
207
+ key: 2,
208
+ class: "n-green",
209
+ title: "Registered at runtime as a global component"
210
+ }, {
211
+ default: withCtx(() => [..._cache[1] || (_cache[1] = [createTextVNode(" runtime ", -1)])]),
212
+ _: 1
213
+ })) : createCommentVNode("", true)
214
+ ]),
215
+ showDependentsPanel.value ? (openBlock(), createElementBlock("div", _hoisted_3$1, [createBaseVNode("div", _hoisted_4$1, [createBaseVNode("strong", _hoisted_5$1, toDisplayString(referencesCount.value), 1), _cache[2] || (_cache[2] = createBaseVNode("span", { op50: "" }, " references", -1))]), referencesCount.value ? (openBlock(), createElementBlock("div", _hoisted_6$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(sortedReferenceEntries.value, (item) => {
216
+ return openBlock(), createBlock(_component_FilepathItem, {
217
+ key: `${item.filepath}-${item.line ?? 0}-${item.column ?? 0}`,
218
+ filepath: item.filepath,
219
+ line: item.line,
220
+ column: item.column
221
+ }, null, 8, [
222
+ "filepath",
223
+ "line",
224
+ "column"
225
+ ]);
226
+ }), 128))])) : createCommentVNode("", true)])) : createCommentVNode("", true),
227
+ renderSlot(_ctx.$slots, "default")
228
+ ]);
229
+ };
230
+ }
231
+ });
232
+ var _hoisted_1$1 = { class: "group flex gap-2 w-full items-center rounded px-2 py-1 hoverLbg-active" };
233
+ var _hoisted_2$1 = {
234
+ key: 0,
235
+ class: "ml--1 text-primary"
236
+ };
237
+ var ComponentItem_default = /* @__PURE__ */ defineComponent({
238
+ __name: "ComponentItem",
239
+ props: {
240
+ component: {},
241
+ dependents: {}
242
+ },
243
+ setup(__props) {
244
+ const props = __props;
245
+ const dependentsList = computed(() => props.dependents ?? props.component.dependents ?? []);
246
+ const referenceLocations = computed(() => props.component.locations ?? []);
247
+ const referenceCount = computed(() => referenceLocations.value.length || dependentsList.value.length);
248
+ return (_ctx, _cache) => {
249
+ const _component_ComponentName = ComponentName_default;
250
+ const _component_ComponentDetails = ComponentDetails_default;
251
+ const _component_VDropdown = resolveComponent("VDropdown");
252
+ const _component_Badge = Badge_default;
253
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [
254
+ createVNode(_component_VDropdown, null, {
255
+ popper: withCtx(() => [createVNode(_component_ComponentDetails, {
256
+ component: __props.component,
257
+ dependents: dependentsList.value,
258
+ locations: referenceLocations.value,
259
+ class: "w-100 py3"
260
+ }, null, 8, [
261
+ "component",
262
+ "dependents",
263
+ "locations"
264
+ ])]),
265
+ default: withCtx(() => [createBaseVNode("button", { class: normalizeClass(["hover:text-primary", referenceCount.value === 0 ? "op50" : ""]) }, [createVNode(_component_ComponentName, { component: __props.component }, null, 8, ["component"])], 2)]),
266
+ _: 1
267
+ }),
268
+ referenceCount.value ? (openBlock(), createElementBlock("sup", _hoisted_2$1, " x" + toDisplayString(referenceCount.value), 1)) : createCommentVNode("", true),
269
+ __props.component.meta?.category ? (openBlock(), createBlock(_component_Badge, {
270
+ key: 1,
271
+ class: "n-blue",
272
+ title: `Category: ${__props.component.meta.category}`
273
+ }, {
274
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.component.meta.category), 1)]),
275
+ _: 1
276
+ }, 8, ["title"])) : createCommentVNode("", true),
277
+ __props.component.global ? (openBlock(), createBlock(_component_Badge, {
278
+ key: 2,
279
+ class: "n-green",
280
+ title: "Registered at runtime as a global component"
281
+ }, {
282
+ default: withCtx(() => [..._cache[0] || (_cache[0] = [createTextVNode(" runtime ", -1)])]),
283
+ _: 1
284
+ })) : createCommentVNode("", true),
285
+ renderSlot(_ctx.$slots, "default")
286
+ ]);
287
+ };
288
+ }
289
+ });
290
+ var _hoisted_1 = { class: "relative h-full flex flex-col of-hidden" };
291
+ var _hoisted_2 = { class: "flex items-center gap-2" };
292
+ var _hoisted_3 = { class: "flex-1 of-auto" };
293
+ var _hoisted_4 = { class: "flex flex-col gap-2 px4 py3" };
294
+ var _hoisted_5 = {
295
+ key: 0,
296
+ class: "text-sm text-red op75"
297
+ };
298
+ var _hoisted_6 = {
299
+ key: 1,
300
+ class: "text-sm op50 px2 py1"
301
+ };
302
+ var component_default = /* @__PURE__ */ defineComponent({
303
+ name: "ComponentPage",
304
+ __name: "component",
305
+ setup(__props) {
306
+ const search = ref("");
307
+ const filterMode = ref("all");
308
+ const { execute, data, error, isFetching } = componentUsageFetch;
309
+ if (!data.value) execute();
310
+ computed(() => data.value?.stats ?? {
311
+ total: 0,
312
+ used: 0,
313
+ unused: 0
314
+ });
315
+ const components = computed(() => data.value?.components ?? []);
316
+ const normalizedSearch = computed(() => search.value.trim().toLowerCase());
317
+ const packageStats = computed(() => {
318
+ const map = /* @__PURE__ */ new Map();
319
+ components.value.forEach((component) => {
320
+ if (!map.has(component.package)) map.set(component.package, {
321
+ total: 0,
322
+ used: 0,
323
+ unused: 0
324
+ });
325
+ const stats = map.get(component.package);
326
+ stats.total += 1;
327
+ if (component.count > 0) stats.used += 1;
328
+ else stats.unused += 1;
329
+ });
330
+ return map;
331
+ });
332
+ function matchesFilter(component, mode) {
333
+ if (mode === "using") return component.count > 0;
334
+ if (mode === "not-used") return component.count === 0;
335
+ return true;
336
+ }
337
+ function matchesQuery(component, query) {
338
+ if (!query) return true;
339
+ return [
340
+ component.name,
341
+ component.kebabName,
342
+ component.package,
343
+ ...component.dependents
344
+ ].join(" ").toLowerCase().includes(query);
345
+ }
346
+ const filteredComponents = computed(() => {
347
+ const query = normalizedSearch.value;
348
+ const mode = filterMode.value;
349
+ return [...components.value].sort((a, b) => {
350
+ if (a.count === b.count) return a.name.localeCompare(b.name);
351
+ return b.count - a.count;
352
+ }).filter((component) => matchesFilter(component, mode) && matchesQuery(component, query));
353
+ });
354
+ computed(() => filteredComponents.value.length);
355
+ const FALLBACK_GROUP_ORDER = Number.MAX_SAFE_INTEGER;
356
+ function resolvePackageGroupMeta(pkg) {
357
+ return {
358
+ label: pkg,
359
+ icon: "i-carbon-cube",
360
+ order: FALLBACK_GROUP_ORDER
361
+ };
362
+ }
363
+ const groupedComponents = computed(() => {
364
+ const grouped = /* @__PURE__ */ new Map();
365
+ filteredComponents.value.forEach((component) => {
366
+ if (!grouped.has(component.package)) grouped.set(component.package, []);
367
+ grouped.get(component.package).push(component);
368
+ });
369
+ return Array.from(grouped.entries()).map(([pkg, items]) => {
370
+ const meta = resolvePackageGroupMeta(pkg);
371
+ const stats = packageStats.value.get(pkg) ?? {
372
+ total: items.length,
373
+ used: items.filter((item) => item.count > 0).length,
374
+ unused: items.filter((item) => item.count === 0).length
375
+ };
376
+ return {
377
+ id: pkg,
378
+ label: meta.label,
379
+ icon: meta.icon,
380
+ order: meta.order ?? Number.MAX_SAFE_INTEGER,
381
+ items,
382
+ stats
383
+ };
384
+ }).sort((a, b) => {
385
+ if (a.order === b.order) return a.label.localeCompare(b.label);
386
+ return a.order - b.order;
387
+ });
388
+ });
389
+ const emptyStateMessage = computed(() => {
390
+ if (isFetching.value && !components.value.length) return "正在扫描组件使用情况...";
391
+ if (!components.value.length) return "还没有可追踪的组件。";
392
+ return "没有符合条件的组件。";
393
+ });
394
+ const requestError = computed(() => {
395
+ const raw = error.value;
396
+ if (!raw) return "";
397
+ if (typeof raw === "string") return raw;
398
+ if (raw instanceof Error) return raw.message;
399
+ try {
400
+ return JSON.stringify(raw);
401
+ } catch {
402
+ return "获取组件使用数据失败";
403
+ }
404
+ });
405
+ return (_ctx, _cache) => {
406
+ const _component_Icon = Icon_default;
407
+ const _component_SelectTabs = SelectTabs_default;
408
+ const _component_Navbar = Navbar_default;
409
+ const _component_ComponentItem = ComponentItem_default;
410
+ const _component_SectionBlock = SectionBlock_default;
411
+ return openBlock(), createElementBlock("div", _hoisted_1, [createVNode(_component_Navbar, {
412
+ search: unref(search),
413
+ "onUpdate:search": _cache[1] || (_cache[1] = ($event) => isRef(search) ? search.value = $event : null),
414
+ class: "pb3 flex-none"
415
+ }, {
416
+ default: withCtx(() => [createBaseVNode("div", _hoisted_2, [createVNode(_component_Icon, {
417
+ icon: "i-carbon-filter",
418
+ class: "op50"
419
+ }), createVNode(_component_SelectTabs, {
420
+ modelValue: unref(filterMode),
421
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(filterMode) ? filterMode.value = $event : null),
422
+ class: "n-primary n-sm",
423
+ options: [
424
+ {
425
+ label: "All",
426
+ value: "all"
427
+ },
428
+ {
429
+ label: "Using",
430
+ value: "using"
431
+ },
432
+ {
433
+ label: "Not used",
434
+ value: "not-used"
435
+ }
436
+ ]
437
+ }, null, 8, ["modelValue"])])]),
438
+ _: 1
439
+ }, 8, ["search"]), createBaseVNode("div", _hoisted_3, [createBaseVNode("div", _hoisted_4, [unref(requestError) ? (openBlock(), createElementBlock("div", _hoisted_5, toDisplayString(unref(requestError)), 1)) : !unref(filteredComponents).length ? (openBlock(), createElementBlock("div", _hoisted_6, toDisplayString(unref(emptyStateMessage)), 1)) : (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(unref(groupedComponents), (group) => {
440
+ return openBlock(), createBlock(_component_SectionBlock, {
441
+ key: group.id,
442
+ text: group.label,
443
+ description: `Total components: ${group.stats.total}`,
444
+ icon: group.icon
445
+ }, {
446
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(group.items, (componentEntry) => {
447
+ return openBlock(), createBlock(_component_ComponentItem, {
448
+ key: `${componentEntry.package}-${componentEntry.name}`,
449
+ component: componentEntry,
450
+ dependencies: componentEntry.dependencies,
451
+ dependents: componentEntry.dependents
452
+ }, null, 8, [
453
+ "component",
454
+ "dependencies",
455
+ "dependents"
456
+ ]);
457
+ }), 128))]),
458
+ _: 2
459
+ }, 1032, [
460
+ "text",
461
+ "description",
462
+ "icon"
463
+ ]);
464
+ }), 128))])])]);
465
+ };
466
+ }
467
+ });
468
+ export { component_default as default };