@pubinfo-pr/devtools 0.220.2 → 0.220.4
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/client/assets/Navbar-D8ux538U.css +18 -0
- package/dist/client/assets/Navbar-DCdslOKs.js +219 -0
- package/dist/client/assets/PanelGrids-Bq_2z9g3.js +9 -0
- package/dist/client/assets/SelectTabs-Chnu7x16.js +171 -0
- package/dist/client/assets/_plugin-vue_export-helper-D8E0syuh.js +6 -0
- package/dist/client/assets/component-Qe9twpoz.js +468 -0
- package/dist/client/assets/{fetch-DxuBXEk3.js → fetch-CwAFBmMG.js} +121 -4
- package/dist/client/assets/import-DV9l8S2T.js +375 -0
- package/dist/client/assets/{index-DcEJJh1_.js → index-ByOJyids.js} +34 -11
- package/dist/client/assets/index-DNthkvua.css +443 -0
- package/dist/client/assets/issue-BHrGN1_d.css +10 -0
- package/dist/client/assets/issue-MdUzHAB3.js +130 -0
- package/dist/client/assets/pages-D4LiKgxN.js +285 -0
- package/dist/client/assets/pages-DQ8FtB9Y.css +17 -0
- package/dist/client/assets/{server-router-8PynUpe5.css → server-router-B1AB70as.css} +0 -18
- package/dist/client/assets/{server-router-Bu5965f8.js → server-router-DuEpkdvh.js} +14 -225
- package/dist/client/component.svg +1 -0
- package/dist/client/import.svg +1 -0
- package/dist/client/index.html +2 -2
- package/dist/client/issue.svg +1 -0
- package/dist/client/logo.svg +1 -0
- package/dist/index.d.mts +0 -14
- package/dist/index.mjs +1966 -50
- package/dist/panel/index.d.mts +1 -0
- package/dist/panel/index.mjs +97 -1
- package/package.json +7 -2
- package/dist/client/assets/index-D7UL6pHD.css +0 -443
- package/dist/client/assets/pages-CfWIiNIx.js +0 -20
|
@@ -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 };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as toRef$1, E as nextTick, G as isRef, H as customRef, J as readonly, K as onScopeDispose, M as renderSlot, O as onMounted, Q as toRaw, R as watch, U as effectScope, W as getCurrentScope, X as shallowReadonly, Y as ref, Z as shallowRef, b as defineComponent, et as toValue, f as computed, g as createElementBlock, k as openBlock, tt as unref, x as getCurrentInstance } from "./index-ByOJyids.js";
|
|
2
2
|
function tryOnScopeDispose(fn, failSilently) {
|
|
3
3
|
if (getCurrentScope()) {
|
|
4
4
|
onScopeDispose(fn, failSilently);
|
|
@@ -89,6 +89,19 @@ function promiseTimeout(ms, throwOnTimeout = false, reason = "Timeout") {
|
|
|
89
89
|
else setTimeout(resolve, ms);
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
|
+
function createSingletonPromise(fn) {
|
|
93
|
+
let _promise;
|
|
94
|
+
function wrapper() {
|
|
95
|
+
if (!_promise) _promise = fn();
|
|
96
|
+
return _promise;
|
|
97
|
+
}
|
|
98
|
+
wrapper.reset = async () => {
|
|
99
|
+
const _prev = _promise;
|
|
100
|
+
_promise = void 0;
|
|
101
|
+
if (_prev) await _prev;
|
|
102
|
+
};
|
|
103
|
+
return wrapper;
|
|
104
|
+
}
|
|
92
105
|
function containsProp(obj, ...props) {
|
|
93
106
|
return props.some((k) => k in obj);
|
|
94
107
|
}
|
|
@@ -344,7 +357,7 @@ function keysToCamelKebabCase(obj) {
|
|
|
344
357
|
}
|
|
345
358
|
var defaultWindow = isClient ? window : void 0;
|
|
346
359
|
isClient && window.document;
|
|
347
|
-
isClient
|
|
360
|
+
var defaultNavigator = isClient ? window.navigator : void 0;
|
|
348
361
|
isClient && window.location;
|
|
349
362
|
function unrefElement(elRef) {
|
|
350
363
|
var _$el;
|
|
@@ -479,6 +492,94 @@ function useSupported(callback) {
|
|
|
479
492
|
return Boolean(callback());
|
|
480
493
|
});
|
|
481
494
|
}
|
|
495
|
+
function usePermission(permissionDesc, options = {}) {
|
|
496
|
+
const { controls = false, navigator: navigator$1 = defaultNavigator } = options;
|
|
497
|
+
const isSupported = /* @__PURE__ */ useSupported(() => navigator$1 && "permissions" in navigator$1);
|
|
498
|
+
const permissionStatus = shallowRef();
|
|
499
|
+
const desc = typeof permissionDesc === "string" ? { name: permissionDesc } : permissionDesc;
|
|
500
|
+
const state = shallowRef();
|
|
501
|
+
const update = () => {
|
|
502
|
+
var _permissionStatus$val, _permissionStatus$val2;
|
|
503
|
+
state.value = (_permissionStatus$val = (_permissionStatus$val2 = permissionStatus.value) === null || _permissionStatus$val2 === void 0 ? void 0 : _permissionStatus$val2.state) !== null && _permissionStatus$val !== void 0 ? _permissionStatus$val : "prompt";
|
|
504
|
+
};
|
|
505
|
+
useEventListener(permissionStatus, "change", update, { passive: true });
|
|
506
|
+
const query = createSingletonPromise(async () => {
|
|
507
|
+
if (!isSupported.value) return;
|
|
508
|
+
if (!permissionStatus.value) try {
|
|
509
|
+
permissionStatus.value = await navigator$1.permissions.query(desc);
|
|
510
|
+
} catch (_unused) {
|
|
511
|
+
permissionStatus.value = void 0;
|
|
512
|
+
} finally {
|
|
513
|
+
update();
|
|
514
|
+
}
|
|
515
|
+
if (controls) return toRaw(permissionStatus.value);
|
|
516
|
+
});
|
|
517
|
+
query();
|
|
518
|
+
if (controls) return {
|
|
519
|
+
state,
|
|
520
|
+
isSupported,
|
|
521
|
+
query
|
|
522
|
+
};
|
|
523
|
+
else return state;
|
|
524
|
+
}
|
|
525
|
+
function useClipboard(options = {}) {
|
|
526
|
+
const { navigator: navigator$1 = defaultNavigator, read = false, source, copiedDuring = 1500, legacy = false } = options;
|
|
527
|
+
const isClipboardApiSupported = /* @__PURE__ */ useSupported(() => navigator$1 && "clipboard" in navigator$1);
|
|
528
|
+
const permissionRead = usePermission("clipboard-read");
|
|
529
|
+
const permissionWrite = usePermission("clipboard-write");
|
|
530
|
+
const isSupported = computed(() => isClipboardApiSupported.value || legacy);
|
|
531
|
+
const text = shallowRef("");
|
|
532
|
+
const copied = shallowRef(false);
|
|
533
|
+
const timeout = useTimeoutFn(() => copied.value = false, copiedDuring, { immediate: false });
|
|
534
|
+
async function updateText() {
|
|
535
|
+
let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionRead.value));
|
|
536
|
+
if (!useLegacy) try {
|
|
537
|
+
text.value = await navigator$1.clipboard.readText();
|
|
538
|
+
} catch (_unused) {
|
|
539
|
+
useLegacy = true;
|
|
540
|
+
}
|
|
541
|
+
if (useLegacy) text.value = legacyRead();
|
|
542
|
+
}
|
|
543
|
+
if (isSupported.value && read) useEventListener(["copy", "cut"], updateText, { passive: true });
|
|
544
|
+
async function copy(value = toValue(source)) {
|
|
545
|
+
if (isSupported.value && value != null) {
|
|
546
|
+
let useLegacy = !(isClipboardApiSupported.value && isAllowed(permissionWrite.value));
|
|
547
|
+
if (!useLegacy) try {
|
|
548
|
+
await navigator$1.clipboard.writeText(value);
|
|
549
|
+
} catch (_unused2) {
|
|
550
|
+
useLegacy = true;
|
|
551
|
+
}
|
|
552
|
+
if (useLegacy) legacyCopy(value);
|
|
553
|
+
text.value = value;
|
|
554
|
+
copied.value = true;
|
|
555
|
+
timeout.start();
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function legacyCopy(value) {
|
|
559
|
+
const ta = document.createElement("textarea");
|
|
560
|
+
ta.value = value;
|
|
561
|
+
ta.style.position = "absolute";
|
|
562
|
+
ta.style.opacity = "0";
|
|
563
|
+
ta.setAttribute("readonly", "");
|
|
564
|
+
document.body.appendChild(ta);
|
|
565
|
+
ta.select();
|
|
566
|
+
document.execCommand("copy");
|
|
567
|
+
ta.remove();
|
|
568
|
+
}
|
|
569
|
+
function legacyRead() {
|
|
570
|
+
var _document$getSelectio, _document, _document$getSelectio2;
|
|
571
|
+
return (_document$getSelectio = (_document = document) === null || _document === void 0 || (_document$getSelectio2 = _document.getSelection) === null || _document$getSelectio2 === void 0 || (_document$getSelectio2 = _document$getSelectio2.call(_document)) === null || _document$getSelectio2 === void 0 ? void 0 : _document$getSelectio2.toString()) !== null && _document$getSelectio !== void 0 ? _document$getSelectio : "";
|
|
572
|
+
}
|
|
573
|
+
function isAllowed(status) {
|
|
574
|
+
return status === "granted" || status === "prompt";
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
isSupported,
|
|
578
|
+
text: readonly(text),
|
|
579
|
+
copied: readonly(copied),
|
|
580
|
+
copy
|
|
581
|
+
};
|
|
582
|
+
}
|
|
482
583
|
function cloneFnJSON(source) {
|
|
483
584
|
return JSON.parse(JSON.stringify(source));
|
|
484
585
|
}
|
|
@@ -984,7 +1085,23 @@ function useVModel(props, key, emit, options = {}) {
|
|
|
984
1085
|
}
|
|
985
1086
|
});
|
|
986
1087
|
}
|
|
1088
|
+
var _hoisted_1 = { class: "n-badge" };
|
|
1089
|
+
var Badge_default = /* @__PURE__ */ defineComponent({
|
|
1090
|
+
name: "Badge",
|
|
1091
|
+
__name: "Badge",
|
|
1092
|
+
setup(__props) {
|
|
1093
|
+
return (_ctx, _cache) => {
|
|
1094
|
+
return openBlock(), createElementBlock("span", _hoisted_1, [renderSlot(_ctx.$slots, "default")]);
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
987
1098
|
var API_ROOT = "/__pubinfo_devtools_api";
|
|
988
|
-
const
|
|
1099
|
+
const overviewFetch = useFetch(`${API_ROOT}/overview`, { immediate: false }).json();
|
|
989
1100
|
const apiListFetch = useFetch(`${API_ROOT}/api-list`, { immediate: false }).json();
|
|
990
|
-
|
|
1101
|
+
const componentUsageFetch = useFetch(`${API_ROOT}/component-usage`, { immediate: false }).json();
|
|
1102
|
+
const importUsageFetch = useFetch(`${API_ROOT}/import-usage`, { immediate: false }).json();
|
|
1103
|
+
function usePackageVersion(packageName) {
|
|
1104
|
+
return useFetch(`${API_ROOT}/package-version?package=${encodeURIComponent(packageName)}`, { immediate: false }).json();
|
|
1105
|
+
}
|
|
1106
|
+
useFetch(`${API_ROOT}/environment-info`, { immediate: false }).json();
|
|
1107
|
+
export { usePackageVersion as a, onClickOutside as c, useLocalStorage as d, useVModel as f, overviewFetch as i, useClipboard as l, createSharedComposable as m, componentUsageFetch as n, Badge_default as o, createEventHook as p, importUsageFetch as r, createReusableTemplate as s, apiListFetch as t, useElementSize as u };
|