@zid-utils/tree-utils 0.0.6
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.js +512 -0
- package/package.json +29 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var defaultLogger = {
|
|
3
|
+
warn: (msg) => console.warn("[tree-utils]", msg),
|
|
4
|
+
error: (msg) => console.error("[tree-utils]", msg)
|
|
5
|
+
};
|
|
6
|
+
var getLeafNodes = (treeData, isLeafKey = "isLeaf") => {
|
|
7
|
+
function collectLeafNodes(nodes) {
|
|
8
|
+
const leafNodes = [];
|
|
9
|
+
for (const node of nodes) {
|
|
10
|
+
if (node[isLeafKey] === true) {
|
|
11
|
+
leafNodes.push(node);
|
|
12
|
+
} else if (node.children) {
|
|
13
|
+
leafNodes.push(...collectLeafNodes(node.children));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return leafNodes;
|
|
17
|
+
}
|
|
18
|
+
return collectLeafNodes(treeData);
|
|
19
|
+
};
|
|
20
|
+
var filterTreeNodes = (nodes, callback, isOnlyFilterChildren = true) => {
|
|
21
|
+
const filterChildren = (children) => {
|
|
22
|
+
if (children && children.length > 0) {
|
|
23
|
+
return children.filter(callback).map((child) => {
|
|
24
|
+
return {
|
|
25
|
+
...child,
|
|
26
|
+
children: filterChildren(child.children)
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return [];
|
|
31
|
+
};
|
|
32
|
+
const rootNodes = isOnlyFilterChildren ? nodes : nodes.filter(callback);
|
|
33
|
+
return rootNodes.map((node) => ({
|
|
34
|
+
...node,
|
|
35
|
+
children: filterChildren(node.children)
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
var findNodeByKey = (treeData, key) => {
|
|
39
|
+
for (let i = 0; i < treeData.length; i++) {
|
|
40
|
+
const node = treeData[i];
|
|
41
|
+
if (node.key === key) {
|
|
42
|
+
return node;
|
|
43
|
+
}
|
|
44
|
+
if (node.children) {
|
|
45
|
+
const foundNode = findNodeByKey(node.children, key);
|
|
46
|
+
if (foundNode) {
|
|
47
|
+
return foundNode;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
};
|
|
53
|
+
var searchInTree = (tree, searchValue) => {
|
|
54
|
+
function searchRecursive(node, searchText, result2) {
|
|
55
|
+
const title = node.title?.toString().toLowerCase() || "";
|
|
56
|
+
const text = searchText.toLowerCase();
|
|
57
|
+
const arr = text.split("");
|
|
58
|
+
if (node.isLeaf && arr.every((item) => title.includes(item))) {
|
|
59
|
+
if (!result2.some((item) => item.key === node.key)) {
|
|
60
|
+
result2.push(node);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (node.children) {
|
|
64
|
+
for (const child of node.children) {
|
|
65
|
+
searchRecursive(child, text, result2);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const result = [];
|
|
70
|
+
for (const rootNode of tree) {
|
|
71
|
+
searchRecursive(rootNode, searchValue.toLowerCase(), result);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
};
|
|
75
|
+
var updateKeys = (sourceNode, targetNode) => {
|
|
76
|
+
sourceNode.key = `${targetNode.key}-${targetNode.children?.length}`;
|
|
77
|
+
if (sourceNode.children) {
|
|
78
|
+
sourceNode.children.forEach((item, index) => {
|
|
79
|
+
item.key = `${sourceNode.key}-${index}`;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var moveNodeInTree = (treeData, sourceKey, targetKey, logger = defaultLogger) => {
|
|
84
|
+
function findNode(nodes, key) {
|
|
85
|
+
if (!nodes) return null;
|
|
86
|
+
for (const node of nodes) {
|
|
87
|
+
if (node.key === key) return node;
|
|
88
|
+
if (node.children) {
|
|
89
|
+
const found = findNode(node.children, key);
|
|
90
|
+
if (found) return found;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
function getParentNode(nodes, node) {
|
|
96
|
+
for (const parent of nodes) {
|
|
97
|
+
if (parent.children && parent.children.includes(node)) {
|
|
98
|
+
return parent;
|
|
99
|
+
}
|
|
100
|
+
const result = getParentNode(parent.children || [], node);
|
|
101
|
+
if (result) return result;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const sourceNode = findNode(
|
|
106
|
+
Array.isArray(treeData) ? treeData : [treeData],
|
|
107
|
+
sourceKey
|
|
108
|
+
);
|
|
109
|
+
const targetNode = findNode(
|
|
110
|
+
Array.isArray(treeData) ? treeData : [treeData],
|
|
111
|
+
targetKey
|
|
112
|
+
);
|
|
113
|
+
if (!sourceNode || !targetNode) {
|
|
114
|
+
logger.error?.("Source or target node not found");
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (sourceNode.children && sourceNode.children.length > 0) {
|
|
118
|
+
logger.error?.("Source node is not a leaf node, cannot move");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const sourceParent = getParentNode(
|
|
122
|
+
Array.isArray(treeData) ? treeData : [treeData],
|
|
123
|
+
sourceNode
|
|
124
|
+
);
|
|
125
|
+
if (sourceParent) {
|
|
126
|
+
const index = sourceParent.children.findIndex(
|
|
127
|
+
(child) => child.key === sourceKey
|
|
128
|
+
);
|
|
129
|
+
if (index !== -1) {
|
|
130
|
+
sourceParent.children.splice(index, 1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
targetNode.children = targetNode.children || [];
|
|
134
|
+
targetNode.children.push(sourceNode);
|
|
135
|
+
};
|
|
136
|
+
var cloneNode = (sourceNode, targetNode) => {
|
|
137
|
+
const clonedNode = { ...sourceNode };
|
|
138
|
+
if (targetNode.children) {
|
|
139
|
+
targetNode.children.push(clonedNode);
|
|
140
|
+
} else {
|
|
141
|
+
targetNode.children = [clonedNode];
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
var copyNode = (treeData, key, targetKey) => {
|
|
145
|
+
const sourceNode = structuredClone(findNodeByKey(treeData, key));
|
|
146
|
+
const targetNode = findNodeByKey(treeData, targetKey);
|
|
147
|
+
if (sourceNode && targetNode) {
|
|
148
|
+
sourceNode.title += "-\u526F\u672C";
|
|
149
|
+
updateKeys(sourceNode, targetNode);
|
|
150
|
+
cloneNode(sourceNode, targetNode);
|
|
151
|
+
return [...treeData];
|
|
152
|
+
}
|
|
153
|
+
return treeData;
|
|
154
|
+
};
|
|
155
|
+
var updateNodeTitleByKey = (tree, targetKey, newTitle) => {
|
|
156
|
+
for (const node of tree) {
|
|
157
|
+
if (node.key === targetKey) {
|
|
158
|
+
node.title = newTitle;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (node.children) {
|
|
162
|
+
updateNodeTitleByKey(node.children, targetKey, newTitle);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var deleteNode = (treeData, key) => {
|
|
167
|
+
const delNode = (data) => {
|
|
168
|
+
return data.filter((node) => {
|
|
169
|
+
if (node.key === key) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (node.children) {
|
|
173
|
+
node.children = delNode(node.children);
|
|
174
|
+
}
|
|
175
|
+
return true;
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
return delNode([...treeData]);
|
|
179
|
+
};
|
|
180
|
+
var flattenTree = (tree, filter = () => true) => {
|
|
181
|
+
const result = [];
|
|
182
|
+
const flatten = (node) => {
|
|
183
|
+
if (filter(node)) {
|
|
184
|
+
result.push(node);
|
|
185
|
+
}
|
|
186
|
+
if (node.children) {
|
|
187
|
+
node.children.forEach(flatten);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
tree.forEach(flatten);
|
|
191
|
+
return result;
|
|
192
|
+
};
|
|
193
|
+
var addLeafProperties = (treeData) => {
|
|
194
|
+
return treeData.map((node) => {
|
|
195
|
+
const isLeaf = !node.children || node.children.length === 0;
|
|
196
|
+
return {
|
|
197
|
+
...node,
|
|
198
|
+
isLeaf,
|
|
199
|
+
disabled: !isLeaf,
|
|
200
|
+
children: node.children ? addLeafProperties(node.children) : void 0
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
};
|
|
204
|
+
var findNodeById = (nodes, id) => {
|
|
205
|
+
for (const node of nodes) {
|
|
206
|
+
if (node.id === id) return node;
|
|
207
|
+
if (node.children && node.children.length) {
|
|
208
|
+
const found = findNodeById(node.children, id);
|
|
209
|
+
if (found) return found;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
};
|
|
214
|
+
var filterCheckedLeafKeys = (treeData) => {
|
|
215
|
+
const result = [];
|
|
216
|
+
const traverse = (nodes) => {
|
|
217
|
+
if (!nodes || nodes.length === 0) return;
|
|
218
|
+
for (const node of nodes) {
|
|
219
|
+
if (node.checked === false) continue;
|
|
220
|
+
if (node.children && node.children.length > 0) {
|
|
221
|
+
traverse(node.children);
|
|
222
|
+
} else if (node.checked === true) {
|
|
223
|
+
result.push(node.key);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
traverse(treeData);
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
var nodeExistsInTree = (nodes, searchValue) => {
|
|
231
|
+
return nodes.some((node) => {
|
|
232
|
+
if (node.value === searchValue || node.title === searchValue) {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
if (node.children && Array.isArray(node.children)) {
|
|
236
|
+
return nodeExistsInTree(node.children, searchValue);
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
var collectLeafValuesByKey = (nodes, targetValue, isLeafKey = "isLeaf") => {
|
|
242
|
+
for (const node of nodes) {
|
|
243
|
+
if (node.value === targetValue) {
|
|
244
|
+
if (node.children && Array.isArray(node.children) && node.children.length > 0) {
|
|
245
|
+
const leafNodes = getLeafNodes([node], isLeafKey);
|
|
246
|
+
return leafNodes.map((leaf) => leaf.value);
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
if (node.children && Array.isArray(node.children)) {
|
|
251
|
+
const result = collectLeafValuesByKey(
|
|
252
|
+
node.children,
|
|
253
|
+
targetValue,
|
|
254
|
+
isLeafKey
|
|
255
|
+
);
|
|
256
|
+
if (result !== null) {
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
};
|
|
263
|
+
var transformTreeKeys = (treeData, keyMapping, childrenKey = "children", logger = defaultLogger) => {
|
|
264
|
+
if (!Array.isArray(treeData)) {
|
|
265
|
+
logger.warn?.("transformTreeKeys: treeData must be an array");
|
|
266
|
+
return [];
|
|
267
|
+
}
|
|
268
|
+
const transformNode = (node) => {
|
|
269
|
+
if (!node || typeof node !== "object") {
|
|
270
|
+
return node;
|
|
271
|
+
}
|
|
272
|
+
const transformedNode = {};
|
|
273
|
+
Object.keys(node).forEach((key) => {
|
|
274
|
+
const value = node[key];
|
|
275
|
+
const newKey = keyMapping[key] || key;
|
|
276
|
+
if (key === childrenKey && Array.isArray(value)) {
|
|
277
|
+
transformedNode[newKey] = transformTreeKeys(
|
|
278
|
+
value,
|
|
279
|
+
keyMapping,
|
|
280
|
+
childrenKey,
|
|
281
|
+
logger
|
|
282
|
+
);
|
|
283
|
+
} else {
|
|
284
|
+
transformedNode[newKey] = value;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
return transformedNode;
|
|
288
|
+
};
|
|
289
|
+
return treeData.map(transformNode);
|
|
290
|
+
};
|
|
291
|
+
var transformTreeNodes = (treeData, transformer, childrenKey = "children", logger = defaultLogger) => {
|
|
292
|
+
if (!Array.isArray(treeData)) {
|
|
293
|
+
logger.warn?.("transformTreeNodes: treeData must be an array");
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
296
|
+
const transformNode = (node) => {
|
|
297
|
+
if (!node || typeof node !== "object") {
|
|
298
|
+
return node;
|
|
299
|
+
}
|
|
300
|
+
const children = node[childrenKey];
|
|
301
|
+
const nodeWithTransformedChildren = {
|
|
302
|
+
...node,
|
|
303
|
+
...Array.isArray(children) && {
|
|
304
|
+
[childrenKey]: transformTreeNodes(
|
|
305
|
+
children,
|
|
306
|
+
transformer,
|
|
307
|
+
childrenKey,
|
|
308
|
+
logger
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
return transformer(nodeWithTransformedChildren);
|
|
313
|
+
};
|
|
314
|
+
return treeData.map(transformNode);
|
|
315
|
+
};
|
|
316
|
+
var findParentOf = (nodes, targetKey) => {
|
|
317
|
+
for (const node of nodes) {
|
|
318
|
+
if (node.children?.some((child) => child.key === targetKey)) {
|
|
319
|
+
return node;
|
|
320
|
+
}
|
|
321
|
+
if (node.children) {
|
|
322
|
+
const found = findParentOf(node.children, targetKey);
|
|
323
|
+
if (found) return found;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
};
|
|
328
|
+
var findNodeByMatcher = (nodes, matcher, childrenKey = "children") => {
|
|
329
|
+
for (const node of nodes) {
|
|
330
|
+
if (matcher(node)) {
|
|
331
|
+
return node;
|
|
332
|
+
}
|
|
333
|
+
if (node[childrenKey]) {
|
|
334
|
+
const found = findNodeByMatcher(node[childrenKey], matcher, childrenKey);
|
|
335
|
+
if (found) {
|
|
336
|
+
return found;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return null;
|
|
341
|
+
};
|
|
342
|
+
var updateNodeByMatcher = (nodes, matcher, updater, childrenKey = "children") => {
|
|
343
|
+
return nodes.map((node) => {
|
|
344
|
+
if (matcher(node)) {
|
|
345
|
+
return updater(node);
|
|
346
|
+
}
|
|
347
|
+
if (node[childrenKey] && node[childrenKey].length > 0) {
|
|
348
|
+
const newChildren = updateNodeByMatcher(
|
|
349
|
+
node[childrenKey],
|
|
350
|
+
matcher,
|
|
351
|
+
updater,
|
|
352
|
+
childrenKey
|
|
353
|
+
);
|
|
354
|
+
if (newChildren !== node[childrenKey]) {
|
|
355
|
+
return {
|
|
356
|
+
...node,
|
|
357
|
+
[childrenKey]: newChildren
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return node;
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
var getNodePath = (treeData, targetKey, keyField = "key", childrenKey = "children") => {
|
|
365
|
+
const findPath = (nodes, target, currentPath) => {
|
|
366
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
367
|
+
const node = nodes[i];
|
|
368
|
+
const newPathNode = {
|
|
369
|
+
node,
|
|
370
|
+
depth: currentPath.length,
|
|
371
|
+
index: i,
|
|
372
|
+
parent: currentPath.length > 0 ? currentPath[currentPath.length - 1] : null,
|
|
373
|
+
path: currentPath.length === 0 ? String(node[keyField]) : `${currentPath[currentPath.length - 1].path}/${String(node[keyField])}`
|
|
374
|
+
};
|
|
375
|
+
if (node[keyField] === target) {
|
|
376
|
+
return [...currentPath, newPathNode];
|
|
377
|
+
}
|
|
378
|
+
const children = node[childrenKey];
|
|
379
|
+
if (children && Array.isArray(children) && children.length > 0) {
|
|
380
|
+
const result = findPath(children, target, [
|
|
381
|
+
...currentPath,
|
|
382
|
+
newPathNode
|
|
383
|
+
]);
|
|
384
|
+
if (result) {
|
|
385
|
+
return result;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
};
|
|
391
|
+
return findPath(treeData, targetKey, []);
|
|
392
|
+
};
|
|
393
|
+
var getNodeDepth = (treeData, targetKey, keyField = "key", childrenKey = "children") => {
|
|
394
|
+
const path = getNodePath(treeData, targetKey, keyField, childrenKey);
|
|
395
|
+
return path ? path.length - 1 : -1;
|
|
396
|
+
};
|
|
397
|
+
var getNodeBreadcrumb = (treeData, targetKey, keyField = "key", childrenKey = "children") => {
|
|
398
|
+
const path = getNodePath(treeData, targetKey, keyField, childrenKey);
|
|
399
|
+
return path ? path.map((p) => p.node) : [];
|
|
400
|
+
};
|
|
401
|
+
var getTreeStats = (treeData, childrenKey = "children") => {
|
|
402
|
+
let totalNodes = 0;
|
|
403
|
+
let maxDepth = 0;
|
|
404
|
+
let leafCount = 0;
|
|
405
|
+
const traverse = (nodes, depth) => {
|
|
406
|
+
for (const node of nodes) {
|
|
407
|
+
totalNodes++;
|
|
408
|
+
maxDepth = Math.max(maxDepth, depth);
|
|
409
|
+
const children = node[childrenKey];
|
|
410
|
+
if (children && Array.isArray(children) && children.length > 0) {
|
|
411
|
+
traverse(children, depth + 1);
|
|
412
|
+
} else {
|
|
413
|
+
leafCount++;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
traverse(treeData, 0);
|
|
418
|
+
return { totalNodes, maxDepth, leafCount };
|
|
419
|
+
};
|
|
420
|
+
var mapTree = (treeData, mapper, childrenKey = "children") => {
|
|
421
|
+
const traverse = (nodes, parent) => {
|
|
422
|
+
return nodes.map((node) => {
|
|
423
|
+
const mappedNode = mapper(node, parent);
|
|
424
|
+
const children = node[childrenKey];
|
|
425
|
+
if (children && Array.isArray(children) && children.length > 0) {
|
|
426
|
+
return {
|
|
427
|
+
...mappedNode,
|
|
428
|
+
[childrenKey]: traverse(children, node)
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
return mappedNode;
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
return traverse(treeData);
|
|
435
|
+
};
|
|
436
|
+
var findFirstLeaf = (treeData, childrenKey = "children") => {
|
|
437
|
+
for (const node of treeData) {
|
|
438
|
+
const children = node[childrenKey];
|
|
439
|
+
if (!children || children.length === 0) {
|
|
440
|
+
return node;
|
|
441
|
+
}
|
|
442
|
+
const leaf = findFirstLeaf(children, childrenKey);
|
|
443
|
+
if (leaf) return leaf;
|
|
444
|
+
}
|
|
445
|
+
return null;
|
|
446
|
+
};
|
|
447
|
+
var traverseTreeValues = (treeData, key, childrenKey = "children") => {
|
|
448
|
+
const result = [];
|
|
449
|
+
const traverse = (nodes) => {
|
|
450
|
+
for (const node of nodes) {
|
|
451
|
+
if (key in node) {
|
|
452
|
+
result.push(node[key]);
|
|
453
|
+
}
|
|
454
|
+
const children = node[childrenKey];
|
|
455
|
+
if (children && Array.isArray(children) && children.length > 0) {
|
|
456
|
+
traverse(children);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
traverse(treeData);
|
|
461
|
+
return result;
|
|
462
|
+
};
|
|
463
|
+
var convertGroupsToTreeData = (groups, groupKey = "group", _childrenKey = "children") => {
|
|
464
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
465
|
+
for (const item of groups) {
|
|
466
|
+
const groupName = String(item[groupKey] || "");
|
|
467
|
+
if (!groupMap.has(groupName)) {
|
|
468
|
+
groupMap.set(groupName, {
|
|
469
|
+
label: groupName,
|
|
470
|
+
value: groupName,
|
|
471
|
+
children: []
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
groupMap.get(groupName).children.push(item);
|
|
475
|
+
}
|
|
476
|
+
return Array.from(groupMap.values());
|
|
477
|
+
};
|
|
478
|
+
export {
|
|
479
|
+
addLeafProperties,
|
|
480
|
+
cloneNode,
|
|
481
|
+
collectLeafValuesByKey,
|
|
482
|
+
convertGroupsToTreeData,
|
|
483
|
+
copyNode,
|
|
484
|
+
deleteNode,
|
|
485
|
+
filterCheckedLeafKeys,
|
|
486
|
+
filterTreeNodes,
|
|
487
|
+
findFirstLeaf,
|
|
488
|
+
findNodeById as findNode,
|
|
489
|
+
collectLeafValuesByKey as findNodeAndCollectLeafValues,
|
|
490
|
+
findNodeById,
|
|
491
|
+
findNodeByKey,
|
|
492
|
+
findNodeByMatcher,
|
|
493
|
+
nodeExistsInTree as findNodeInTree,
|
|
494
|
+
findParentOf,
|
|
495
|
+
findParentOf as findTreeNode,
|
|
496
|
+
flattenTree,
|
|
497
|
+
getLeafNodes,
|
|
498
|
+
getNodeBreadcrumb,
|
|
499
|
+
getNodeDepth,
|
|
500
|
+
getNodePath,
|
|
501
|
+
getTreeStats,
|
|
502
|
+
mapTree,
|
|
503
|
+
moveNodeInTree,
|
|
504
|
+
nodeExistsInTree,
|
|
505
|
+
searchInTree,
|
|
506
|
+
transformTreeKeys,
|
|
507
|
+
transformTreeNodes,
|
|
508
|
+
traverseTreeValues,
|
|
509
|
+
updateKeys,
|
|
510
|
+
updateNodeByMatcher,
|
|
511
|
+
updateNodeTitleByKey
|
|
512
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zid-utils/tree-utils",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "Tree data structure utility functions",
|
|
5
|
+
"repository": "github:huangzida/utils-packages",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"tsup": "^8.0.2",
|
|
22
|
+
"vitest": "^2.0.0",
|
|
23
|
+
"typescript": "^5.4.5"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup src/index.ts --format esm --out-dir dist --clean",
|
|
27
|
+
"test": "vitest run"
|
|
28
|
+
}
|
|
29
|
+
}
|