path-treeify 1.3.0-beta.56a60fd β 1.3.0-beta.9bb4032
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/README.md +2 -8
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/types/index.d.ts +46 -73
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
<img alt="LOGO" width="320" src="https://assets-amu.pages.dev/path-treeify/logo.png">
|
|
3
|
-
</div>
|
|
4
|
-
<br/>
|
|
1
|
+
# path-treeify
|
|
5
2
|
|
|
6
3
|
> π [δΈζζζ‘£ (Chinese README)](https://github.com/isaaxite/path-treeify/blob/main/docs/README.zh-CN.md)
|
|
7
4
|
|
|
@@ -17,9 +14,6 @@
|
|
|
17
14
|
<a href="https://nodejs.org">
|
|
18
15
|
<img alt="node" src="https://img.shields.io/node/v/path-treeify">
|
|
19
16
|
</a>
|
|
20
|
-
<a href="https://github.com/isaaxite/path-treeify/blob/main/CHANGELOG.md">
|
|
21
|
-
<img alt="CHANGELOG" src="https://img.shields.io/badge/changelog-maintained-brightgreen">
|
|
22
|
-
</a>
|
|
23
17
|
<a href="https://github.com/isaaxite/path-treeify/blob/main/LICENSE">
|
|
24
18
|
<img alt="GitHub License" src="https://img.shields.io/github/license/isaaxite/path-treeify">
|
|
25
19
|
</a>
|
|
@@ -259,4 +253,4 @@ const tree = treeify.build();
|
|
|
259
253
|
|
|
260
254
|
## License
|
|
261
255
|
|
|
262
|
-
[MIT](https://github.com/isaaxite/path-treeify/blob/main/LICENSE) Β© [isaaxite](https://github.com/isaaxite)
|
|
256
|
+
[MIT](https://github.com/isaaxite/path-treeify/blob/main/LICENSE) Β© [isaaxite](https://github.com/isaaxite)
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var t=require("fs"),e=require("path");class r{static isValid(e){try{return t.accessSync(e,t.constants.F_OK),!0}catch{return!1}}static isDirectory(e){try{return t.statSync(e).isDirectory()}catch{return!1}}}class i{constructor(t){this.parent=null,this.value="",this.children=[],this.base=t}getPath(){let t="",r=this;for(;r.parent;)t=t?`${r.value}${e.sep}${t}`:r.value,r=r.parent;return{relative:t,absolute:e.resolve(this.base,t)}}}exports.PathTreeify=class{constructor({filter:t,base:e}){if(void 0!==t&&(this.validateFilter(t),this.filter=t),!e||!r.isValid(e))throw new Error(`${e} is not a valid path!`);if(!r.isDirectory(e))throw new Error(`${e} is not a dirPath!`);this.base=e}validateFilter(t){if("function"!=typeof t)throw new TypeError("filter must be a function");if(1!==t.length)throw new TypeError("filter must accept exactly one parameter");try{if("boolean"!=typeof t({name:"test",postPath:"/test"}))throw new TypeError("filter must return a boolean")}catch(t){throw new TypeError("filter function threw an error during test: "+t)}}initNode(t=null){const e=new i(this.base);return t&&(e.parent=t),e}buildChildren(r,i){const s=t.readdirSync(r),a=[];for(const n of s){const s=e.join(r,n);if(!t.statSync(s).isDirectory())continue;if(this.filter&&!this.filter({dirPath:r,name:n}))continue;const o=this.initNode();o.value=n,o.parent=i,o.children=this.buildChildren(s,o),a.push(o)}return a}checkRelativePaths(t){if(!Array.isArray(t))throw new Error("Expected array, got "+typeof t);for(let i=0;i<t.length;i++){const s=t[i];if("string"!=typeof s)throw new Error(`Item at index ${i} is not a string, got ${typeof s}`);const a=e.resolve(this.base,s);if(!r.isValid(a))throw new Error(`Path does not exist or is not accessible: ${a} (from relative path: ${s})`);if(!r.isDirectory(a))throw new Error(`Path is not a directory: ${a} (from relative path: ${s})`)}}formatDirnames(t){return t.map(t=>t.replace(/^\/+|\/+$/g,"")).filter(t=>""!==t)}getAllDirNamesUnderBase(){return t.readdirSync(this.base).filter(t=>{const i=e.resolve(this.base,t);return!!r.isDirectory(i)&&!(this.filter&&!this.filter({name:t,dirPath:this.base}))})}buildByDirNames(t){const r=this.initNode(),i=this.formatDirnames(t);this.checkRelativePaths(i);for(const t of i){const i=this.initNode();i.value=t,i.parent=r,i.children=this.buildChildren(e.resolve(this.base,t),i),r.children.push(i)}return r}buildByFilter(t){const e=this.getAllDirNamesUnderBase();return this.buildByDirNames(e.filter(t))}getPathBy(t){let r="",i=t;for(;i.parent;)r=r?`${i.value}${e.sep}${r}`:i.value,i=i.parent;return{relative:r,absolute:e.resolve(this.base,r)}}buildBy(t){if(Array.isArray(t))return this.buildByDirNames(t);if("function"==typeof t)return this.buildByFilter(t);throw new TypeError("buildBy: expected an array of strings or a filter function, but received "+typeof t)}build(){const t=this.getAllDirNamesUnderBase();return this.buildByDirNames(t)}};
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readdirSync as t,
|
|
1
|
+
import{readdirSync as t,statSync as r,accessSync as e,constants as i}from"fs";import{join as s,resolve as a,sep as n}from"path";class o{static isValid(t){try{return e(t,i.F_OK),!0}catch{return!1}}static isDirectory(t){try{return r(t).isDirectory()}catch{return!1}}}class l{constructor(t){this.parent=null,this.value="",this.children=[],this.base=t}getPath(){let t="",r=this;for(;r.parent;)t=t?`${r.value}${n}${t}`:r.value,r=r.parent;return{relative:t,absolute:a(this.base,t)}}}class h{constructor({filter:t,base:r}){if(void 0!==t&&(this.validateFilter(t),this.filter=t),!r||!o.isValid(r))throw new Error(`${r} is not a valid path!`);if(!o.isDirectory(r))throw new Error(`${r} is not a dirPath!`);this.base=r}validateFilter(t){if("function"!=typeof t)throw new TypeError("filter must be a function");if(1!==t.length)throw new TypeError("filter must accept exactly one parameter");try{if("boolean"!=typeof t({name:"test",postPath:"/test"}))throw new TypeError("filter must return a boolean")}catch(t){throw new TypeError("filter function threw an error during test: "+t)}}initNode(t=null){const r=new l(this.base);return t&&(r.parent=t),r}buildChildren(e,i){const a=t(e),n=[];for(const t of a){const a=s(e,t);if(!r(a).isDirectory())continue;if(this.filter&&!this.filter({dirPath:e,name:t}))continue;const o=this.initNode();o.value=t,o.parent=i,o.children=this.buildChildren(a,o),n.push(o)}return n}checkRelativePaths(t){if(!Array.isArray(t))throw new Error("Expected array, got "+typeof t);for(let r=0;r<t.length;r++){const e=t[r];if("string"!=typeof e)throw new Error(`Item at index ${r} is not a string, got ${typeof e}`);const i=a(this.base,e);if(!o.isValid(i))throw new Error(`Path does not exist or is not accessible: ${i} (from relative path: ${e})`);if(!o.isDirectory(i))throw new Error(`Path is not a directory: ${i} (from relative path: ${e})`)}}formatDirnames(t){return t.map(t=>t.replace(/^\/+|\/+$/g,"")).filter(t=>""!==t)}getAllDirNamesUnderBase(){return t(this.base).filter(t=>{const r=a(this.base,t);return!!o.isDirectory(r)&&!(this.filter&&!this.filter({name:t,dirPath:this.base}))})}buildByDirNames(t){const r=this.initNode(),e=this.formatDirnames(t);this.checkRelativePaths(e);for(const t of e){const e=this.initNode();e.value=t,e.parent=r,e.children=this.buildChildren(a(this.base,t),e),r.children.push(e)}return r}buildByFilter(t){const r=this.getAllDirNamesUnderBase();return this.buildByDirNames(r.filter(t))}getPathBy(t){let r="",e=t;for(;e.parent;)r=r?`${e.value}${n}${r}`:e.value,e=e.parent;return{relative:r,absolute:a(this.base,r)}}buildBy(t){if(Array.isArray(t))return this.buildByDirNames(t);if("function"==typeof t)return this.buildByFilter(t);throw new TypeError("buildBy: expected an array of strings or a filter function, but received "+typeof t)}build(){const t=this.getAllDirNamesUnderBase();return this.buildByDirNames(t)}}export{h as PathTreeify};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,120 +1,93 @@
|
|
|
1
|
-
/** A filter function that determines whether
|
|
1
|
+
/** A filter function that determines whether a directory should be included in the tree */
|
|
2
2
|
type FilterFunction = (params: {
|
|
3
3
|
name: string;
|
|
4
4
|
dirPath: string;
|
|
5
5
|
}) => boolean;
|
|
6
6
|
/** Constructor options for PathTreeify */
|
|
7
7
|
interface PathTreeifyProps {
|
|
8
|
-
/** The root directory to scan */
|
|
9
8
|
base: string;
|
|
10
|
-
/** Optional filter applied to every entry during recursive traversal */
|
|
11
9
|
filter?: FilterFunction;
|
|
12
|
-
/** When true, files are included as leaf nodes alongside directories. Defaults to false */
|
|
13
|
-
fileVisible?: boolean;
|
|
14
|
-
}
|
|
15
|
-
/** Classification of a node in the path tree */
|
|
16
|
-
export declare enum PathTreeNodeType {
|
|
17
|
-
Dir = "dir",
|
|
18
|
-
File = "file",
|
|
19
|
-
/** Assigned before the node's type has been resolved */
|
|
20
|
-
Unknown = "unknown"
|
|
21
10
|
}
|
|
22
|
-
/** Represents a single
|
|
23
|
-
|
|
11
|
+
/** Represents a single node (directory) in the path tree */
|
|
12
|
+
declare class PathTreeNode {
|
|
13
|
+
/** The root base path used to resolve absolute paths */
|
|
14
|
+
private base;
|
|
24
15
|
/** Reference to the parent node; null for the root node */
|
|
25
16
|
parent: PathTreeNode | null;
|
|
26
|
-
/** The
|
|
17
|
+
/** The directory name of this node (not a full path) */
|
|
27
18
|
value: string;
|
|
28
|
-
/** Child nodes
|
|
19
|
+
/** Child nodes representing subdirectories */
|
|
29
20
|
children: PathTreeNode[];
|
|
30
|
-
|
|
31
|
-
type: PathTreeNodeType;
|
|
21
|
+
constructor(base: string);
|
|
32
22
|
/**
|
|
33
|
-
* Walks up the parent chain to compute this node's relative
|
|
34
|
-
* @returns
|
|
23
|
+
* Walks up the parent chain to compute this node's relative and absolute paths.
|
|
24
|
+
* @returns An object containing the relative path from base and the absolute path
|
|
35
25
|
*/
|
|
36
|
-
getPath():
|
|
26
|
+
getPath(): {
|
|
27
|
+
relative: string;
|
|
28
|
+
absolute: string;
|
|
29
|
+
};
|
|
37
30
|
}
|
|
38
|
-
/** Builds a tree of
|
|
31
|
+
/** Builds a tree of directory nodes rooted at a given base path */
|
|
39
32
|
export declare class PathTreeify {
|
|
40
33
|
/** The root directory to scan */
|
|
41
34
|
private base;
|
|
35
|
+
/** Optional filter applied to each directory during traversal */
|
|
36
|
+
private filter?;
|
|
37
|
+
constructor({ filter, base }: Partial<PathTreeifyProps>);
|
|
42
38
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
39
|
+
* Validates that the provided filter is a function, accepts one parameter,
|
|
40
|
+
* and returns a boolean. Throws a TypeError if any condition is violated.
|
|
45
41
|
*/
|
|
46
|
-
private
|
|
47
|
-
/** When true, files are included as leaf nodes during traversal. Defaults to false */
|
|
48
|
-
private fileVisible;
|
|
49
|
-
/**
|
|
50
|
-
* Determines whether a given entry should be included in the tree.
|
|
51
|
-
* - If {@link fileVisible} is false, non-directory entries are always excluded.
|
|
52
|
-
* - If a {@link userFilter} is set, the entry must also satisfy it.
|
|
53
|
-
* @param absPath - Absolute path of the entry to test
|
|
54
|
-
* @param name - Entry name (filename or directory name)
|
|
55
|
-
*/
|
|
56
|
-
private applyFilter;
|
|
57
|
-
constructor({ filter, base, fileVisible }: Partial<PathTreeifyProps>);
|
|
42
|
+
private validateFilter;
|
|
58
43
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
44
|
+
* Creates and optionally attaches a new PathTreeNode to a parent.
|
|
45
|
+
* @param parent - The parent node to attach to, or null for the root
|
|
61
46
|
*/
|
|
62
|
-
private validateFilter;
|
|
63
|
-
/** Creates a new unattached {@link PathTreeNode} */
|
|
64
47
|
private initNode;
|
|
65
48
|
/**
|
|
66
|
-
* Recursively reads
|
|
67
|
-
*
|
|
68
|
-
* files (when {@link fileVisible} is true) become leaf nodes.
|
|
49
|
+
* Recursively reads a directory and builds child nodes for each subdirectory.
|
|
50
|
+
* Applies the instance-level filter if one is set.
|
|
69
51
|
* @param dirPath - Absolute path of the directory to read
|
|
70
|
-
* @param parent - The parent node to attach
|
|
52
|
+
* @param parent - The parent node to attach children to
|
|
71
53
|
*/
|
|
72
54
|
private buildChildren;
|
|
73
55
|
/**
|
|
74
|
-
* Validates that
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* @param relativeSegments - Relative path strings to validate
|
|
56
|
+
* Validates that each entry in the array is a string pointing to
|
|
57
|
+
* an accessible directory relative to the base path.
|
|
58
|
+
* @param relativeDirNames - Array of relative directory path strings to validate
|
|
78
59
|
*/
|
|
79
60
|
private checkRelativePaths;
|
|
80
61
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* Entries that reduce to an empty string (e.g. `"///"`) are removed.
|
|
84
|
-
* @param segments - Raw path strings to normalise
|
|
85
|
-
*/
|
|
86
|
-
private formatSegments;
|
|
87
|
-
/**
|
|
88
|
-
* Returns the names of all immediate entries under {@link base} that pass
|
|
89
|
-
* {@link applyFilter}.
|
|
62
|
+
* Strips leading and trailing slashes from each directory name
|
|
63
|
+
* and removes any resulting empty strings.
|
|
90
64
|
*/
|
|
91
|
-
private
|
|
65
|
+
private formatDirnames;
|
|
66
|
+
/** Returns the names of all immediate subdirectories under the base path */
|
|
67
|
+
private getAllDirNamesUnderBase;
|
|
92
68
|
/**
|
|
93
|
-
* Builds a
|
|
94
|
-
*
|
|
95
|
-
* @param segments - Relative paths to include as top-level nodes
|
|
69
|
+
* Builds a tree rooted at base, containing only the specified subdirectories.
|
|
70
|
+
* @param dirNames - Relative directory names to include as top-level nodes
|
|
96
71
|
*/
|
|
97
|
-
private
|
|
72
|
+
private buildByDirNames;
|
|
98
73
|
/**
|
|
99
|
-
* Builds a
|
|
100
|
-
*
|
|
101
|
-
* For recursive filtering use the `filter` constructor option.
|
|
102
|
-
* @param filter - Predicate applied to each top-level entry name
|
|
74
|
+
* Builds a tree using only the subdirectories under base that pass the given filter.
|
|
75
|
+
* @param filter - A predicate applied to each top-level directory name
|
|
103
76
|
*/
|
|
104
77
|
private buildByFilter;
|
|
105
78
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
79
|
+
* Computes the relative and absolute paths for a given node
|
|
80
|
+
* by walking up the parent chain.
|
|
108
81
|
*/
|
|
109
82
|
getPathBy(node: PathTreeNode): {
|
|
110
83
|
relative: string;
|
|
111
84
|
absolute: string;
|
|
112
85
|
};
|
|
113
|
-
/** Overload: build the tree from an explicit list of relative
|
|
114
|
-
buildBy(
|
|
115
|
-
/** Overload: build the tree from a predicate applied to top-level
|
|
116
|
-
buildBy(filter: (
|
|
117
|
-
/** Builds a full tree from all immediate
|
|
86
|
+
/** Overload: build the tree from an explicit list of relative directory names */
|
|
87
|
+
buildBy(dirNames: string[]): PathTreeNode;
|
|
88
|
+
/** Overload: build the tree from a predicate applied to top-level directory names */
|
|
89
|
+
buildBy(filter: (dirName: string) => boolean): PathTreeNode;
|
|
90
|
+
/** Builds a full tree from all immediate subdirectories under the base path */
|
|
118
91
|
build(): PathTreeNode;
|
|
119
92
|
}
|
|
120
93
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "path-treeify",
|
|
3
|
-
"version": "1.3.0-beta.
|
|
3
|
+
"version": "1.3.0-beta.9bb4032",
|
|
4
4
|
"description": "Convert a path or an array of paths into a tree-structured JavaScript object, where each node has a `parent` property that holds a circular reference to its parent node.",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -95,7 +95,6 @@
|
|
|
95
95
|
"rollup": "^4.59.0",
|
|
96
96
|
"tap-xunit": "^2.4.1",
|
|
97
97
|
"tslib": "^2.8.1",
|
|
98
|
-
"tsx": "^4.21.0",
|
|
99
98
|
"typescript": "^5.9.3"
|
|
100
99
|
},
|
|
101
100
|
"engines": {
|