@thi.ng/file-io 0.5.28 → 1.0.2

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-10-23T07:37:37Z
3
+ - **Last updated**: 2023-11-24T09:35:46Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,18 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ # [1.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/file-io@1.0.0) (2023-11-09)
13
+
14
+ #### 🛑 Breaking changes
15
+
16
+ - update matching logic for files()/dirs() ([8f275b5](https://github.com/thi-ng/umbrella/commit/8f275b5))
17
+ - BREAKING CHANGE: files()/dirs() matchers use full relative sub-path
18
+ - add support for arbitrary predicate fns as matcher
19
+
20
+ #### ♻️ Refactoring
21
+
22
+ - update all tests (packages A-S) ([e3085e4](https://github.com/thi-ng/umbrella/commit/e3085e4))
23
+
12
24
  ## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/file-io@0.5.0) (2023-02-05)
13
25
 
14
26
  #### 🚀 Features
package/README.md CHANGED
@@ -44,7 +44,7 @@ For Node.js REPL:
44
44
  const fileIo = await import("@thi.ng/file-io");
45
45
  ```
46
46
 
47
- Package sizes (brotli'd, pre-treeshake): ESM: 1.25 KB
47
+ Package sizes (brotli'd, pre-treeshake): ESM: 1.30 KB
48
48
 
49
49
  ## Dependencies
50
50
 
package/files.d.ts CHANGED
@@ -1,11 +1,14 @@
1
+ import type { Predicate } from "@thi.ng/api";
1
2
  import type { ILogger } from "@thi.ng/logger";
2
3
  /**
3
4
  * Recursively reads given directory (up to given max. depth, default: infinite)
4
- * and yields sequence of file names matching given extension (or regexp).
5
+ * and yields sequence of file names matching given extension (or regexp or
6
+ * predicate).
5
7
  *
6
8
  * @remarks
7
- * If NO `match` is given, all files will be matched. Directory names will not
8
- * be tested and are always traversed (up to given `maxDepth`).
9
+ * Files will be matched using their _full_ relative sub-path (starting with
10
+ * given `dir`). If NO `match` is given, all files will be matched. Directories
11
+ * will *not* be tested and are always traversed (up to given `maxDepth`).
9
12
  *
10
13
  * The optional `logger` is only used to log errors for files which couldn't be
11
14
  * accessed.
@@ -15,13 +18,13 @@ import type { ILogger } from "@thi.ng/logger";
15
18
  * @param maxDepth
16
19
  * @param logger
17
20
  */
18
- export declare const files: (dir: string, match?: string | RegExp, maxDepth?: number, logger?: ILogger) => IterableIterator<string>;
21
+ export declare const files: (dir: string, match?: string | RegExp | Predicate<string>, maxDepth?: number, logger?: ILogger) => IterableIterator<string>;
19
22
  /**
20
23
  * Similar to {@link files}, however yields iterator of only matching
21
24
  * sub-directories in given `dir`. Normal files are being ignored.
22
25
  *
23
26
  * @remarks
24
- * Unlike the regex matching in {@link files}, here the regex will be applied to
27
+ * Like the matcher in {@link files}, the regex or predicate will be applied to
25
28
  * the _full_ sub-path (starting with `dir`) in order to determine a match.
26
29
  *
27
30
  * @param dir
@@ -29,5 +32,5 @@ export declare const files: (dir: string, match?: string | RegExp, maxDepth?: nu
29
32
  * @param maxDepth
30
33
  * @param logger
31
34
  */
32
- export declare const dirs: (dir: string, match?: string | RegExp, maxDepth?: number, logger?: ILogger) => IterableIterator<string>;
35
+ export declare const dirs: (dir: string, match?: string | RegExp | Predicate<string>, maxDepth?: number, logger?: ILogger) => IterableIterator<string>;
33
36
  //# sourceMappingURL=files.d.ts.map
package/files.js CHANGED
@@ -1,14 +1,17 @@
1
+ import { isFunction } from "@thi.ng/checks/is-function";
1
2
  import { isString } from "@thi.ng/checks/is-string";
2
3
  import { readdirSync, statSync } from "fs";
3
4
  import { sep } from "path";
4
5
  import { isDirectory } from "./dir.js";
5
6
  /**
6
7
  * Recursively reads given directory (up to given max. depth, default: infinite)
7
- * and yields sequence of file names matching given extension (or regexp).
8
+ * and yields sequence of file names matching given extension (or regexp or
9
+ * predicate).
8
10
  *
9
11
  * @remarks
10
- * If NO `match` is given, all files will be matched. Directory names will not
11
- * be tested and are always traversed (up to given `maxDepth`).
12
+ * Files will be matched using their _full_ relative sub-path (starting with
13
+ * given `dir`). If NO `match` is given, all files will be matched. Directories
14
+ * will *not* be tested and are always traversed (up to given `maxDepth`).
12
15
  *
13
16
  * The optional `logger` is only used to log errors for files which couldn't be
14
17
  * accessed.
@@ -22,14 +25,14 @@ export const files = (dir, match = "", maxDepth = Infinity, logger) => __files(d
22
25
  function* __files(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
23
26
  if (depth >= maxDepth)
24
27
  return;
25
- const re = __ensureRegEx(match);
26
- for (let f of readdirSync(dir)) {
28
+ const pred = __ensurePred(match);
29
+ for (let f of readdirSync(dir).sort()) {
27
30
  const curr = dir + sep + f;
28
31
  try {
29
32
  if (isDirectory(curr)) {
30
33
  yield* __files(curr, match, logger, maxDepth, depth + 1);
31
34
  }
32
- else if (re.test(f)) {
35
+ else if (pred(curr)) {
33
36
  yield curr;
34
37
  }
35
38
  }
@@ -44,7 +47,7 @@ function* __files(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
44
47
  * sub-directories in given `dir`. Normal files are being ignored.
45
48
  *
46
49
  * @remarks
47
- * Unlike the regex matching in {@link files}, here the regex will be applied to
50
+ * Like the matcher in {@link files}, the regex or predicate will be applied to
48
51
  * the _full_ sub-path (starting with `dir`) in order to determine a match.
49
52
  *
50
53
  * @param dir
@@ -56,12 +59,12 @@ export const dirs = (dir, match = "", maxDepth = Infinity, logger) => __dirs(dir
56
59
  function* __dirs(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
57
60
  if (depth >= maxDepth)
58
61
  return;
59
- const re = __ensureRegEx(match);
60
- for (let f of readdirSync(dir)) {
62
+ const pred = __ensurePred(match);
63
+ for (let f of readdirSync(dir).sort()) {
61
64
  const curr = dir + sep + f;
62
65
  try {
63
66
  if (statSync(curr).isDirectory()) {
64
- if (re.test(curr))
67
+ if (pred(curr))
65
68
  yield curr;
66
69
  yield* __dirs(curr, match, logger, maxDepth, depth + 1);
67
70
  }
@@ -74,3 +77,7 @@ function* __dirs(dir, match = "", logger, maxDepth = Infinity, depth = 0) {
74
77
  }
75
78
  /** @internal */
76
79
  const __ensureRegEx = (match) => isString(match) ? new RegExp(`${match.replace(/\./g, "\\.")}$`) : match;
80
+ const __ensurePred = (match) => isFunction(match)
81
+ ? match
82
+ : ((match = __ensureRegEx(match)),
83
+ (x) => match.test(x));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/file-io",
3
- "version": "0.5.28",
3
+ "version": "1.0.2",
4
4
  "description": "Assorted file I/O utils (with logging support) for NodeJS",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -28,25 +28,24 @@
28
28
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
29
29
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
30
30
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
31
- "doc:readme": "yarn doc:stats && tools:readme",
32
- "doc:stats": "tools:module-stats",
31
+ "doc:readme": "bun ../../tools/src/module-stats.ts && bun ../../tools/src/readme.ts",
33
32
  "pub": "yarn npm publish --access public",
34
- "test": "testament test"
33
+ "test": "bun test"
35
34
  },
36
35
  "dependencies": {
37
- "@thi.ng/api": "^8.9.6",
38
- "@thi.ng/checks": "^3.4.6",
39
- "@thi.ng/hex": "^2.3.18",
40
- "@thi.ng/logger": "^1.4.22",
41
- "@thi.ng/random": "^3.6.12"
36
+ "@thi.ng/api": "^8.9.9",
37
+ "@thi.ng/checks": "^3.4.9",
38
+ "@thi.ng/hex": "^2.3.21",
39
+ "@thi.ng/logger": "^2.0.0",
40
+ "@thi.ng/random": "^3.6.15"
42
41
  },
43
42
  "devDependencies": {
44
- "@microsoft/api-extractor": "^7.38.0",
45
- "@thi.ng/testament": "^0.3.24",
43
+ "@microsoft/api-extractor": "^7.38.3",
44
+ "@thi.ng/testament": "^0.4.2",
46
45
  "rimraf": "^5.0.5",
47
46
  "tools": "^0.0.1",
48
- "typedoc": "^0.25.2",
49
- "typescript": "^5.2.2"
47
+ "typedoc": "^0.25.3",
48
+ "typescript": "^5.3.2"
50
49
  },
51
50
  "keywords": [
52
51
  "file",
@@ -116,5 +115,5 @@
116
115
  "status": "stable",
117
116
  "year": 2022
118
117
  },
119
- "gitHead": "336bd1bf95825b3c318a3ab49c54451c94aaa883\n"
118
+ "gitHead": "f6de41f4991704fdbbb2899bb430ed4f4f6efab0\n"
120
119
  }
package/write.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import type { TypedArray } from "@thi.ng/api";
2
3
  import type { ILogger } from "@thi.ng/logger";
3
4
  import { type WriteFileOptions } from "fs";