@wtasnorg/node-lib 0.0.5 → 0.0.7

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/src/find.ts ADDED
@@ -0,0 +1,99 @@
1
+ import { resolve, join } from "node:path";
2
+
3
+ interface FileSystemDependencies {
4
+ readdir: (path: string, opts: { withFileTypes: true }) => Promise<{ name: string; isDirectory(): boolean; }[]>;
5
+ stat: (path: string) => Promise<{ isDirectory(): boolean }>;
6
+ }
7
+
8
+ interface FindDirectoriesOptions {
9
+ maxDepth?: number;
10
+ followSymlinks?: boolean;
11
+ allowlist?: string[] | ((absPath: string, name: string) => boolean);
12
+ blocklist?: string[] | ((absPath: string, name: string) => boolean);
13
+ }
14
+
15
+ /**
16
+ * Factory that produces an async findDirectories function with
17
+ * injected filesystem dependencies for full testability.
18
+ */
19
+ function createFindDirectories(deps: FileSystemDependencies) {
20
+
21
+ const { readdir } = deps;
22
+
23
+ return async function findDirectories(
24
+ root: string,
25
+ options: FindDirectoriesOptions = {}
26
+ ): Promise<string[]> {
27
+
28
+ const {
29
+ maxDepth = 1,
30
+ allowlist,
31
+ blocklist
32
+ } = options;
33
+
34
+ const absRoot = resolve(root);
35
+ const results: string[] = [];
36
+
37
+
38
+ function isAllowed(absPath: string, name: string): boolean {
39
+ if (allowlist) {
40
+ if (Array.isArray(allowlist)) {
41
+ if (!allowlist.includes(name)) return false;
42
+ } else if (!allowlist(absPath, name)) {
43
+ return false;
44
+ }
45
+ }
46
+ return true;
47
+ }
48
+
49
+ function isBlocked(absPath: string, name: string): boolean {
50
+ if (blocklist) {
51
+ if (Array.isArray(blocklist)) {
52
+ if (blocklist.includes(name)) return true;
53
+ } else if (blocklist(absPath, name)) {
54
+ return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+
60
+ async function walk(currentPath: string, depth: number): Promise<void> {
61
+ if (depth > maxDepth) return;
62
+
63
+ const entries = await readdir(currentPath, { withFileTypes: true });
64
+
65
+ for (const entry of entries) {
66
+ const childPath = resolve(join(currentPath, entry.name));
67
+
68
+ const isDirectory = entry.isDirectory();
69
+
70
+ if (!isDirectory) continue;
71
+
72
+ if (isBlocked(childPath, entry.name)) continue;
73
+ if (!isAllowed(childPath, entry.name)) continue;
74
+
75
+ results.push(childPath);
76
+
77
+ if (depth < maxDepth) {
78
+ await walk(childPath, depth + 1);
79
+ }
80
+ }
81
+ }
82
+
83
+ // match find(1): root is always included
84
+ results.push(absRoot);
85
+
86
+ await walk(absRoot, 1);
87
+
88
+ return results;
89
+ };
90
+ }
91
+
92
+ export {
93
+ createFindDirectories,
94
+ };
95
+
96
+ export type {
97
+ FileSystemDependencies,
98
+ FindDirectoriesOptions,
99
+ };
package/src/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import { hello } from "./hello.js";
2
2
  import { pojo } from "./pojo.js";
3
- export { hello, pojo };
3
+ import type { FindDirectoriesOptions, FileSystemDependencies } from "./find.js";
4
+ import { createFindDirectories } from "./find.js";
5
+ export { hello, pojo, createFindDirectories };
6
+ export type { FindDirectoriesOptions, FileSystemDependencies, };
4
7
  //# sourceMappingURL=index.d.ts.map
package/src/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { hello } from "./hello.js";
2
2
  import { pojo } from "./pojo.js";
3
- export { hello, pojo };
3
+ import { createFindDirectories } from "./find.js";
4
+ export { hello, pojo, createFindDirectories };
4
5
  //# sourceMappingURL=index.js.map
package/src/index.ts CHANGED
@@ -1,7 +1,15 @@
1
1
  import { hello } from "./hello.js";
2
2
  import { pojo } from "./pojo.js";
3
+ import type { FindDirectoriesOptions, FileSystemDependencies } from "./find.js";
4
+ import { createFindDirectories } from "./find.js";
3
5
 
4
6
  export {
5
7
  hello,
6
- pojo
8
+ pojo,
9
+ createFindDirectories
10
+ };
11
+
12
+ export type {
13
+ FindDirectoriesOptions,
14
+ FileSystemDependencies,
7
15
  };
package/src/pojo.d.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  *
6
6
  * @template T
7
7
  * @param {T} instance - A class instance to convert.
8
- * @returns {Object<string, any>} A plain JavaScript object containing only data fields.
8
+ * @returns {Object<string, unknown>} A plain JavaScript object containing only data fields.
9
9
  */
10
- declare function pojo<T extends object>(instance: T): Record<string, any>;
10
+ declare function pojo<T extends object>(instance: T): Record<string, unknown>;
11
11
  export { pojo };
12
12
  //# sourceMappingURL=pojo.d.ts.map
package/src/pojo.js CHANGED
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @template T
7
7
  * @param {T} instance - A class instance to convert.
8
- * @returns {Object<string, any>} A plain JavaScript object containing only data fields.
8
+ * @returns {Object<string, unknown>} A plain JavaScript object containing only data fields.
9
9
  */
10
10
  function pojo(instance) {
11
11
  return Object.fromEntries(Object.entries(instance).filter(([_, value]) => typeof value !== "function"));
package/src/pojo.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * @template T
7
7
  * @param {T} instance - A class instance to convert.
8
- * @returns {Object<string, any>} A plain JavaScript object containing only data fields.
8
+ * @returns {Object<string, unknown>} A plain JavaScript object containing only data fields.
9
9
  */
10
- function pojo<T extends object>(instance: T): Record<string, any> {
10
+ function pojo<T extends object>(instance: T): Record<string, unknown> {
11
11
  return Object.fromEntries(
12
12
  Object.entries(instance).filter(([_, value]) => typeof value !== "function")
13
13
  );
package/test_report ADDED
@@ -0,0 +1,26 @@
1
+
2
+ > @wtasnorg/node-lib@0.0.7 test
3
+ > bash -c 'node --test src/**/*.test.js'
4
+
5
+ ✔ find: findDirectories success (1.077042ms)
6
+ ✔ find: findDirectories symlink is NOT treated as a directory (0.181028ms)
7
+ ✔ find: findDirectories at depth=2 (0.264408ms)
8
+ ✔ find: findDirectories at depth=3 (0.225558ms)
9
+ hello from @wtasnorg/node-lib
10
+ hello from @wtasnorg/node-lib
11
+ ▶ hello
12
+ ✔ returns a string that has the word 'hello' in it (0.855703ms)
13
+ ✔ returns exact string (0.132439ms)
14
+ ✔ hello (1.649597ms)
15
+ ✔ pojo() should return only enumerable data fields (0.948072ms)
16
+ ✔ pojo() should exclude methods (0.137609ms)
17
+ ✔ pojo() should exclude prototype properties (0.141089ms)
18
+ ✔ pojo() should ignore non-enumerable own properties (0.671565ms)
19
+ ℹ tests 10
20
+ ℹ suites 1
21
+ ℹ pass 10
22
+ ℹ fail 0
23
+ ℹ cancelled 0
24
+ ℹ skipped 0
25
+ ℹ todo 0
26
+ ℹ duration_ms 50.692585
package/typedoc.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "$schema": "https://typedoc.org/schema.json",
3
- "entryPoints": ["./src/index.ts"],
3
+ "entryPoints": [
4
+ "./src/index.ts"
5
+ ],
4
6
  "excludePrivate": true,
5
7
  "excludeProtected": true,
6
8
  "name": "@wtasnorg/node-lib",
7
9
  "out": "docs",
8
- "plugin": ["typedoc-plugin-markdown"],
10
+ "plugin": [
11
+ "typedoc-plugin-markdown"
12
+ ],
9
13
  "theme": "default",
10
14
  "tsconfig": "./tsconfig.json",
11
15
  }