vue-hook-optimizer 0.0.77 → 0.0.78

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/index.cjs ADDED
@@ -0,0 +1,2016 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const __babel_traverse = __toESM(require("@babel/traverse"));
25
+ const __vue_compiler_sfc = __toESM(require("@vue/compiler-sfc"));
26
+
27
+ //#region src/analyze/utils.ts
28
+ let NodeType = /* @__PURE__ */ function(NodeType$1) {
29
+ NodeType$1["var"] = "var";
30
+ NodeType$1["fun"] = "fun";
31
+ return NodeType$1;
32
+ }({});
33
+ var NodeCollection = class {
34
+ constructor(_lineOffset = 0, _addInfo = true) {
35
+ this.lineOffset = 0;
36
+ this.addInfo = true;
37
+ this.nodes = /* @__PURE__ */ new Map();
38
+ this.lineOffset = _lineOffset;
39
+ this.addInfo = _addInfo;
40
+ }
41
+ addNode(label, node, options = {
42
+ isComputed: false,
43
+ isMethod: false,
44
+ comment: ""
45
+ }) {
46
+ if (this.nodes.has(label)) return;
47
+ if (!options.isComputed && (node.type === "VariableDeclarator" && [
48
+ "ArrowFunctionExpression",
49
+ "FunctionDeclaration",
50
+ "FunctionExpression"
51
+ ].includes(node.init?.type || "") || node.type === "ObjectProperty" && [
52
+ "ArrowFunctionExpression",
53
+ "FunctionDeclaration",
54
+ "FunctionExpression"
55
+ ].includes(node.value?.type || "") || node.type === "FunctionDeclaration" || node.type === "ObjectMethod" || node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") || options.isMethod) this.nodes.set(label, {
56
+ label,
57
+ type: NodeType.fun,
58
+ ...this.addInfo ? { info: {
59
+ line: (node.loc?.start.line || 1) - 1 + this.lineOffset,
60
+ column: node.loc?.start.column || 0,
61
+ ...options.comment ? { comment: options.comment } : {}
62
+ } } : {}
63
+ });
64
+ else this.nodes.set(label, {
65
+ label,
66
+ type: NodeType.var,
67
+ ...this.addInfo ? { info: {
68
+ line: (node.loc?.start.line || 1) - 1 + this.lineOffset,
69
+ column: node.loc?.start.column || 0,
70
+ ...options.comment ? { comment: options.comment } : {}
71
+ } } : {}
72
+ });
73
+ }
74
+ addTypedNode(label, node) {
75
+ this.nodes.set(label, {
76
+ label,
77
+ type: node.type,
78
+ ...this.addInfo ? { info: { ...node.info || {} } } : {}
79
+ });
80
+ }
81
+ getNode(label) {
82
+ return this.nodes.get(label);
83
+ }
84
+ map(graph) {
85
+ const nodes = new Set(Array.from(graph.nodes).map((node) => {
86
+ return this.nodes.get(node);
87
+ }).filter((node) => !!node));
88
+ const edges = new Map(Array.from(graph.edges).map(([from, to]) => {
89
+ const labelMap = /* @__PURE__ */ new Map();
90
+ for (const item of to) {
91
+ const node = this.nodes.get(item.label);
92
+ if (!node) continue;
93
+ const existing = labelMap.get(item.label);
94
+ if (!existing || existing.type === "get" && item.type === "set") labelMap.set(item.label, {
95
+ node,
96
+ type: item.type
97
+ });
98
+ }
99
+ const items = Array.from(labelMap.values());
100
+ return [this.nodes.get(from), new Set(items)];
101
+ }));
102
+ return {
103
+ nodes,
104
+ edges
105
+ };
106
+ }
107
+ };
108
+ function getComment(node) {
109
+ let comment = "";
110
+ node.leadingComments?.forEach((_comment) => {
111
+ if (_comment.loc.end.line > node.loc.start.line) return;
112
+ if (_comment.value.trim().startsWith("*")) comment += `${_comment.value.trim().replace(/^\s*\*+\s*\**/gm, "").trim()}\n`;
113
+ });
114
+ node.trailingComments?.forEach((_comment) => {
115
+ if (_comment.loc.end.line > node.loc.start.line) return;
116
+ if (_comment.value.trim().startsWith("*")) comment += `${_comment.value.trim().replace(/^\s*\*+\s*\**/gm, "").trim()}\n`;
117
+ else comment += `${_comment.value.trim()}\n`;
118
+ });
119
+ return comment.trim();
120
+ }
121
+ function isWritingNode(path) {
122
+ const assignParent = path.findParent((p) => p.isAssignmentExpression());
123
+ if (assignParent) {
124
+ const leftNode = assignParent.node.left;
125
+ if (leftNode.start != null && path.node.start >= leftNode.start && path.node.end <= leftNode.end) return true;
126
+ }
127
+ const updateParent = path.findParent((p) => p.isUpdateExpression());
128
+ if (updateParent) {
129
+ const argNode = updateParent.node.argument;
130
+ if (argNode.start != null && path.node.start >= argNode.start && path.node.end <= argNode.end) return true;
131
+ }
132
+ return false;
133
+ }
134
+ function isCallingNode(path) {
135
+ const parent = path.parentPath;
136
+ if (parent && parent.isCallExpression()) return parent.node.callee === path.node;
137
+ return false;
138
+ }
139
+ function getRelationType(path) {
140
+ if (path.node.type === "Identifier" && isCallingNode(path)) return "call";
141
+ if (isWritingNode(path)) return "set";
142
+ return "get";
143
+ }
144
+
145
+ //#endregion
146
+ //#region src/analyze/setupScript.ts
147
+ const traverse$3 = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
148
+ const ignoreFunctionsName = [
149
+ "defineProps",
150
+ "defineEmits",
151
+ "withDefaults"
152
+ ];
153
+ const watchHooks = [
154
+ "watch",
155
+ "watchArray",
156
+ "watchAtMost",
157
+ "watchDebounced",
158
+ "watchDeep",
159
+ "watchIgnorable",
160
+ "watchImmediate",
161
+ "watchOnce",
162
+ "watchPausable",
163
+ "watchThrottled",
164
+ "watchTriggerable",
165
+ "watchWithFilter"
166
+ ];
167
+ function processSetup(ast, parentScope, parentPath, _spread, _lineOffset = 0) {
168
+ const spread = _spread || [];
169
+ const nodeCollection = new NodeCollection(_lineOffset);
170
+ const graph = {
171
+ nodes: /* @__PURE__ */ new Set(),
172
+ edges: /* @__PURE__ */ new Map(),
173
+ spread: /* @__PURE__ */ new Map()
174
+ };
175
+ traverse$3(ast, {
176
+ VariableDeclaration(path) {
177
+ path.node.declarations.forEach((declaration) => {
178
+ if (declaration.id.type === "ArrayPattern") declaration.id.elements.forEach((element) => {
179
+ if (element?.type === "Identifier") {
180
+ const name = element.name;
181
+ const binding = path.scope.getBinding(name);
182
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent) && !(declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && ignoreFunctionsName.includes(declaration.init?.callee.name))) {
183
+ graph.nodes.add(name);
184
+ nodeCollection.addNode(name, element, { comment: getComment(path.node) });
185
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
186
+ }
187
+ }
188
+ if (element?.type === "RestElement" && element.argument.type === "Identifier") {
189
+ const name = element.argument.name;
190
+ const binding = path.scope.getBinding(name);
191
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent) && !(declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && ignoreFunctionsName.includes(declaration.init?.callee.name))) {
192
+ graph.nodes.add(name);
193
+ nodeCollection.addNode(name, element.argument, { comment: getComment(path.node) });
194
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
195
+ }
196
+ }
197
+ });
198
+ if (declaration.id.type === "ObjectPattern") declaration.id.properties.forEach((property) => {
199
+ if (property.type === "ObjectProperty" && property.value.type === "Identifier") {
200
+ const name = property.value.name;
201
+ const binding = path.scope.getBinding(name);
202
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent) && !(declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && ignoreFunctionsName.includes(declaration.init?.callee.name))) {
203
+ graph.nodes.add(name);
204
+ nodeCollection.addNode(name, property.value, { comment: getComment(property) });
205
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
206
+ }
207
+ }
208
+ if (property.type === "RestElement" && property.argument.type === "Identifier") {
209
+ const name = property.argument.name;
210
+ const binding = path.scope.getBinding(name);
211
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent) && !(declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && ignoreFunctionsName.includes(declaration.init?.callee.name))) {
212
+ graph.nodes.add(name);
213
+ nodeCollection.addNode(name, property.argument, { comment: getComment(property) });
214
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
215
+ }
216
+ }
217
+ });
218
+ if (declaration.id?.type === "Identifier") {
219
+ const name = declaration.id.name;
220
+ const binding = path.scope.getBinding(name);
221
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent) && !(declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && ignoreFunctionsName.includes(declaration.init?.callee.name))) {
222
+ graph.nodes.add(name);
223
+ nodeCollection.addNode(name, declaration, { comment: getComment(path.node) });
224
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
225
+ if (spread.includes(name)) {
226
+ if (declaration.init?.type === "ObjectExpression") declaration.init?.properties.forEach((prop) => {
227
+ if ((prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && prop.key.type === "Identifier") {
228
+ const keyName = prop.key.name;
229
+ graph.nodes.add(keyName);
230
+ nodeCollection.addNode(keyName, prop, { comment: getComment(prop) });
231
+ if (!graph.edges.get(keyName)) graph.edges.set(keyName, /* @__PURE__ */ new Set());
232
+ if (graph.spread.has(name)) graph.spread.get(name)?.add(keyName);
233
+ else graph.spread.set(name, new Set([keyName]));
234
+ } else if (prop.type === "SpreadElement") console.warn("not support spread in spread");
235
+ });
236
+ if (declaration.init?.type === "CallExpression" && declaration.init?.callee.type === "Identifier" && declaration.init?.callee.name === "reactive") {
237
+ const arg = declaration.init?.arguments[0];
238
+ if (arg.type === "ObjectExpression") arg.properties.forEach((prop) => {
239
+ if ((prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && prop.key.type === "Identifier") {
240
+ const keyName = prop.key.name;
241
+ graph.nodes.add(keyName);
242
+ nodeCollection.addNode(keyName, prop, { comment: getComment(prop) });
243
+ if (!graph.edges.get(keyName)) graph.edges.set(keyName, /* @__PURE__ */ new Set());
244
+ if (graph.spread.has(name)) graph.spread.get(name)?.add(keyName);
245
+ else graph.spread.set(name, new Set([keyName]));
246
+ } else if (prop.type === "SpreadElement") console.warn("not support spread in spread");
247
+ });
248
+ }
249
+ }
250
+ }
251
+ }
252
+ });
253
+ },
254
+ FunctionDeclaration(path) {
255
+ const name = path.node.id?.name;
256
+ if (name) {
257
+ const binding = path.scope.getBinding(name);
258
+ if (binding && (path.parent.type === "Program" || parentPath?.type === "ObjectMethod" && parentPath.body === path.parent)) {
259
+ graph.nodes.add(name);
260
+ nodeCollection.addNode(name, path.node.id, {
261
+ isMethod: true,
262
+ comment: getComment(path.node)
263
+ });
264
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
265
+ }
266
+ }
267
+ }
268
+ }, parentScope, parentPath);
269
+ function traverseHooks(node, patentScope) {
270
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" || node.type === "CallExpression" && node.callee.type === "Identifier") {
271
+ const hookName = (() => {
272
+ if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier") return node.expression.callee.name;
273
+ if (node.type === "CallExpression" && node.callee.type === "Identifier") return node.callee.name;
274
+ })() || "";
275
+ if (!hookName) return;
276
+ const hookBinding = patentScope.getBinding(hookName);
277
+ if (!(hookBinding === void 0 || hookBinding?.scope.block.type === "Program" || parentScope === hookBinding?.scope)) return;
278
+ const expression = node.type === "ExpressionStatement" ? node.expression : node;
279
+ const watchArgs = /* @__PURE__ */ new Set();
280
+ if (hookName === "provide") traverse$3(expression, { Identifier(path1) {
281
+ const binding = path1.scope.getBinding(path1.node.name);
282
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
283
+ const _node = nodeCollection.getNode(path1.node.name);
284
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
285
+ else if (_node) _node.info = {
286
+ ..._node?.info,
287
+ used: new Set([hookName])
288
+ };
289
+ }
290
+ } }, patentScope, node);
291
+ else if (watchHooks.includes(hookName)) if (expression.arguments[0].type === "Identifier") {
292
+ const binding = patentScope.getBinding(expression.arguments[0].name);
293
+ if (graph.nodes.has(expression.arguments[0].name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) watchArgs.add(expression.arguments[0]);
294
+ } else traverse$3(expression.arguments[0], { Identifier(path1) {
295
+ const binding = path1.scope.getBinding(path1.node.name);
296
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) watchArgs.add(path1.node);
297
+ } }, patentScope, node);
298
+ else if (hookName === "useEffect" && expression.arguments[1].type === "ArrayExpression") traverse$3(expression.arguments[1], { Identifier(path1) {
299
+ const binding = path1.scope.getBinding(path1.node.name);
300
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) watchArgs.add(path1.node);
301
+ } }, patentScope, node);
302
+ expression.arguments.forEach((argNode, index) => {
303
+ if (watchHooks.includes(hookName) && index === 0 && argNode.type === "Identifier") {
304
+ const _node = nodeCollection.getNode(argNode.name);
305
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
306
+ else if (_node) _node.info = {
307
+ ..._node?.info,
308
+ used: new Set([hookName])
309
+ };
310
+ return;
311
+ }
312
+ if (argNode.type === "Identifier") {
313
+ const binding = patentScope.getBinding(argNode.name);
314
+ if (graph.nodes.has(argNode.name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
315
+ const _node = nodeCollection.getNode(argNode.name);
316
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
317
+ else if (_node) _node.info = {
318
+ ..._node?.info,
319
+ used: new Set([hookName])
320
+ };
321
+ }
322
+ } else traverse$3(argNode, { Identifier(path1) {
323
+ const binding = path1.scope.getBinding(path1.node.name);
324
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) {
325
+ if ([...watchHooks, "useEffect"].includes(hookName) && watchArgs.size > 0) {
326
+ const watchArgsNames = Array.from(watchArgs).map((arg) => arg.name);
327
+ watchArgs.forEach((watchArg) => {
328
+ if (!watchArgsNames.includes(path1.node.name)) graph.edges.get(watchArg.name)?.add({
329
+ label: path1.node.name,
330
+ type: getRelationType(path1)
331
+ });
332
+ });
333
+ }
334
+ const _node = nodeCollection.getNode(path1.node.name);
335
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
336
+ else if (_node) _node.info = {
337
+ ..._node?.info,
338
+ used: new Set([hookName])
339
+ };
340
+ }
341
+ } }, patentScope, node);
342
+ });
343
+ }
344
+ }
345
+ traverse$3(ast, {
346
+ FunctionDeclaration(path) {
347
+ const name = path.node.id?.name;
348
+ if (name && graph.nodes.has(name)) traverse$3(path.node.body, {
349
+ Identifier(path1) {
350
+ const binding = path1.scope.getBinding(path1.node.name);
351
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
352
+ label: path1.node.name,
353
+ type: getRelationType(path1)
354
+ });
355
+ },
356
+ MemberExpression(path1) {
357
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
358
+ const binding = path1.scope.getBinding(path1.node.object.name);
359
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
360
+ label: path1.node.property.name,
361
+ type: getRelationType(path1)
362
+ });
363
+ }
364
+ }
365
+ }, path.scope, path);
366
+ },
367
+ VariableDeclarator(path) {
368
+ if (path.node.init) {
369
+ if (path.node.id.type === "ArrayPattern") path.node.id.elements.forEach((element) => {
370
+ if (element?.type === "Identifier") {
371
+ const name = element.name;
372
+ if (name && graph.nodes.has(name) && path.node.init?.type === "CallExpression") traverse$3(path.node.init, {
373
+ Identifier(path1) {
374
+ const binding = path1.scope.getBinding(path1.node.name);
375
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
376
+ label: path1.node.name,
377
+ type: getRelationType(path1)
378
+ });
379
+ },
380
+ MemberExpression(path1) {
381
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
382
+ const binding = path1.scope.getBinding(path1.node.object.name);
383
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
384
+ label: path1.node.property.name,
385
+ type: getRelationType(path1)
386
+ });
387
+ }
388
+ }
389
+ }, path.scope, path);
390
+ }
391
+ });
392
+ else if (path.node.id.type === "ObjectPattern") path.node.id.properties.forEach((property) => {
393
+ if (property.type === "ObjectProperty" && property.value.type === "Identifier") {
394
+ const name = property.value.name;
395
+ if (name && graph.nodes.has(name) && path.node.init) traverse$3(path.node.init, {
396
+ Identifier(path1) {
397
+ const binding = path1.scope.getBinding(path1.node.name);
398
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
399
+ label: path1.node.name,
400
+ type: getRelationType(path1)
401
+ });
402
+ },
403
+ MemberExpression(path1) {
404
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
405
+ const binding = path1.scope.getBinding(path1.node.object.name);
406
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
407
+ label: path1.node.property.name,
408
+ type: getRelationType(path1)
409
+ });
410
+ }
411
+ }
412
+ }, path.scope, path);
413
+ }
414
+ });
415
+ else if ([
416
+ "CallExpression",
417
+ "ArrowFunctionExpression",
418
+ "FunctionDeclaration"
419
+ ].includes(path.node.init.type) && path.node.id.type === "Identifier") {
420
+ if (path.node.init.type === "CallExpression" && path.node.init.callee.type === "Identifier" && [...watchHooks, "watchEffect"].includes(path.node.init.callee.name)) traverseHooks(path.node.init, path.scope);
421
+ const name = path.node.id?.name;
422
+ if (name && graph.nodes.has(name)) traverse$3(path.node.init, {
423
+ Identifier(path1) {
424
+ const binding = path1.scope.getBinding(path1.node.name);
425
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
426
+ label: path1.node.name,
427
+ type: getRelationType(path1)
428
+ });
429
+ },
430
+ MemberExpression(path1) {
431
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
432
+ const binding = path1.scope.getBinding(path1.node.object.name);
433
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
434
+ label: path1.node.property.name,
435
+ type: getRelationType(path1)
436
+ });
437
+ }
438
+ }
439
+ }, path.scope, path);
440
+ } else if (path.node.id.type === "Identifier") {
441
+ const name = path.node.id.name;
442
+ if (path.node.init.type === "Identifier") {
443
+ const binding = path.scope.getBinding(path.node.init.name);
444
+ if (graph.nodes.has(path.node.init.name) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
445
+ label: path.node.init.name,
446
+ type: getRelationType(path)
447
+ });
448
+ } else traverse$3(path.node.init, { Identifier(path1) {
449
+ const binding = path1.scope.getBinding(path1.node.name);
450
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
451
+ label: path1.node.name,
452
+ type: getRelationType(path1)
453
+ });
454
+ } }, path.scope, path);
455
+ }
456
+ }
457
+ },
458
+ ObjectMethod(path) {
459
+ if (path.node.key.type === "Identifier" && graph.nodes.has(path.node.key.name)) {
460
+ const name = path.node.key.name;
461
+ traverse$3(path.node.body, {
462
+ Identifier(path1) {
463
+ const binding = path1.scope.getBinding(path1.node.name);
464
+ if (graph.nodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node) && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
465
+ label: path1.node.name,
466
+ type: getRelationType(path1)
467
+ });
468
+ },
469
+ MemberExpression(path1) {
470
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
471
+ const binding = path1.scope.getBinding(path1.node.object.name);
472
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
473
+ label: path1.node.property.name,
474
+ type: getRelationType(path1)
475
+ });
476
+ }
477
+ }
478
+ }, path.scope, path);
479
+ }
480
+ },
481
+ ObjectProperty(path) {
482
+ if (path.node.key.type === "Identifier" && graph.nodes.has(path.node.key.name)) {
483
+ const name = path.node.key.name;
484
+ traverse$3(path.node.value, { MemberExpression(path1) {
485
+ if (path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name)) {
486
+ const binding = path1.scope.getBinding(path1.node.object.name);
487
+ if (spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier" && (binding?.scope.block.type === "Program" || parentScope === binding?.scope)) graph.edges.get(name)?.add({
488
+ label: path1.node.property.name,
489
+ type: getRelationType(path1)
490
+ });
491
+ }
492
+ } }, path.scope, path);
493
+ }
494
+ },
495
+ ExpressionStatement(path) {
496
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "CallExpression" && path.node.expression.callee.type === "Identifier") {
497
+ const name = path.node.expression.callee.name;
498
+ if (graph.nodes.has(name) && path.scope.block.type === "Program") {
499
+ const _node = nodeCollection.getNode(name);
500
+ if (_node?.info?.used) _node?.info?.used?.add("Call Expression");
501
+ else if (_node) _node.info = {
502
+ ..._node?.info,
503
+ used: new Set(["Call Expression"])
504
+ };
505
+ } else traverseHooks(path.node.expression, path.scope);
506
+ }
507
+ if (path.type === "ExpressionStatement" && path.node.expression.type === "AssignmentExpression" && path.node.expression.right.type === "CallExpression" && path.node.expression.right.callee.type === "Identifier") traverseHooks(path.node.expression.right, path.scope);
508
+ }
509
+ }, parentScope, parentPath);
510
+ return {
511
+ graph,
512
+ nodeCollection
513
+ };
514
+ }
515
+ function analyze$1(content, lineOffset = 0, jsx = false) {
516
+ const ast = (0, __vue_compiler_sfc.babelParse)(content, {
517
+ sourceType: "module",
518
+ plugins: ["typescript", ...jsx ? ["jsx"] : []]
519
+ });
520
+ const { graph, nodeCollection } = processSetup(ast, void 0, void 0, void 0, lineOffset);
521
+ return nodeCollection.map(graph);
522
+ }
523
+
524
+ //#endregion
525
+ //#region src/analyze/options.ts
526
+ const traverse$2 = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
527
+ const vueLifeCycleHooks = [
528
+ "beforeCreate",
529
+ "created",
530
+ "beforeMount",
531
+ "mounted",
532
+ "beforeUpdate",
533
+ "updated",
534
+ "beforeDestroy",
535
+ "destroyed",
536
+ "activated",
537
+ "deactivated",
538
+ "errorCaptured",
539
+ "renderTracked",
540
+ "renderTriggered",
541
+ "provide"
542
+ ];
543
+ function analyze(content, lineOffset = 0, jsx = false) {
544
+ const ast = (0, __vue_compiler_sfc.babelParse)(content, {
545
+ sourceType: "module",
546
+ plugins: ["typescript", ...jsx ? ["jsx"] : []]
547
+ });
548
+ let nodeCollection = new NodeCollection(lineOffset);
549
+ const tNodes = /* @__PURE__ */ new Map();
550
+ const graph = {
551
+ nodes: /* @__PURE__ */ new Set(),
552
+ edges: /* @__PURE__ */ new Map()
553
+ };
554
+ /** used in render block or setup return */
555
+ const nodesUsedInTemplate = /* @__PURE__ */ new Set();
556
+ function process(node, path) {
557
+ traverse$2(node, {
558
+ ObjectProperty(path1) {
559
+ if (path.node.declaration.type === "ObjectExpression" && path1.parent === path.node.declaration || path.node.declaration.type === "CallExpression" && path1.parent === path.node.declaration.arguments[0]) {
560
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "data" && (path1.node.value.type === "ArrowFunctionExpression" || path1.node.value.type === "FunctionExpression")) {
561
+ const dataNode = path1.node.value;
562
+ traverse$2(dataNode, { ReturnStatement(path2) {
563
+ if (path2.parent === dataNode.body) {
564
+ if (path2.node.argument?.type === "ObjectExpression") path2.node.argument.properties.forEach((prop) => {
565
+ if (prop.type === "ObjectProperty") {
566
+ if (prop.key.type === "Identifier") {
567
+ const name = prop.key.name;
568
+ graph.nodes.add(name);
569
+ tNodes.set(name, prop.key);
570
+ nodeCollection.addNode(name, prop, { comment: getComment(prop) });
571
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
572
+ }
573
+ }
574
+ });
575
+ }
576
+ } }, path1.scope, path1);
577
+ }
578
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "computed") {
579
+ const computedNode = path1.node;
580
+ if (computedNode.value.type === "ObjectExpression") computedNode.value.properties.forEach((prop) => {
581
+ if (prop.type === "ObjectProperty" || prop.type === "ObjectMethod") {
582
+ if (prop.key.type === "Identifier") {
583
+ const name = prop.key.name;
584
+ graph.nodes.add(name);
585
+ tNodes.set(name, prop.key);
586
+ nodeCollection.addNode(name, prop, {
587
+ isComputed: true,
588
+ comment: getComment(prop)
589
+ });
590
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
591
+ }
592
+ }
593
+ });
594
+ }
595
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "methods") {
596
+ const methodsNode = path1.node;
597
+ if (methodsNode.value.type === "ObjectExpression") methodsNode.value.properties.forEach((prop) => {
598
+ if (prop.type === "ObjectProperty" || prop.type === "ObjectMethod") {
599
+ if (prop.key.type === "Identifier") {
600
+ const name = prop.key.name;
601
+ graph.nodes.add(name);
602
+ tNodes.set(name, prop.key);
603
+ nodeCollection.addNode(name, prop, {
604
+ isMethod: true,
605
+ comment: getComment(prop)
606
+ });
607
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
608
+ }
609
+ }
610
+ });
611
+ }
612
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "render" && (path1.node.value.type === "ArrowFunctionExpression" || path1.node.value.type === "FunctionExpression")) traverse$2(path1.node.value, { ReturnStatement(path2) {
613
+ const templateNode = path2.node;
614
+ traverse$2(templateNode, { MemberExpression(path3) {
615
+ if (path3.node.object && path3.node.object.type === "ThisExpression") {
616
+ if (path3.node.property && path3.node.property.type === "Identifier") nodesUsedInTemplate.add(path3.node.property.name);
617
+ }
618
+ } }, path2.scope, path2);
619
+ } }, path1.scope, path1);
620
+ }
621
+ },
622
+ ObjectMethod(path1) {
623
+ if (path.node.declaration.type === "ObjectExpression" && path1.parent === path.node.declaration || path.node.declaration.type === "CallExpression" && path1.parent === path.node.declaration.arguments[0]) {
624
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "setup") {
625
+ const setupNode = path1.node;
626
+ const spread = [];
627
+ traverse$2(setupNode, { ReturnStatement(path2) {
628
+ if (path2.node.argument?.type === "ObjectExpression") {
629
+ const returnNode = path2.node.argument;
630
+ traverse$2(returnNode, { SpreadElement(path3) {
631
+ if (path3.node.argument.type === "CallExpression" && path3.node.argument.callee.type === "Identifier" && path3.node.argument.callee.name === "toRefs" && path3.node.argument.arguments[0].type === "Identifier") spread.push(path3.node.argument.arguments[0].name);
632
+ else if (path3.node.argument.type === "Identifier") spread.push(path3.node.argument.name);
633
+ } }, path2.scope, path2);
634
+ }
635
+ if (path2.node.argument?.type === "FunctionExpression" || path2.node.argument?.type === "ArrowFunctionExpression") {
636
+ const templateNode = path2.node.argument.body;
637
+ traverse$2(templateNode, {
638
+ Identifier(path3) {
639
+ const binding = path3.scope.getBinding(path3.node.name);
640
+ if (binding?.scope === path1.scope) nodesUsedInTemplate.add(path3.node.name);
641
+ },
642
+ JSXIdentifier(path3) {
643
+ const binding = path3.scope.getBinding(path3.node.name);
644
+ if (binding?.scope === path1.scope) nodesUsedInTemplate.add(path3.node.name);
645
+ }
646
+ }, path2.scope, path2);
647
+ }
648
+ } }, path1.scope, path1);
649
+ const { graph: { nodes: tempNodes, edges: tempEdges, spread: tempSpread }, nodeCollection: tempNodeCollection } = processSetup(setupNode, path1.scope, setupNode, spread, lineOffset);
650
+ traverse$2(setupNode, { ReturnStatement(path2) {
651
+ if (path2.scope !== path1.scope) return;
652
+ if (path2.node.argument?.type === "ObjectExpression") {
653
+ const returnNode = path2.node.argument;
654
+ traverse$2(returnNode, {
655
+ ObjectProperty(path3) {
656
+ if (path3.parent === returnNode) {
657
+ if (path3.node.key.type === "Identifier" && path3.node.value.type === "Identifier" && tempNodes.has(path3.node.value.name)) {
658
+ const valName = path3.node.value.name;
659
+ if (!graph.nodes.has(valName)) {
660
+ graph.nodes.add(valName);
661
+ tNodes.set(valName, path3.node.value);
662
+ nodeCollection.addTypedNode(valName, tempNodeCollection.nodes.get(valName));
663
+ }
664
+ if (!graph.edges.has(valName)) graph.edges.set(valName, new Set([...Array.from(tempEdges.get(valName) || /* @__PURE__ */ new Set())]));
665
+ const name = path3.node.key.name;
666
+ if (name !== valName) {
667
+ graph.nodes.add(name);
668
+ tNodes.set(name, path3.node.key);
669
+ nodeCollection.addNode(name, path3.node.key, { comment: getComment(path3.node) });
670
+ graph.edges.set(name, new Set([{
671
+ label: valName,
672
+ type: getRelationType(path3)
673
+ }]));
674
+ }
675
+ }
676
+ }
677
+ },
678
+ SpreadElement(path3) {
679
+ if (path3.node.argument.type === "CallExpression" && path3.node.argument.callee.type === "Identifier" && path3.node.argument.callee.name === "toRefs" && path3.node.argument.arguments[0].type === "Identifier" && tempSpread.get(path3.node.argument.arguments[0].name)) tempSpread.get(path3.node.argument.arguments[0].name)?.forEach((name) => {
680
+ graph.nodes.add(name);
681
+ tNodes.set(name, path3.node.argument.arguments[0]);
682
+ nodeCollection.addTypedNode(name, tempNodeCollection.nodes.get(name));
683
+ if (!graph.edges.get(name)) {
684
+ graph.edges.set(name, /* @__PURE__ */ new Set());
685
+ tempEdges.get(name)?.forEach((edge) => {
686
+ graph.edges.get(name)?.add(edge);
687
+ });
688
+ }
689
+ });
690
+ else if (path3.node.argument.type === "Identifier" && tempSpread.get(path3.node.argument.name)) tempSpread.get(path3.node.argument.name)?.forEach((name) => {
691
+ graph.nodes.add(name);
692
+ tNodes.set(name, path3.node.argument);
693
+ nodeCollection.addTypedNode(name, tempNodeCollection.nodes.get(name));
694
+ if (!graph.edges.get(name)) {
695
+ graph.edges.set(name, /* @__PURE__ */ new Set());
696
+ tempEdges.get(name)?.forEach((edge) => {
697
+ graph.edges.get(name)?.add(edge);
698
+ });
699
+ }
700
+ });
701
+ }
702
+ }, path2.scope, path2);
703
+ } else {
704
+ graph.edges = tempEdges;
705
+ graph.nodes = tempNodes;
706
+ nodeCollection = tempNodeCollection;
707
+ }
708
+ } }, path1.scope, path1);
709
+ }
710
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "data") {
711
+ const dataNode = path1.node;
712
+ traverse$2(dataNode, { ReturnStatement(path2) {
713
+ if (path2.parent === dataNode.body) {
714
+ if (path2.node.argument?.type === "ObjectExpression") path2.node.argument.properties.forEach((prop) => {
715
+ if (prop.type === "ObjectProperty") {
716
+ if (prop.key.type === "Identifier") {
717
+ const name = prop.key.name;
718
+ graph.nodes.add(name);
719
+ tNodes.set(name, prop.key);
720
+ nodeCollection.addNode(name, prop, { comment: getComment(prop) });
721
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
722
+ }
723
+ }
724
+ });
725
+ }
726
+ } }, path1.scope, path1);
727
+ }
728
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "render") traverse$2(path1.node, { ReturnStatement(path2) {
729
+ const templateNode = path2.node;
730
+ traverse$2(templateNode, { MemberExpression(path3) {
731
+ if (path3.node.object && path3.node.object.type === "ThisExpression") {
732
+ if (path3.node.property && path3.node.property.type === "Identifier") nodesUsedInTemplate.add(path3.node.property.name);
733
+ }
734
+ } }, path2.scope, path2);
735
+ } }, path1.scope, path1);
736
+ }
737
+ }
738
+ }, path.scope, path);
739
+ traverse$2(node, {
740
+ ObjectMethod(path1) {
741
+ if (path.node.declaration.type === "ObjectExpression" && path1.parent === path.node.declaration || path.node.declaration.type === "CallExpression" && path1.parent === path.node.declaration.arguments[0]) {
742
+ if (path1.node.key.type === "Identifier" && vueLifeCycleHooks.includes(path1.node.key.name)) {
743
+ const hookName = path1.node.key.name;
744
+ traverse$2(path1.node.body, { MemberExpression(path2) {
745
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") {
746
+ const _node = nodeCollection.getNode(path2.node.property.name);
747
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
748
+ else if (_node) _node.info = {
749
+ ..._node?.info,
750
+ used: new Set([hookName])
751
+ };
752
+ }
753
+ } }, path1.scope, path1);
754
+ }
755
+ }
756
+ },
757
+ ObjectProperty(path1) {
758
+ if (path.node.declaration.type === "ObjectExpression" && path1.parent === path.node.declaration || path.node.declaration.type === "CallExpression" && path1.parent === path.node.declaration.arguments[0]) {
759
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "computed") {
760
+ const computedNode = path1.node;
761
+ if (computedNode.value.type === "ObjectExpression") computedNode.value.properties.forEach((prop) => {
762
+ if (prop.type === "ObjectMethod" && prop.key.type === "Identifier") {
763
+ const name = prop.key.name;
764
+ traverse$2(prop, { MemberExpression(path2) {
765
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") graph.edges.get(name)?.add({
766
+ label: path2.node.property.name,
767
+ type: getRelationType(path2)
768
+ });
769
+ } }, path1.scope, path1);
770
+ }
771
+ if (prop.type === "ObjectProperty" && prop.key.type === "Identifier" && prop.value.type === "ObjectExpression") {
772
+ const name = prop.key.name;
773
+ prop.value.properties.forEach((prop1) => {
774
+ if (prop1.type === "ObjectProperty" && prop1.key.type === "Identifier" && prop1.key.name === "get") traverse$2(prop1, { MemberExpression(path2) {
775
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") graph.edges.get(name)?.add({
776
+ label: path2.node.property.name,
777
+ type: getRelationType(path2)
778
+ });
779
+ } }, path1.scope, path1);
780
+ });
781
+ }
782
+ });
783
+ }
784
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "methods") {
785
+ const methodsNode = path1.node;
786
+ if (methodsNode.value.type === "ObjectExpression") methodsNode.value.properties.forEach((prop) => {
787
+ if ((prop.type === "ObjectMethod" || prop.type === "ObjectProperty") && prop.key.type === "Identifier") {
788
+ const name = prop.key.name;
789
+ traverse$2(prop, { MemberExpression(path2) {
790
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") graph.edges.get(name)?.add({
791
+ label: path2.node.property.name,
792
+ type: getRelationType(path2)
793
+ });
794
+ } }, path1.scope, path1);
795
+ }
796
+ });
797
+ }
798
+ if (path1.node.key.type === "Identifier" && [...watchHooks, ...vueLifeCycleHooks].includes(path1.node.key.name)) {
799
+ const hookName = path1.node.key.name;
800
+ if (watchHooks.includes(hookName) && path1.node.value.type === "ObjectExpression") path1.node.value.properties.forEach((prop) => {
801
+ if ((prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && (prop.key.type === "Identifier" || prop.key.type === "StringLiteral")) {
802
+ const keyName = prop.key.type === "Identifier" ? prop.key.name : prop.key.type === "StringLiteral" ? prop.key.value.split(".")[0] : "";
803
+ const watchArg = tNodes.get(keyName);
804
+ const _node = nodeCollection.getNode(keyName);
805
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
806
+ else if (_node) _node.info = {
807
+ ..._node?.info,
808
+ used: new Set([hookName])
809
+ };
810
+ traverse$2(path1.node.value, { MemberExpression(path2) {
811
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") {
812
+ if (watchArg && watchArg.name !== path2.node.property.name) graph.edges.get(watchArg.name)?.add({
813
+ label: path2.node.property.name,
814
+ type: getRelationType(path2)
815
+ });
816
+ }
817
+ } }, path1.scope, path1);
818
+ }
819
+ });
820
+ else traverse$2(path1.node.value, { MemberExpression(path2) {
821
+ if (path2.node.object.type === "ThisExpression" && path2.node.property.type === "Identifier") {
822
+ const _node = nodeCollection.getNode(path2.node.property.name);
823
+ if (_node?.info?.used) _node?.info?.used?.add(hookName);
824
+ else if (_node) _node.info = {
825
+ ..._node?.info,
826
+ used: new Set([hookName])
827
+ };
828
+ }
829
+ } }, path1.scope, path1);
830
+ }
831
+ }
832
+ }
833
+ }, path.scope, path);
834
+ }
835
+ traverse$2(ast, { ExportDefaultDeclaration(path) {
836
+ if (path.node.declaration.type === "ObjectExpression") process(path.node.declaration, path);
837
+ else if (path.node.declaration.type === "CallExpression" && path.node.declaration.callee.type === "Identifier" && path.node.declaration.callee.name === "defineComponent" && path.node.declaration.arguments[0].type === "ObjectExpression") process(path.node.declaration.arguments[0], path);
838
+ } });
839
+ return {
840
+ graph: nodeCollection.map(graph),
841
+ nodesUsedInTemplate
842
+ };
843
+ }
844
+
845
+ //#endregion
846
+ //#region src/analyze/style.ts
847
+ var LexerState = /* @__PURE__ */ function(LexerState$1) {
848
+ LexerState$1[LexerState$1["inParens"] = 0] = "inParens";
849
+ LexerState$1[LexerState$1["inSingleQuoteString"] = 1] = "inSingleQuoteString";
850
+ LexerState$1[LexerState$1["inDoubleQuoteString"] = 2] = "inDoubleQuoteString";
851
+ return LexerState$1;
852
+ }(LexerState || {});
853
+ function lexBinding(content, start) {
854
+ let state = LexerState.inParens;
855
+ let parenDepth = 0;
856
+ for (let i = start; i < content.length; i++) {
857
+ const char = content.charAt(i);
858
+ switch (state) {
859
+ case LexerState.inParens:
860
+ if (char === "'") state = LexerState.inSingleQuoteString;
861
+ else if (char === "\"") state = LexerState.inDoubleQuoteString;
862
+ else if (char === "(") parenDepth++;
863
+ else if (char === ")") if (parenDepth > 0) parenDepth--;
864
+ else return i;
865
+ break;
866
+ case LexerState.inSingleQuoteString:
867
+ if (char === "'") state = LexerState.inParens;
868
+ break;
869
+ case LexerState.inDoubleQuoteString:
870
+ if (char === "\"") state = LexerState.inParens;
871
+ break;
872
+ }
873
+ }
874
+ return null;
875
+ }
876
+ function normalizeExpression(exp) {
877
+ exp = exp.trim();
878
+ if (exp[0] === "'" && exp[exp.length - 1] === "'" || exp[0] === "\"" && exp[exp.length - 1] === "\"") return exp.slice(1, -1);
879
+ return exp;
880
+ }
881
+ const vBindRE = /v-bind\s*\(/g;
882
+ function analyze$2(styles) {
883
+ const nodes = /* @__PURE__ */ new Set();
884
+ styles.forEach((style) => {
885
+ let match;
886
+ const content = style.content.replace(/\/\*([\s\S]*?)\*\/|\/\/.*/g, "");
887
+ while (match = vBindRE.exec(content)) {
888
+ const start = match.index + match[0].length;
889
+ const end = lexBinding(content, start);
890
+ if (end !== null) {
891
+ const variable = normalizeExpression(content.slice(start, end));
892
+ nodes.add(variable);
893
+ }
894
+ }
895
+ });
896
+ return nodes;
897
+ }
898
+
899
+ //#endregion
900
+ //#region src/analyze/template.ts
901
+ const traverse$1 = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
902
+ function analyze$3(content) {
903
+ const id = "template";
904
+ const { code } = (0, __vue_compiler_sfc.compileTemplate)({
905
+ id,
906
+ source: content,
907
+ filename: `${id}.js`
908
+ });
909
+ const ast = (0, __vue_compiler_sfc.babelParse)(code, {
910
+ sourceType: "module",
911
+ plugins: ["typescript"]
912
+ });
913
+ const nodes = /* @__PURE__ */ new Set();
914
+ traverse$1(ast, {
915
+ MemberExpression(path) {
916
+ if (path.type === "MemberExpression") {
917
+ if (path.node.object && path.node.object.type === "Identifier" && path.node.object.name === "_ctx") {
918
+ if (path.node.property && path.node.property.type === "Identifier") nodes.add(path.node.property.name);
919
+ }
920
+ }
921
+ },
922
+ ObjectProperty(path) {
923
+ if (path.node.key.type === "Identifier" && path.node.key.name === "ref") {
924
+ if (path.node.value.type === "StringLiteral") {
925
+ const name = path.node.value.value;
926
+ if (name) nodes.add(name);
927
+ }
928
+ }
929
+ },
930
+ CallExpression(path) {
931
+ if (path.node.callee.type === "Identifier" && path.node.callee.name === "_resolveComponent") {
932
+ if (path.node.arguments[0].type === "StringLiteral") {
933
+ const name = path.node.arguments[0].value;
934
+ if (name) nodes.add(name);
935
+ }
936
+ }
937
+ }
938
+ });
939
+ return nodes;
940
+ }
941
+
942
+ //#endregion
943
+ //#region src/utils/traverse.ts
944
+ const traverse = __babel_traverse.default.default?.default || __babel_traverse.default.default || __babel_traverse.default;
945
+ /**
946
+ * 递归遍历如下结构:
947
+ * let { loc, loc: locd, loc: { start, end }, loc: { start: { line: { deep } }} } = node;
948
+ * 解出 loc, locd, start, end, deep
949
+ */
950
+ function rescureObjectPattern({ node, rootScope, res, parentScope, parentPath }) {
951
+ traverse(node, {
952
+ ObjectProperty(path1) {
953
+ if (path1.node.type === "ObjectProperty" && path1.node.key.type === "Identifier" && path1.node.value.type === "Identifier") {
954
+ const name = path1.node.value.name;
955
+ const _scope = path1.scope.getBinding(name)?.scope;
956
+ if (_scope && _scope === rootScope) res.push(path1.node.value);
957
+ } else if (path1.node.type === "ObjectProperty" && path1.node.key.type === "Identifier" && path1.node.value.type === "ObjectPattern") rescureObjectPattern({
958
+ node: path1.node.value,
959
+ rootScope,
960
+ res,
961
+ parentScope: path1.scope,
962
+ parentPath: path1
963
+ });
964
+ },
965
+ RestElement(path1) {
966
+ if (path1.node.argument.type === "Identifier") {
967
+ const name = path1.node.argument.name;
968
+ const _scope = path1.scope.getBinding(name)?.scope;
969
+ if (_scope && _scope === rootScope) res.push(path1.node.argument);
970
+ }
971
+ }
972
+ }, parentScope, parentPath);
973
+ }
974
+ /**
975
+ * 递归遍历如下结构:
976
+ * let [foo, [bar, baz]] = [1, [[2], 3]];
977
+ * 解出 foo, bar, baz
978
+ */
979
+ function rescureArrayPattern({ node, rootScope, res, parentScope, parentPath }) {
980
+ traverse(node, {
981
+ Identifier(path1) {
982
+ if (path1.node.type === "Identifier") {
983
+ const name = path1.node.name;
984
+ const _scope = path1.scope.getBinding(name)?.scope;
985
+ if (_scope && _scope === rootScope) res.push(path1.node);
986
+ }
987
+ },
988
+ ArrayPattern(path1) {
989
+ if (path1.node.type === "ArrayPattern") rescureArrayPattern({
990
+ node: path1.node,
991
+ rootScope,
992
+ res,
993
+ parentScope: path1.scope,
994
+ parentPath: path1
995
+ });
996
+ }
997
+ }, parentScope, parentPath);
998
+ }
999
+ function parseNodeIdentifierPattern({ path, rootScope, cb }) {
1000
+ if (path.node.id.type !== "Identifier") return;
1001
+ if (path.node.init?.type === "ArrowFunctionExpression" || path.node.init?.type === "FunctionExpression") cb?.({
1002
+ name: path.node.id.name,
1003
+ node: path.node,
1004
+ path,
1005
+ scope: rootScope
1006
+ });
1007
+ else cb?.({
1008
+ name: path.node.id.name,
1009
+ node: path.node,
1010
+ path,
1011
+ scope: rootScope
1012
+ });
1013
+ }
1014
+ function parseNodeObjectPattern({ path, rootScope, cb }) {
1015
+ if (path.node.id.type !== "ObjectPattern") return;
1016
+ path.node.id.properties.forEach((property) => {
1017
+ if (property.type === "ObjectProperty" && property.key.type === "Identifier" && property.value.type === "Identifier") cb?.({
1018
+ name: property.value.name,
1019
+ node: property,
1020
+ path,
1021
+ scope: rootScope
1022
+ });
1023
+ else if (property.type === "ObjectProperty" && property.key.type === "Identifier" && property.value.type === "AssignmentPattern") cb?.({
1024
+ name: property.key.name,
1025
+ node: property,
1026
+ path,
1027
+ scope: rootScope
1028
+ });
1029
+ else if (property.type === "RestElement" && property.argument.type === "Identifier") cb?.({
1030
+ name: property.argument.name,
1031
+ node: property,
1032
+ path,
1033
+ scope: rootScope
1034
+ });
1035
+ else if (property.type === "ObjectProperty" && property.key.type === "Identifier" && property.value.type === "ObjectPattern") {
1036
+ const res = [];
1037
+ rescureObjectPattern({
1038
+ node: property.value,
1039
+ rootScope,
1040
+ res,
1041
+ parentScope: path.scope,
1042
+ parentPath: path
1043
+ });
1044
+ res.forEach((r) => cb?.({
1045
+ name: r.name,
1046
+ node: r,
1047
+ path,
1048
+ scope: rootScope
1049
+ }));
1050
+ }
1051
+ });
1052
+ }
1053
+ function parseNodeArrayPattern({ path, rootScope, cb }) {
1054
+ if (path.node.id.type !== "ArrayPattern") return;
1055
+ path.node.id.elements.forEach((ele) => {
1056
+ if (ele?.type === "Identifier") cb?.({
1057
+ name: ele.name,
1058
+ node: ele,
1059
+ path,
1060
+ scope: rootScope
1061
+ });
1062
+ else if (ele?.type === "ArrayPattern") {
1063
+ const res = [];
1064
+ rescureArrayPattern({
1065
+ node: ele,
1066
+ rootScope,
1067
+ res,
1068
+ parentScope: path.scope,
1069
+ parentPath: path
1070
+ });
1071
+ res.forEach((r) => cb?.({
1072
+ name: r.name,
1073
+ node: r,
1074
+ path,
1075
+ scope: rootScope
1076
+ }));
1077
+ } else if (ele?.type === "AssignmentPattern") {
1078
+ if (ele.left.type === "Identifier") cb?.({
1079
+ name: ele.left.name,
1080
+ node: ele,
1081
+ path,
1082
+ scope: rootScope
1083
+ });
1084
+ } else if (ele?.type === "RestElement") {
1085
+ if (ele.argument.type === "Identifier") cb?.({
1086
+ name: ele.argument.name,
1087
+ node: ele,
1088
+ path,
1089
+ scope: rootScope
1090
+ });
1091
+ }
1092
+ });
1093
+ }
1094
+ function parseNodeFunctionPattern({ path, rootScope, cb }) {
1095
+ if (path.node.type !== "FunctionDeclaration") return;
1096
+ if (path.node.id?.type === "Identifier") cb?.({
1097
+ name: path.node.id.name,
1098
+ node: path.node,
1099
+ path,
1100
+ scope: rootScope
1101
+ });
1102
+ }
1103
+ function parseEdgeLeftIdentifierPattern({ path, rootScope, cb, collectionNodes, spread }) {
1104
+ if (!path.node.id || path.node.id.type !== "Identifier") return;
1105
+ if (path.node.init?.type && [
1106
+ "ArrowFunctionExpression",
1107
+ "FunctionExpression",
1108
+ "CallExpression",
1109
+ "ObjectExpression",
1110
+ "ArrayExpression"
1111
+ ].includes(path.node.init.type)) {
1112
+ if (collectionNodes.has(path.node.id.name) && path.scope.getBinding(path.node.id.name)?.scope === rootScope) {
1113
+ const name = path.node.id.name;
1114
+ traverse(path.node.init, {
1115
+ Identifier(path1) {
1116
+ const binding = path1.scope.getBinding(path1.node.name);
1117
+ if (binding?.scope === rootScope && collectionNodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node)) cb?.({
1118
+ fromName: name,
1119
+ toName: path1.node.name,
1120
+ path: path1,
1121
+ scope: rootScope,
1122
+ collectionNodes
1123
+ });
1124
+ },
1125
+ MemberExpression(path1) {
1126
+ if (spread?.length && path1.node.object.type === "Identifier" && spread.includes(path1.node.object.name) && path1.node.property.type === "Identifier") cb?.({
1127
+ fromName: name,
1128
+ toName: path1.node.property.name,
1129
+ toScope: path1.scope.getBinding(path1.node.object.name)?.scope,
1130
+ path: path1,
1131
+ scope: rootScope,
1132
+ collectionNodes
1133
+ });
1134
+ }
1135
+ }, path.scope, path);
1136
+ }
1137
+ }
1138
+ }
1139
+ function parseEdgeLeftObjectPattern({ path, rootScope, cb, collectionNodes }) {
1140
+ if (!path.node.id || path.node.id.type !== "ObjectPattern") return;
1141
+ if (path.node.init?.type && [
1142
+ "ArrowFunctionExpression",
1143
+ "FunctionExpression",
1144
+ "CallExpression",
1145
+ "ObjectExpression",
1146
+ "ArrayExpression"
1147
+ ].includes(path.node.init.type)) {
1148
+ const res = [];
1149
+ rescureObjectPattern({
1150
+ node: path.node.id,
1151
+ rootScope,
1152
+ res,
1153
+ parentScope: path.scope,
1154
+ parentPath: path
1155
+ });
1156
+ res.filter((r) => collectionNodes.has(r.name) && path.scope.getBinding(r.name)?.scope === rootScope);
1157
+ traverse(path.node.init, { Identifier(path1) {
1158
+ const binding = path1.scope.getBinding(path1.node.name);
1159
+ if (binding?.scope === rootScope && collectionNodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node)) res.forEach((r) => {
1160
+ cb?.({
1161
+ fromName: r.name,
1162
+ toName: path1.node.name,
1163
+ path: path1,
1164
+ scope: rootScope,
1165
+ collectionNodes
1166
+ });
1167
+ });
1168
+ } }, path.scope, path);
1169
+ }
1170
+ }
1171
+ function parseEdgeLeftArrayPattern({ path, rootScope, cb, collectionNodes }) {
1172
+ if (!path.node.id || path.node.id.type !== "ArrayPattern") return;
1173
+ if (path.node.init?.type && [
1174
+ "ArrowFunctionExpression",
1175
+ "FunctionExpression",
1176
+ "CallExpression",
1177
+ "ObjectExpression",
1178
+ "ArrayExpression"
1179
+ ].includes(path.node.init.type)) {
1180
+ const res = [];
1181
+ rescureArrayPattern({
1182
+ node: path.node.id,
1183
+ rootScope,
1184
+ res,
1185
+ parentScope: path.scope,
1186
+ parentPath: path
1187
+ });
1188
+ res.filter((r) => collectionNodes.has(r.name) && path.scope.getBinding(r.name)?.scope === rootScope);
1189
+ traverse(path.node.init, { Identifier(path1) {
1190
+ const binding = path1.scope.getBinding(path1.node.name);
1191
+ if (binding?.scope === rootScope && collectionNodes.has(path1.node.name) && (path1.parent.type !== "MemberExpression" && path1.parent.type !== "OptionalMemberExpression" || path1.parent.object === path1.node)) res.forEach((r) => {
1192
+ cb?.({
1193
+ fromName: r.name,
1194
+ toName: path1.node.name,
1195
+ path: path1,
1196
+ scope: rootScope,
1197
+ collectionNodes
1198
+ });
1199
+ });
1200
+ } }, path.scope, path);
1201
+ }
1202
+ }
1203
+ function parseEdgeFunctionPattern({ path, rootScope, cb, collectionNodes }) {
1204
+ if (!path.node.id) return;
1205
+ if (collectionNodes.has(path.node.id.name) && path.scope.getBinding(path.node.id.name)?.scope === rootScope) {
1206
+ const name = path.node.id.name;
1207
+ traverse(path.node.body, { Identifier(path1) {
1208
+ const binding = path1.scope.getBinding(path1.node.name);
1209
+ if (binding?.scope === rootScope && collectionNodes.has(path1.node.name)) cb?.({
1210
+ fromName: name,
1211
+ toName: path1.node.name,
1212
+ path: path1,
1213
+ scope: rootScope,
1214
+ collectionNodes
1215
+ });
1216
+ } }, path.scope, path);
1217
+ }
1218
+ }
1219
+ function parseReturnJsxPattern({ path, parentPath, cb }) {
1220
+ if (path.node.argument && ((path.node.argument.type === "ArrowFunctionExpression" || path.node.argument.type === "FunctionExpression") && (path.node.argument.body.type === "JSXElement" || path.node.argument.body.type === "JSXFragment") || path.node.argument.type === "JSXElement" || path.node.argument.type === "JSXFragment")) path.traverse({ Identifier(path1) {
1221
+ cb?.({
1222
+ name: path1.node.name,
1223
+ path: path1,
1224
+ parentPath
1225
+ });
1226
+ } });
1227
+ }
1228
+ function traverseSetup({ node, parentScope, parentPath }) {
1229
+ let path;
1230
+ traverse(node, { ObjectMethod(path1) {
1231
+ if (parentPath.node.declaration.type === "ObjectExpression" && path1.parent === parentPath.node.declaration || parentPath.node.declaration.type === "CallExpression" && path1.parent === parentPath.node.declaration.arguments[0]) {
1232
+ if (path1.node.key.type === "Identifier" && path1.node.key.name === "setup") path = path1;
1233
+ }
1234
+ } }, parentScope, parentPath);
1235
+ return path;
1236
+ }
1237
+ function collectionSpread({ path: path1, spread }) {
1238
+ path1.traverse({ ReturnStatement(path2) {
1239
+ if (path2.node.argument?.type === "ObjectExpression") {
1240
+ const returnNode = path2.node.argument;
1241
+ traverse(returnNode, { SpreadElement(path3) {
1242
+ if (path3.node.argument.type === "CallExpression" && path3.node.argument.callee.type === "Identifier" && path3.node.argument.callee.name === "toRefs" && path3.node.argument.arguments[0].type === "Identifier") spread.push(path3.node.argument.arguments[0].name);
1243
+ else if (path3.node.argument.type === "Identifier") spread.push(path3.node.argument.name);
1244
+ } }, path2.scope, path2);
1245
+ }
1246
+ } });
1247
+ }
1248
+ function addIdentifiesToGraphByScanReturn({ path: path1, graph, nodeCollection, tempNodeCollection, tempEdges }) {
1249
+ path1.traverse({ ReturnStatement(path2) {
1250
+ if (path2.node.argument?.type === "ObjectExpression") {
1251
+ const returnNode = path2.node.argument;
1252
+ traverse(returnNode, { ObjectProperty(path3) {
1253
+ if (path3.parent === returnNode) {
1254
+ if (path3.node.key.type === "Identifier" && path3.node.value.type === "Identifier") {
1255
+ const valName = path3.node.value.name;
1256
+ if (!graph.nodes.has(valName)) {
1257
+ graph.nodes.add(valName);
1258
+ nodeCollection.addTypedNode(valName, tempNodeCollection.nodes.get(valName));
1259
+ }
1260
+ if (!graph.edges.has(valName)) graph.edges.set(valName, new Set([...Array.from(tempEdges.get(valName) || /* @__PURE__ */ new Set())]));
1261
+ const name = path3.node.key.name;
1262
+ if (name !== valName) {
1263
+ graph.nodes.add(name);
1264
+ nodeCollection.addNode(name, path3.node.key, { comment: getComment(path3.node) });
1265
+ graph.edges.set(name, new Set([{
1266
+ label: valName,
1267
+ type: getRelationType(path3)
1268
+ }]));
1269
+ }
1270
+ }
1271
+ }
1272
+ } }, path2.scope, path2);
1273
+ }
1274
+ } });
1275
+ }
1276
+ function addSpreadToGraphByScanReturn({ path: path1, graph, nodeCollection, tempNodeCollection, tempEdges, tempSpread }) {
1277
+ path1.traverse({ ReturnStatement(path2) {
1278
+ if (path2.node.argument?.type === "ObjectExpression") {
1279
+ const returnNode = path2.node.argument;
1280
+ traverse(returnNode, { SpreadElement(path3) {
1281
+ if (path3.node.argument.type === "CallExpression" && path3.node.argument.callee.type === "Identifier" && path3.node.argument.callee.name === "toRefs" && path3.node.argument.arguments[0].type === "Identifier" && tempSpread.get(path3.node.argument.arguments[0].name)) tempSpread.get(path3.node.argument.arguments[0].name)?.forEach((name) => {
1282
+ graph.nodes.add(name);
1283
+ nodeCollection.addTypedNode(name, tempNodeCollection.nodes.get(name));
1284
+ if (!graph.edges.get(name)) {
1285
+ graph.edges.set(name, /* @__PURE__ */ new Set());
1286
+ tempEdges.get(name)?.forEach((edge) => {
1287
+ graph.edges.get(name)?.add(edge);
1288
+ });
1289
+ }
1290
+ });
1291
+ else if (path3.node.argument.type === "Identifier" && tempSpread.get(path3.node.argument.name)) tempSpread.get(path3.node.argument.name)?.forEach((name) => {
1292
+ graph.nodes.add(name);
1293
+ nodeCollection.addTypedNode(name, tempNodeCollection.nodes.get(name));
1294
+ if (!graph.edges.get(name)) {
1295
+ graph.edges.set(name, /* @__PURE__ */ new Set());
1296
+ tempEdges.get(name)?.forEach((edge) => {
1297
+ graph.edges.get(name)?.add(edge);
1298
+ });
1299
+ }
1300
+ });
1301
+ } }, path2.scope, path2);
1302
+ }
1303
+ } });
1304
+ }
1305
+ function addGraphBySpreadIdentifier({ path: path1, graph, nodeCollection, iname }) {
1306
+ if (path1.node.init?.type === "ObjectExpression") path1.node.init?.properties.forEach((prop) => {
1307
+ if ((prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && prop.key.type === "Identifier") {
1308
+ const keyName = prop.key.name;
1309
+ graph.nodes.add(keyName);
1310
+ nodeCollection.addNode(keyName, prop, { comment: getComment(prop) });
1311
+ if (!graph.edges.get(keyName)) graph.edges.set(keyName, /* @__PURE__ */ new Set());
1312
+ if (graph.spread.has(iname)) graph.spread.get(iname)?.add(keyName);
1313
+ else graph.spread.set(iname, new Set([keyName]));
1314
+ } else if (prop.type === "SpreadElement") console.warn("not support spread in spread");
1315
+ });
1316
+ if (path1.node.init?.type === "CallExpression" && path1.node.init?.callee.type === "Identifier" && path1.node.init?.callee.name === "reactive") {
1317
+ const arg = path1.node.init?.arguments[0];
1318
+ if (arg.type === "ObjectExpression") arg.properties.forEach((prop) => {
1319
+ if ((prop.type === "ObjectProperty" || prop.type === "ObjectMethod") && prop.key.type === "Identifier") {
1320
+ const keyName = prop.key.name;
1321
+ graph.nodes.add(keyName);
1322
+ nodeCollection.addNode(keyName, prop, { comment: getComment(prop) });
1323
+ if (!graph.edges.get(keyName)) graph.edges.set(keyName, /* @__PURE__ */ new Set());
1324
+ if (graph.spread.has(iname)) graph.spread.get(iname)?.add(keyName);
1325
+ else graph.spread.set(iname, new Set([keyName]));
1326
+ } else if (prop.type === "SpreadElement") console.warn("not support spread in spread");
1327
+ });
1328
+ }
1329
+ }
1330
+
1331
+ //#endregion
1332
+ //#region src/analyze/tsx.ts
1333
+ function processByReturnNotJSX(params) {
1334
+ const { node, parentPath, lineOffset, addInfo } = params;
1335
+ const spread = [];
1336
+ const nodeCollection = new NodeCollection(lineOffset, addInfo);
1337
+ const graph = {
1338
+ nodes: /* @__PURE__ */ new Set(),
1339
+ edges: /* @__PURE__ */ new Map()
1340
+ };
1341
+ const setupPath = traverseSetup({
1342
+ node,
1343
+ parentScope: parentPath.scope,
1344
+ parentPath
1345
+ });
1346
+ collectionSpread({
1347
+ path: setupPath,
1348
+ spread
1349
+ });
1350
+ const { graph: { nodes: tempNodes, edges: tempEdges, spread: tempSpread }, nodeCollection: tempNodeCollection, nodesUsedInTemplate } = processByReturnJSX({
1351
+ node,
1352
+ parentPath,
1353
+ spread,
1354
+ lineOffset,
1355
+ addInfo
1356
+ });
1357
+ addIdentifiesToGraphByScanReturn({
1358
+ path: setupPath,
1359
+ graph,
1360
+ nodeCollection,
1361
+ tempNodeCollection,
1362
+ tempEdges
1363
+ });
1364
+ addSpreadToGraphByScanReturn({
1365
+ path: setupPath,
1366
+ graph,
1367
+ nodeCollection,
1368
+ tempNodeCollection,
1369
+ tempEdges,
1370
+ tempSpread
1371
+ });
1372
+ return {
1373
+ graph,
1374
+ nodeCollection,
1375
+ nodesUsedInTemplate
1376
+ };
1377
+ }
1378
+ function processByReturnJSX(params) {
1379
+ const { node, parentPath, spread = [], lineOffset, addInfo } = params;
1380
+ const nodeCollection = new NodeCollection(lineOffset, addInfo);
1381
+ const nodesUsedInTemplate = /* @__PURE__ */ new Set();
1382
+ const graph = {
1383
+ nodes: /* @__PURE__ */ new Set(),
1384
+ edges: /* @__PURE__ */ new Map(),
1385
+ spread: /* @__PURE__ */ new Map()
1386
+ };
1387
+ function addNode({ name, node: node$1, path, scope }, commentParentNode) {
1388
+ const binding = path.scope.getBinding(name);
1389
+ if (scope === binding?.scope) {
1390
+ graph.nodes.add(name);
1391
+ nodeCollection.addNode(name, node$1, { comment: commentParentNode ? getComment(commentParentNode) : "" });
1392
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
1393
+ }
1394
+ }
1395
+ function addEdge({ fromName, toName, path, scope, toScope, collectionNodes }) {
1396
+ const bindingScope = toScope || path.scope.getBinding(toName)?.scope;
1397
+ if (scope === bindingScope && collectionNodes.has(toName)) graph.edges.get(fromName)?.add({
1398
+ label: toName,
1399
+ type: getRelationType(path)
1400
+ });
1401
+ }
1402
+ function addUsed({ name, path, parentPath: parentPath$1 }) {
1403
+ const binding = path.scope.getBinding(name);
1404
+ if (binding?.scope === parentPath$1.scope) nodesUsedInTemplate.add(name);
1405
+ }
1406
+ const setupPath = traverseSetup({
1407
+ node,
1408
+ parentScope: parentPath.scope,
1409
+ parentPath
1410
+ });
1411
+ const setupScope = setupPath.scope;
1412
+ const setupNode = setupPath.node;
1413
+ traverse(setupNode, {
1414
+ VariableDeclarator(path1) {
1415
+ parseNodeIdentifierPattern({
1416
+ path: path1,
1417
+ rootScope: setupScope,
1418
+ cb: (params$1) => {
1419
+ if (!spread.includes(params$1.name)) addNode(params$1, path1.node);
1420
+ else addGraphBySpreadIdentifier({
1421
+ path: path1,
1422
+ graph,
1423
+ nodeCollection,
1424
+ iname: params$1.name
1425
+ });
1426
+ }
1427
+ });
1428
+ parseNodeObjectPattern({
1429
+ path: path1,
1430
+ rootScope: setupScope,
1431
+ cb: addNode
1432
+ });
1433
+ parseNodeArrayPattern({
1434
+ path: path1,
1435
+ rootScope: setupScope,
1436
+ cb: addNode
1437
+ });
1438
+ },
1439
+ FunctionDeclaration(path1) {
1440
+ parseNodeFunctionPattern({
1441
+ path: path1,
1442
+ rootScope: setupScope,
1443
+ cb: addNode
1444
+ });
1445
+ }
1446
+ }, setupScope, setupPath);
1447
+ setupPath.traverse({ ReturnStatement(path2) {
1448
+ parseReturnJsxPattern({
1449
+ path: path2,
1450
+ parentPath: setupPath,
1451
+ cb: addUsed
1452
+ });
1453
+ } });
1454
+ traverse(setupNode, {
1455
+ VariableDeclarator(path1) {
1456
+ parseEdgeLeftIdentifierPattern({
1457
+ path: path1,
1458
+ rootScope: setupScope,
1459
+ collectionNodes: graph.nodes,
1460
+ cb: addEdge,
1461
+ spread
1462
+ });
1463
+ parseEdgeLeftObjectPattern({
1464
+ path: path1,
1465
+ rootScope: setupScope,
1466
+ collectionNodes: graph.nodes,
1467
+ cb: addEdge
1468
+ });
1469
+ parseEdgeLeftArrayPattern({
1470
+ path: path1,
1471
+ rootScope: setupScope,
1472
+ collectionNodes: graph.nodes,
1473
+ cb: addEdge
1474
+ });
1475
+ },
1476
+ FunctionDeclaration(path1) {
1477
+ parseEdgeFunctionPattern({
1478
+ path: path1,
1479
+ rootScope: setupScope,
1480
+ collectionNodes: graph.nodes,
1481
+ cb: addEdge
1482
+ });
1483
+ }
1484
+ }, setupScope, setupPath);
1485
+ return {
1486
+ graph,
1487
+ nodeCollection,
1488
+ nodesUsedInTemplate
1489
+ };
1490
+ }
1491
+ function processByReact(params) {
1492
+ const { node, parentScope, parentPath, lineOffset, addInfo } = params;
1493
+ const nodeCollection = new NodeCollection(lineOffset, addInfo);
1494
+ const nodesUsedInTemplate = /* @__PURE__ */ new Set();
1495
+ const graph = {
1496
+ nodes: /* @__PURE__ */ new Set(),
1497
+ edges: /* @__PURE__ */ new Map(),
1498
+ spread: /* @__PURE__ */ new Map()
1499
+ };
1500
+ function addNode({ name, node: node$1, path, scope }, commentParentNode) {
1501
+ const binding = path.scope.getBinding(name);
1502
+ if (scope === binding?.scope) {
1503
+ graph.nodes.add(name);
1504
+ nodeCollection.addNode(name, node$1, { comment: commentParentNode ? getComment(commentParentNode) : "" });
1505
+ if (!graph.edges.get(name)) graph.edges.set(name, /* @__PURE__ */ new Set());
1506
+ }
1507
+ }
1508
+ function addEdge({ fromName, toName, path, scope, toScope, collectionNodes }) {
1509
+ const bindingScope = toScope || path.scope.getBinding(toName)?.scope;
1510
+ if (scope === bindingScope && collectionNodes.has(toName)) graph.edges.get(fromName)?.add({
1511
+ label: toName,
1512
+ type: getRelationType(path)
1513
+ });
1514
+ }
1515
+ function addUsed({ name, path, parentPath: parentPath$1 }) {
1516
+ const binding = path.scope.getBinding(name);
1517
+ if (binding?.scope === parentPath$1.scope) nodesUsedInTemplate.add(name);
1518
+ }
1519
+ traverse(node, {
1520
+ VariableDeclarator(path1) {
1521
+ parseNodeIdentifierPattern({
1522
+ path: path1,
1523
+ rootScope: parentScope,
1524
+ cb: (params$1) => {
1525
+ addNode(params$1, path1.node);
1526
+ }
1527
+ });
1528
+ parseNodeObjectPattern({
1529
+ path: path1,
1530
+ rootScope: parentScope,
1531
+ cb: addNode
1532
+ });
1533
+ parseNodeArrayPattern({
1534
+ path: path1,
1535
+ rootScope: parentScope,
1536
+ cb: addNode
1537
+ });
1538
+ },
1539
+ FunctionDeclaration(path1) {
1540
+ parseNodeFunctionPattern({
1541
+ path: path1,
1542
+ rootScope: parentScope,
1543
+ cb: addNode
1544
+ });
1545
+ }
1546
+ }, parentScope, parentPath);
1547
+ traverse(node, { ReturnStatement(path2) {
1548
+ parseReturnJsxPattern({
1549
+ path: path2,
1550
+ parentPath,
1551
+ cb: addUsed
1552
+ });
1553
+ } }, parentScope, parentPath);
1554
+ traverse(node, {
1555
+ VariableDeclarator(path1) {
1556
+ parseEdgeLeftIdentifierPattern({
1557
+ path: path1,
1558
+ rootScope: parentScope,
1559
+ collectionNodes: graph.nodes,
1560
+ cb: addEdge
1561
+ });
1562
+ parseEdgeLeftObjectPattern({
1563
+ path: path1,
1564
+ rootScope: parentScope,
1565
+ collectionNodes: graph.nodes,
1566
+ cb: addEdge
1567
+ });
1568
+ parseEdgeLeftArrayPattern({
1569
+ path: path1,
1570
+ rootScope: parentScope,
1571
+ collectionNodes: graph.nodes,
1572
+ cb: addEdge
1573
+ });
1574
+ },
1575
+ FunctionDeclaration(path1) {
1576
+ parseEdgeFunctionPattern({
1577
+ path: path1,
1578
+ rootScope: parentScope,
1579
+ collectionNodes: graph.nodes,
1580
+ cb: addEdge
1581
+ });
1582
+ }
1583
+ }, parentScope, parentPath);
1584
+ return {
1585
+ graph,
1586
+ nodeCollection,
1587
+ nodesUsedInTemplate
1588
+ };
1589
+ }
1590
+ function processTsx(params) {
1591
+ let result;
1592
+ function process(params$1) {
1593
+ const { node, parentPath } = params$1;
1594
+ const setupPath = traverseSetup({
1595
+ node,
1596
+ parentScope: parentPath.scope,
1597
+ parentPath
1598
+ });
1599
+ setupPath.traverse({ ReturnStatement(path) {
1600
+ if (path.node.argument && (path.node.argument.type === "ArrowFunctionExpression" || path.node.argument.type === "FunctionExpression") && (path.node.argument.body.type === "JSXElement" || path.node.argument.body.type === "JSXFragment")) result = processByReturnJSX(params$1);
1601
+ else result = processByReturnNotJSX(params$1);
1602
+ } });
1603
+ }
1604
+ traverse(params.node, { ExportDefaultDeclaration(path) {
1605
+ if (params.type === "vue") {
1606
+ if (path.node.declaration.type === "ObjectExpression") process({
1607
+ ...params,
1608
+ node: path.node.declaration,
1609
+ parentNode: path.node,
1610
+ parentPath: path
1611
+ });
1612
+ else if (path.node.declaration.type === "CallExpression" && path.node.declaration.callee.type === "Identifier" && path.node.declaration.callee.name === "defineComponent" && path.node.declaration.arguments[0].type === "ObjectExpression") process({
1613
+ ...params,
1614
+ node: path.node.declaration.arguments[0],
1615
+ parentNode: path.node,
1616
+ parentPath: path
1617
+ });
1618
+ }
1619
+ if (params.type === "react") {
1620
+ if ((path.node.declaration.type === "FunctionDeclaration" || path.node.declaration.type === "ArrowFunctionExpression") && path.node.declaration.body.type === "BlockStatement") {
1621
+ const functionPath = path.get("declaration");
1622
+ result = processByReact({
1623
+ ...params,
1624
+ node: path.node.declaration.body,
1625
+ parentNode: functionPath.node,
1626
+ parentPath: functionPath,
1627
+ parentScope: functionPath.scope
1628
+ });
1629
+ }
1630
+ if (path.node.declaration.type === "ClassDeclaration") {
1631
+ const renderFunction = path.node.declaration.body.body.find((node) => {
1632
+ if (node.type === "ClassMethod" && node.key.type === "Identifier" && node.key.name === "render") return node;
1633
+ return void 0;
1634
+ });
1635
+ if (!renderFunction) return;
1636
+ const renderPath = path.get(`declaration.body.body.${path.node.declaration.body.body.indexOf(renderFunction)}`);
1637
+ result = processByReact({
1638
+ ...params,
1639
+ node: renderFunction.body,
1640
+ parentNode: renderFunction,
1641
+ parentPath: renderPath,
1642
+ parentScope: renderPath.scope
1643
+ });
1644
+ }
1645
+ }
1646
+ } });
1647
+ return result;
1648
+ }
1649
+ function analyze$4(content, type = "vue", lineOffset = 0, addInfo = true) {
1650
+ const ast = (0, __vue_compiler_sfc.babelParse)(content, {
1651
+ sourceType: "module",
1652
+ plugins: ["typescript", "jsx"]
1653
+ });
1654
+ const { graph, nodeCollection, nodesUsedInTemplate } = processTsx({
1655
+ node: ast,
1656
+ type,
1657
+ lineOffset,
1658
+ addInfo
1659
+ });
1660
+ return {
1661
+ graph: nodeCollection.map(graph),
1662
+ nodesUsedInTemplate
1663
+ };
1664
+ }
1665
+
1666
+ //#endregion
1667
+ //#region src/mermaid.ts
1668
+ function getMermaidText(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set(), options = {}) {
1669
+ const direction = options.direction || "TB";
1670
+ const usedNodes = new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
1671
+ let mermaidText = `flowchart ${direction}
1672
+ %% Legend:
1673
+ %% () = variable node
1674
+ %% [] = function node
1675
+ %% * suffix = unused in template/style
1676
+ %% A --> B means A depends on B\n`;
1677
+ graph.nodes.forEach((node) => {
1678
+ const shape = node.type === "var" ? "(" : "[";
1679
+ const closeShape = node.type === "var" ? ")" : "]";
1680
+ const unusedSuffix = !(usedNodes.has(node.label) || node.info?.used?.size) ? "*" : "";
1681
+ mermaidText += ` ${node.label}${shape}${node.label}${unusedSuffix}${closeShape}\n`;
1682
+ });
1683
+ graph.edges.forEach((edge, key) => {
1684
+ edge.forEach((to) => {
1685
+ if (!to || !to.node.label) return;
1686
+ mermaidText += ` ${key.label} --> ${to.node.label}\n`;
1687
+ });
1688
+ });
1689
+ return mermaidText;
1690
+ }
1691
+
1692
+ //#endregion
1693
+ //#region src/suggest/filter.ts
1694
+ /**
1695
+ * Filter out nodes that have no indegree.
1696
+ */
1697
+ function noIndegreeFilter(graph) {
1698
+ const nodes = Array.from(graph.keys());
1699
+ const indegree = /* @__PURE__ */ new Map();
1700
+ nodes.forEach((node) => {
1701
+ indegree.set(node, 0);
1702
+ });
1703
+ graph.forEach((targets, node) => {
1704
+ targets.forEach((target) => {
1705
+ indegree.set(target.node, (indegree.get(target.node) || 0) + 1);
1706
+ });
1707
+ });
1708
+ return nodes.filter((node) => indegree.get(node) === 0);
1709
+ }
1710
+ function findLinearPaths(graph) {
1711
+ const linearPaths = [];
1712
+ const visitedNodes = /* @__PURE__ */ new Set();
1713
+ const nodeInDegrees = /* @__PURE__ */ new Map();
1714
+ for (const [node, edges] of graph.entries()) {
1715
+ if (!nodeInDegrees.has(node)) nodeInDegrees.set(node, 0);
1716
+ for (const edge of edges) {
1717
+ const inDegree = nodeInDegrees.get(edge.node) || 0;
1718
+ nodeInDegrees.set(edge.node, inDegree + 1);
1719
+ }
1720
+ }
1721
+ function dfs$1(node, path) {
1722
+ if (visitedNodes.has(node)) return;
1723
+ path.push(node);
1724
+ visitedNodes.add(node);
1725
+ const edges = graph.get(node) || /* @__PURE__ */ new Set();
1726
+ if (edges.size === 0 || edges.size > 1) {
1727
+ if (path.length > 1) addOrUpdatePath([...path]);
1728
+ } else {
1729
+ const nextNode = Array.from(edges)[0].node;
1730
+ const nextNodeInDegree = nodeInDegrees.get(nextNode) || 0;
1731
+ if (nextNodeInDegree === 1) dfs$1(nextNode, path);
1732
+ }
1733
+ path.pop();
1734
+ visitedNodes.delete(node);
1735
+ }
1736
+ function addOrUpdatePath(newPath) {
1737
+ let shouldAddNewPath = true;
1738
+ for (let i = linearPaths.length - 1; i >= 0; i--) {
1739
+ const existingPath = linearPaths[i];
1740
+ if (isSubpath(existingPath, newPath)) linearPaths.splice(i, 1);
1741
+ else if (isSubpath(newPath, existingPath)) {
1742
+ shouldAddNewPath = false;
1743
+ break;
1744
+ }
1745
+ }
1746
+ if (shouldAddNewPath && newPath.length > 2) linearPaths.push(newPath);
1747
+ }
1748
+ function isSubpath(shortPath, longPath) {
1749
+ if (shortPath.length >= longPath.length) return false;
1750
+ for (let i = 0; i <= longPath.length - shortPath.length; i++) {
1751
+ let isSub = true;
1752
+ for (let j = 0; j < shortPath.length; j++) if (shortPath[j] !== longPath[i + j]) {
1753
+ isSub = false;
1754
+ break;
1755
+ }
1756
+ if (isSub) return true;
1757
+ }
1758
+ return false;
1759
+ }
1760
+ for (const node of graph.keys()) dfs$1(node, []);
1761
+ return linearPaths;
1762
+ }
1763
+ function findArticulationPoints(graph) {
1764
+ const noIndegreeNodes = noIndegreeFilter(graph);
1765
+ let time = 0;
1766
+ const low = /* @__PURE__ */ new Map();
1767
+ const disc = /* @__PURE__ */ new Map();
1768
+ const parent = /* @__PURE__ */ new Map();
1769
+ const ap = /* @__PURE__ */ new Set();
1770
+ const visited = /* @__PURE__ */ new Set();
1771
+ function APUtil(graph$1, node) {
1772
+ let children = 0;
1773
+ disc.set(node, time);
1774
+ low.set(node, time);
1775
+ time++;
1776
+ visited.add(node);
1777
+ for (const neighbor of graph$1.get(node) || []) if (!visited.has(neighbor.node)) {
1778
+ children++;
1779
+ parent.set(neighbor.node, node);
1780
+ APUtil(graph$1, neighbor.node);
1781
+ low.set(node, Math.min(low.get(node), low.get(neighbor.node)));
1782
+ if (parent.get(node) === null && children > 1) ap.add(node);
1783
+ if (parent.get(node) !== null && low.get(neighbor.node) >= disc.get(node)) ap.add(node);
1784
+ } else if (neighbor.node !== parent.get(node)) low.set(node, Math.min(low.get(node), disc.get(neighbor.node)));
1785
+ }
1786
+ for (const node of graph.keys()) if (!visited.has(node) && !noIndegreeNodes.includes(node)) APUtil(graph, node);
1787
+ return ap;
1788
+ }
1789
+
1790
+ //#endregion
1791
+ //#region src/suggest/split.ts
1792
+ function dfs(graph, node, targets, visited, component) {
1793
+ component.add(node);
1794
+ visited.add(node);
1795
+ targets.forEach((target) => {
1796
+ if (!visited.has(target.node)) dfs(graph, target.node, graph.get(target.node) || /* @__PURE__ */ new Set(), visited, component);
1797
+ });
1798
+ }
1799
+ function haveIntersection(setA, setB) {
1800
+ for (const item of setA) if (setB.has(item)) return true;
1801
+ return false;
1802
+ }
1803
+ function mergeSets(arr) {
1804
+ let result = [...arr];
1805
+ for (let i = 0; i < result.length; i++) for (let j = i + 1; j < result.length; j++) if (haveIntersection(result[i], result[j])) {
1806
+ const newSet = new Set([...result[i], ...result[j]]);
1807
+ result.splice(j, 1);
1808
+ result.splice(i, 1);
1809
+ result = [...result, newSet];
1810
+ return mergeSets(result);
1811
+ }
1812
+ return result;
1813
+ }
1814
+ function splitGraph(graph) {
1815
+ const components = [];
1816
+ const sorted = Array.from(graph).sort((a, b) => b[1].size - a[1].size);
1817
+ new Map(sorted).forEach((targets, node) => {
1818
+ const visited = /* @__PURE__ */ new Set();
1819
+ if (!visited.has(node)) {
1820
+ const component = /* @__PURE__ */ new Set();
1821
+ dfs(graph, node, targets, visited, component);
1822
+ components.push(component);
1823
+ }
1824
+ });
1825
+ return mergeSets(components).map((component) => {
1826
+ const subGraph = /* @__PURE__ */ new Map();
1827
+ component.forEach((node) => {
1828
+ const targets = graph.get(node);
1829
+ if (targets) subGraph.set(node, targets);
1830
+ });
1831
+ return subGraph;
1832
+ });
1833
+ }
1834
+
1835
+ //#endregion
1836
+ //#region src/suggest/utils.ts
1837
+ function hasCycle(graph) {
1838
+ const visited = /* @__PURE__ */ new Set();
1839
+ const onStack = /* @__PURE__ */ new Set();
1840
+ const stack = [];
1841
+ let cycleNodes = [];
1842
+ function dfs$1(node) {
1843
+ if (visited.has(node)) {
1844
+ if (onStack.has(node)) {
1845
+ const idx = stack.indexOf(node);
1846
+ const cycle = stack.slice(idx);
1847
+ const allNotGet = cycle.every((curr, i) => {
1848
+ const next = cycle[(i + 1) % cycle.length];
1849
+ return Array.from(graph.get(curr) || []).some((edge) => edge.node === next && edge.type !== "get");
1850
+ });
1851
+ if (allNotGet) {
1852
+ cycleNodes = cycle;
1853
+ return true;
1854
+ }
1855
+ return false;
1856
+ }
1857
+ return false;
1858
+ }
1859
+ visited.add(node);
1860
+ onStack.add(node);
1861
+ stack.push(node);
1862
+ for (const neighbor of graph.get(node) || /* @__PURE__ */ new Set()) {
1863
+ if (neighbor.node === node && neighbor.type !== "get") {
1864
+ cycleNodes = [node];
1865
+ return true;
1866
+ }
1867
+ if (dfs$1(neighbor.node)) return true;
1868
+ }
1869
+ onStack.delete(node);
1870
+ stack.pop();
1871
+ return false;
1872
+ }
1873
+ for (const [node, targets] of graph) if (dfs$1(node)) return {
1874
+ hasCycle: true,
1875
+ cycleNodes
1876
+ };
1877
+ return {
1878
+ hasCycle: false,
1879
+ cycleNodes: []
1880
+ };
1881
+ }
1882
+
1883
+ //#endregion
1884
+ //#region src/suggest/index.ts
1885
+ let SuggestionType = /* @__PURE__ */ function(SuggestionType$1) {
1886
+ SuggestionType$1["info"] = "info";
1887
+ SuggestionType$1["warning"] = "warning";
1888
+ SuggestionType$1["error"] = "error";
1889
+ return SuggestionType$1;
1890
+ }({});
1891
+ function gen(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set()) {
1892
+ const usedNodes = new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
1893
+ const suggestions = [];
1894
+ const splitedGraph = splitGraph(graph.edges);
1895
+ splitedGraph.forEach((g) => {
1896
+ const nodes = Array.from(g.keys());
1897
+ if (splitedGraph.length > 1) {
1898
+ if (nodes.length > 2 && nodes.some((node) => !usedNodes.has(node.label))) suggestions.push({
1899
+ type: SuggestionType.info,
1900
+ message: `Nodes [${nodes.length > 10 ? `${nodes.slice(0, 10).map((node) => node.label).join(",")}...(${nodes.length})` : nodes.map((node) => node.label).join(",")}] are isolated, perhaps you can refactor them to an isolated file.`,
1901
+ nodeInfo: nodes
1902
+ });
1903
+ }
1904
+ if (nodes.length > 1 && nodes.every((node) => !usedNodes.has(node.label) && !node.info?.used?.size)) suggestions.push({
1905
+ type: SuggestionType.info,
1906
+ message: `Nodes [${nodes.length > 10 ? `${nodes.slice(0, 10).map((node) => node.label).join(",")}...` : nodes.map((node) => node.label).join(",")}] are not used, perhaps you can remove them.`,
1907
+ nodeInfo: nodes
1908
+ });
1909
+ const hasCycleResult = hasCycle(g);
1910
+ if (hasCycleResult.hasCycle) suggestions.push({
1911
+ type: SuggestionType.error,
1912
+ message: `There is a loop call in nodes [${hasCycleResult.cycleNodes.map((node) => node.label).join(",")}], perhaps you can refactor it.`,
1913
+ nodeInfo: hasCycleResult.cycleNodes
1914
+ });
1915
+ const paths = findLinearPaths(g);
1916
+ paths.forEach((path) => {
1917
+ const firstUsedNodeIndex = path.findIndex((node) => usedNodes.has(node.label));
1918
+ const reverseLastNotUsedNodeIndex = path.slice().reverse().findIndex((node) => !usedNodes.has(node.label));
1919
+ const lastNotUsedNodeIndex = reverseLastNotUsedNodeIndex !== -1 ? path.length - 1 - reverseLastNotUsedNodeIndex : -1;
1920
+ if (firstUsedNodeIndex > -1 && firstUsedNodeIndex < lastNotUsedNodeIndex) suggestions.push({
1921
+ type: SuggestionType.warning,
1922
+ message: `Nodes [${path.length > 10 ? `${path.slice(0, 10).map((node) => node.label).join(",")}...(${path.length})` : path.map((node) => node.label).join(",")}] are have function chain calls, perhaps you can refactor it.`,
1923
+ nodeInfo: path
1924
+ });
1925
+ });
1926
+ if (g.size > 5) {
1927
+ const ap = findArticulationPoints(g);
1928
+ ap.forEach((node) => {
1929
+ if (node.type === NodeType.fun) suggestions.push({
1930
+ type: SuggestionType.info,
1931
+ message: `Node [${node.label}] is an articulation point, perhaps you need to pay special attention to this node.`,
1932
+ nodeInfo: node
1933
+ });
1934
+ });
1935
+ }
1936
+ });
1937
+ const noIndegreeNodes = noIndegreeFilter(graph.edges);
1938
+ noIndegreeNodes.forEach((node) => {
1939
+ if (!usedNodes.has(node.label) && !node.info?.used?.size) suggestions.push({
1940
+ type: SuggestionType.info,
1941
+ message: `Node [${node.label}] is not used, perhaps you can remove it.`,
1942
+ nodeInfo: node
1943
+ });
1944
+ });
1945
+ return suggestions;
1946
+ }
1947
+
1948
+ //#endregion
1949
+ //#region src/vis.ts
1950
+ function filterNodeUserd(used) {
1951
+ const usedArray = Array.from(used || []);
1952
+ return new Set(usedArray.filter((u) => !["Assignment Expression", "Call Expression"].includes(u)));
1953
+ }
1954
+ function getVisData(graph, nodesUsedInTemplate, nodesUsedInStyle = /* @__PURE__ */ new Set()) {
1955
+ const usedNodes = new Set([...nodesUsedInTemplate, ...nodesUsedInStyle]);
1956
+ const nodes = [];
1957
+ const edges = [];
1958
+ const inDegreeMap = {};
1959
+ const outDegreeMap = {};
1960
+ graph.edges.forEach((edge) => {
1961
+ edge.forEach((to) => {
1962
+ if (to) inDegreeMap[to.node.label] = (inDegreeMap[to.node.label] || 0) + 1;
1963
+ });
1964
+ });
1965
+ graph.edges.forEach((edge, key) => {
1966
+ outDegreeMap[key.label] = edge.size;
1967
+ });
1968
+ graph.nodes.forEach((node) => {
1969
+ const inDegree = inDegreeMap[node.label] || 0;
1970
+ const outDegree = outDegreeMap[node.label] || 0;
1971
+ nodes.push({
1972
+ id: node.label,
1973
+ label: node.label,
1974
+ shape: node.type === "var" ? "dot" : "diamond",
1975
+ group: usedNodes.has(node.label) || node.info?.used?.size ? "used" : "normal",
1976
+ size: 20 + 1.6 ** (inDegree * .75 + outDegree * .25),
1977
+ title: `${filterNodeUserd(node.info?.used).size ? `used by ${Array.from(filterNodeUserd(node.info?.used))?.map((i) => `\`${i}\``).join(",")}\n\n` : ""}${usedNodes.has(node.label) ? `used in ${[nodesUsedInStyle.has(node.label) ? "style" : "", nodesUsedInTemplate.has(node.label) ? "template" : ""].filter(Boolean).join(" and ")}\n\n` : ""}${node.info?.comment || ""}`.trim() || void 0,
1978
+ info: node.info
1979
+ });
1980
+ });
1981
+ graph.edges.forEach((edge, key) => {
1982
+ edge.forEach((to) => {
1983
+ if (!to) return;
1984
+ edges.push({
1985
+ from: key.label,
1986
+ to: to.node.label,
1987
+ arrows: { to: {
1988
+ enabled: true,
1989
+ scaleFactor: .8
1990
+ } }
1991
+ });
1992
+ });
1993
+ });
1994
+ return {
1995
+ nodes,
1996
+ edges
1997
+ };
1998
+ }
1999
+
2000
+ //#endregion
2001
+ exports.SuggestionType = SuggestionType;
2002
+ exports.analyzeOptions = analyze;
2003
+ exports.analyzeSetupScript = analyze$1;
2004
+ exports.analyzeStyle = analyze$2;
2005
+ exports.analyzeTemplate = analyze$3;
2006
+ exports.analyzeTsx = analyze$4;
2007
+ exports.gen = gen;
2008
+ exports.getMermaidText = getMermaidText;
2009
+ exports.getVisData = getVisData;
2010
+ Object.defineProperty(exports, 'parse', {
2011
+ enumerable: true,
2012
+ get: function () {
2013
+ return __vue_compiler_sfc.parse;
2014
+ }
2015
+ });
2016
+ //# sourceMappingURL=index.cjs.map