@ix-xs/node-comfort 1.2.0 → 2.0.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/README.md +136 -549
  3. package/index.js +80 -35
  4. package/package.json +160 -33
  5. package/src/Arr.js +887 -419
  6. package/src/Async.js +585 -0
  7. package/src/Cache.js +329 -0
  8. package/src/Checker.js +971 -539
  9. package/src/Cli.js +1034 -0
  10. package/src/Color.js +415 -0
  11. package/src/Crypto.js +707 -0
  12. package/src/Emitter.js +289 -0
  13. package/src/Env.js +555 -0
  14. package/src/FS.js +1483 -894
  15. package/src/Func.js +670 -353
  16. package/src/Http.js +538 -0
  17. package/src/Id.js +384 -201
  18. package/src/Logger.js +739 -378
  19. package/src/Num.js +844 -361
  20. package/src/Obj.js +855 -372
  21. package/src/SQLite.js +1308 -1005
  22. package/src/Schema.js +1586 -0
  23. package/src/Str.js +983 -436
  24. package/src/Sys.js +511 -0
  25. package/src/Time.js +1260 -422
  26. package/src/Utils.js +321 -325
  27. package/src/errors.js +292 -0
  28. package/types/index.d.ts +693 -526
  29. package/types/src/Arr.d.ts +455 -145
  30. package/types/src/Arr.d.ts.map +1 -1
  31. package/types/src/Async.d.ts +321 -0
  32. package/types/src/Async.d.ts.map +1 -0
  33. package/types/src/Cache.d.ts +195 -0
  34. package/types/src/Cache.d.ts.map +1 -0
  35. package/types/src/Checker.d.ts +501 -235
  36. package/types/src/Checker.d.ts.map +1 -1
  37. package/types/src/Cli.d.ts +582 -0
  38. package/types/src/Cli.d.ts.map +1 -0
  39. package/types/src/Color.d.ts +294 -0
  40. package/types/src/Color.d.ts.map +1 -0
  41. package/types/src/Crypto.d.ts +534 -0
  42. package/types/src/Crypto.d.ts.map +1 -0
  43. package/types/src/Emitter.d.ts +170 -0
  44. package/types/src/Emitter.d.ts.map +1 -0
  45. package/types/src/Env.d.ts +382 -0
  46. package/types/src/Env.d.ts.map +1 -0
  47. package/types/src/FS.d.ts +686 -238
  48. package/types/src/FS.d.ts.map +1 -1
  49. package/types/src/Func.d.ts +380 -135
  50. package/types/src/Func.d.ts.map +1 -1
  51. package/types/src/Http.d.ts +374 -0
  52. package/types/src/Http.d.ts.map +1 -0
  53. package/types/src/Id.d.ts +149 -68
  54. package/types/src/Id.d.ts.map +1 -1
  55. package/types/src/Logger.d.ts +363 -46
  56. package/types/src/Logger.d.ts.map +1 -1
  57. package/types/src/Num.d.ts +473 -137
  58. package/types/src/Num.d.ts.map +1 -1
  59. package/types/src/Obj.d.ts +390 -104
  60. package/types/src/Obj.d.ts.map +1 -1
  61. package/types/src/SQLite.d.ts +646 -309
  62. package/types/src/SQLite.d.ts.map +1 -1
  63. package/types/src/Schema.d.ts +940 -0
  64. package/types/src/Schema.d.ts.map +1 -0
  65. package/types/src/Str.d.ts +569 -166
  66. package/types/src/Str.d.ts.map +1 -1
  67. package/types/src/Sys.d.ts +269 -0
  68. package/types/src/Sys.d.ts.map +1 -0
  69. package/types/src/Time.d.ts +663 -204
  70. package/types/src/Time.d.ts.map +1 -1
  71. package/types/src/Utils.d.ts +154 -102
  72. package/types/src/Utils.d.ts.map +1 -1
  73. package/types/src/errors.d.ts +292 -0
  74. package/types/src/errors.d.ts.map +1 -0
  75. package/types/index.d.ts.map +0 -1
package/types/src/FS.d.ts CHANGED
@@ -1,303 +1,751 @@
1
1
  /**
2
- * Reads an environment variable from process.env.
3
- * @param {string} value - The environment variable name.
4
- * @param {string} [envFilePath] - Reserved for future use.
5
- * @returns {string|undefined} The environment value, or undefined if not set.
2
+ * Options for `copyFoldersIn()` and `moveFoldersIn()`.
6
3
  */
7
- export function getEnv(value: string, envFilePath?: string): string | undefined;
4
+ export type CopyFoldersOptions = {
5
+ /**
6
+ * Destination folder.
7
+ */
8
+ dest: string;
9
+ /**
10
+ * Source folder. Defaults to the working directory.
11
+ */
12
+ path?: string | undefined;
13
+ /**
14
+ * Include nested folders. Defaults to `true`.
15
+ */
16
+ recursive?: boolean | undefined;
17
+ /**
18
+ * Copy the files in each folder too.
19
+ */
20
+ withFiles?: boolean | undefined;
21
+ /**
22
+ * Delete an existing destination folder first.
23
+ */
24
+ force?: boolean | undefined;
25
+ /**
26
+ * Keep a folder when it returns `true`. Gets absolute paths.
27
+ */
28
+ filter?: ((folder: string) => boolean) | undefined;
29
+ };
8
30
  /**
9
- * Resolves a path even when it does not already exist.
10
- * @param {string} [path=process.cwd()] - The path to resolve.
11
- * @returns {string} The resolved path.
31
+ * Options for `copyFolder()` and `moveFolder()`.
12
32
  */
13
- export function createPath(path?: string): string;
33
+ export type CopyFolderOptions = {
34
+ /**
35
+ * Destination folder.
36
+ */
37
+ dest: string;
38
+ /**
39
+ * Source folder. Defaults to the working directory.
40
+ */
41
+ path?: string | undefined;
42
+ /**
43
+ * Copy nested folders too.
44
+ */
45
+ recursive?: boolean | undefined;
46
+ /**
47
+ * Copy files too. `copy()` does all of this in one call.
48
+ */
49
+ withFiles?: boolean | undefined;
50
+ /**
51
+ * Delete an existing destination first.
52
+ */
53
+ force?: boolean | undefined;
54
+ };
14
55
  /**
15
- * Returns folders found inside a path.
16
- * @param {string} [path=process.cwd()] - The base path to inspect.
17
- * @param {boolean} [recursive=true] - Whether to scan recursively.
18
- * @returns {string[]|undefined} Matching folders, or undefined if the path cannot be resolved.
56
+ * Options for `copyFilesIn()` and `moveFilesIn()`.
19
57
  */
20
- export function getFoldersIn(path?: string, recursive?: boolean): string[] | undefined;
58
+ export type CopyFilesOptions = {
59
+ /**
60
+ * Destination folder.
61
+ */
62
+ dest: string;
63
+ /**
64
+ * Source folder. Defaults to the working directory.
65
+ */
66
+ path?: string | undefined;
67
+ /**
68
+ * Include files from nested folders, keeping the tree. Defaults to `true`.
69
+ */
70
+ recursive?: boolean | undefined;
71
+ /**
72
+ * Delete existing destination files first.
73
+ */
74
+ force?: boolean | undefined;
75
+ /**
76
+ * Keep a file when it returns `true`. Gets absolute paths.
77
+ */
78
+ filter?: ((file: string) => boolean) | undefined;
79
+ };
21
80
  /**
22
- * Returns the resolved folder path.
23
- * @param {string} [path=process.cwd()] - The folder path to resolve.
24
- * @returns {string|undefined} The resolved folder path, or undefined if not found.
81
+ * Options for `copyFile()` and `moveFile()`.
25
82
  */
26
- export function getFolder(path?: string): string | undefined;
83
+ export type CopyFileOptions = {
84
+ /**
85
+ * Source file.
86
+ */
87
+ path: string;
88
+ /**
89
+ * Destination file, or a folder if it ends with `/`.
90
+ */
91
+ dest: string;
92
+ /**
93
+ * Delete the destination first.
94
+ */
95
+ force?: boolean | undefined;
96
+ };
97
+ /**
98
+ * Options for `copy()`.
99
+ */
100
+ export type CopyOptions = {
101
+ /**
102
+ * Replace existing files. Defaults to `true`.
103
+ */
104
+ overwrite?: boolean | undefined;
105
+ /**
106
+ * Return `false` to skip a file or folder.
107
+ */
108
+ filter?: ((source: string, destination: string) => boolean) | undefined;
109
+ /**
110
+ * Keep modification times.
111
+ */
112
+ preserveTimestamps?: boolean | undefined;
113
+ };
114
+ /**
115
+ * Options for `writeFile()`.
116
+ */
117
+ export type WriteFileOptions = {
118
+ /**
119
+ * Write to a temporary file and rename it, so nobody reads a half-written file and a crash can't corrupt it. Defaults to `true`.
120
+ */
121
+ atomic?: boolean | undefined;
122
+ /**
123
+ * Defaults to `"utf8"`.
124
+ */
125
+ encoding?: BufferEncoding | undefined;
126
+ /**
127
+ * Permissions, like `0o600` for secrets.
128
+ */
129
+ mode?: number | undefined;
130
+ /**
131
+ * Indentation when writing an object as JSON. Defaults to `2`.
132
+ */
133
+ spaces?: number | undefined;
134
+ };
135
+ /**
136
+ * Options for `writeJSON()`.
137
+ */
138
+ export type WriteJSONOptions = {
139
+ /**
140
+ * Defaults to `2`.
141
+ */
142
+ spaces?: number | undefined;
143
+ /**
144
+ * Defaults to `true`.
145
+ */
146
+ atomic?: boolean | undefined;
147
+ /**
148
+ * Passed to `JSON.stringify`.
149
+ */
150
+ replacer?: ((key: string, value: unknown) => unknown) | undefined;
151
+ };
27
152
  /**
28
- * Returns files found inside a path.
29
- * @param {string} [path=process.cwd()] - The base path to inspect.
30
- * @param {boolean} [recursive=true] - Whether to scan recursively.
31
- * @returns {string[]|undefined} Matching files, or undefined if the path cannot be resolved.
153
+ * Options for `readJSON()`.
32
154
  */
33
- export function getFilesIn(path?: string, recursive?: boolean): string[] | undefined;
155
+ export type ReadJSONOptions = {
156
+ /**
157
+ * Allow comments and trailing commas, like in `tsconfig.json`.
158
+ */
159
+ comments?: boolean | undefined;
160
+ /**
161
+ * Passed to `JSON.parse`.
162
+ */
163
+ reviver?: ((key: string, value: any) => any) | undefined;
164
+ };
34
165
  /**
35
- * Returns the resolved file path.
36
- * @param {string} path - The file path to resolve.
37
- * @returns {string|undefined} The resolved file path, or undefined if not found.
166
+ * Options for `getFilesIn()` and `getFoldersIn()`.
167
+ */
168
+ export type ListOptions = {
169
+ /**
170
+ * Go into nested folders. Defaults to `true`.
171
+ */
172
+ recursive?: boolean | undefined;
173
+ /**
174
+ * Include names starting with a dot. Defaults to `true`.
175
+ */
176
+ hidden?: boolean | undefined;
177
+ /**
178
+ * Folder names to skip. Defaults to `["node_modules"]`.
179
+ */
180
+ ignore?: string[] | undefined;
181
+ };
182
+ /**
183
+ * Options for `glob()`.
184
+ */
185
+ export type GlobOptions = {
186
+ /**
187
+ * Where the pattern starts. Defaults to the working directory.
188
+ */
189
+ cwd?: string | undefined;
190
+ /**
191
+ * Return absolute paths.
192
+ */
193
+ absolute?: boolean | undefined;
194
+ /**
195
+ * Let `*` and `**` match names starting with a dot.
196
+ */
197
+ dot?: boolean | undefined;
198
+ /**
199
+ * Patterns to leave out. Defaults to `node_modules` and `.git`.
200
+ */
201
+ ignore?: string[] | undefined;
202
+ /**
203
+ * Defaults to `"files"`.
204
+ */
205
+ type?: "files" | "folders" | "all" | undefined;
206
+ };
207
+ /**
208
+ * Options for `find()`.
209
+ */
210
+ export type FindOptions = {
211
+ /**
212
+ * Where to start. Defaults to the working directory.
213
+ */
214
+ cwd?: string | undefined;
215
+ /**
216
+ * Defaults to `"file"`.
217
+ */
218
+ type?: "file" | "folder" | "any" | undefined;
219
+ /**
220
+ * Folder names to skip. Defaults to `node_modules` and `.git`.
221
+ */
222
+ ignore?: string[] | undefined;
223
+ };
224
+ /**
225
+ * Options for `watch()`.
226
+ */
227
+ export type WatchOptions = {
228
+ /**
229
+ * What to watch. Defaults to the working directory.
230
+ */
231
+ path?: string | undefined;
232
+ /**
233
+ * Watch nested folders too.
234
+ */
235
+ recursive?: boolean | undefined;
236
+ /**
237
+ * Return `false` to ignore an event.
238
+ */
239
+ filter?: ((event: "rename" | "change", file: string) => boolean) | undefined;
240
+ /**
241
+ * Merge events on the same file within this many ms. Editors often save in several steps.
242
+ */
243
+ debounce?: number | undefined;
244
+ };
245
+ /**
246
+ * Returned by `watch()`.
247
+ */
248
+ export type Watcher = {
249
+ /**
250
+ * Listens for changes. `"all"` also gets the event name.
251
+ */
252
+ on: <E extends "change" | "rename" | "all">(event: E, callback: E extends "all" ? (event: "change" | "rename", file: string) => void : (file: string) => void) => Watcher;
253
+ /**
254
+ * Stops watching.
255
+ */
256
+ stop: () => void;
257
+ /**
258
+ * Ignores events until `resume()`.
259
+ */
260
+ pause: () => Watcher;
261
+ resume: () => Watcher;
262
+ };
263
+ /**
264
+ * Reads an environment variable. For typed and checked values, see `nc.env`.
265
+ *
266
+ * @example
267
+ * nc.getEnv("REGION", "eu-west-1");
268
+ *
269
+ * @param {string} name
270
+ * @param {string} [fallback]
271
+ * @returns {string | undefined}
272
+ */
273
+ export function getEnv(name: string, fallback?: string): string | undefined;
274
+ /**
275
+ * The absolute version of a path, whether it exists or not.
276
+ *
277
+ * @example
278
+ * nc.createPath("./config/app.json"); // next to the calling file
279
+ * nc.createPath("logs/app.log"); // from the working directory
280
+ *
281
+ * @param {string} [path] Defaults to the working directory.
282
+ * @returns {string}
283
+ */
284
+ export function createPath(path?: string): string;
285
+ /**
286
+ * The absolute path of a folder, or `undefined` if it doesn't exist.
287
+ *
288
+ * @example
289
+ * if (!nc.getFolder("./uploads")) nc.createFolder("./uploads");
290
+ *
291
+ * @param {string} [path] Defaults to the working directory.
292
+ * @returns {string | undefined}
293
+ */
294
+ export function getFolder(path?: string): string | undefined;
295
+ /**
296
+ * The absolute path of a file, or `undefined` if it doesn't exist.
297
+ *
298
+ * @param {string} path
299
+ * @returns {string | undefined}
38
300
  */
39
301
  export function getFile(path: string): string | undefined;
40
302
  /**
41
- * Creates a folder.
42
- * @param {string} path - The folder path to create.
43
- * @param {boolean} [force=false] - Whether to recreate the folder if it already exists.
44
- * @returns {boolean|undefined} True on success, false on failure, undefined if no path was provided.
303
+ * The folders inside a folder, nested ones included by default.
304
+ * `node_modules` is skipped.
305
+ *
306
+ * @example
307
+ * nc.getFoldersIn("./src"); // everything
308
+ * nc.getFoldersIn("./src", false); // direct children only
309
+ *
310
+ * @param {string} [path] Defaults to the working directory.
311
+ * @param {boolean | ListOptions} [recursive=true]
312
+ * @returns {string[] | undefined} Absolute paths, or `undefined` if the folder doesn't exist.
313
+ */
314
+ export function getFoldersIn(path?: string, recursive?: boolean | ListOptions): string[] | undefined;
315
+ /**
316
+ * The files inside a folder, nested ones included by default.
317
+ * `node_modules` is skipped.
318
+ *
319
+ * @example
320
+ * nc.getFilesIn("./src").filter((file) => file.endsWith(".js"));
321
+ *
322
+ * @param {string} [path] Defaults to the working directory.
323
+ * @param {boolean | ListOptions} [recursive=true]
324
+ * @returns {string[] | undefined} Absolute paths, or `undefined` if the folder doesn't exist.
325
+ */
326
+ export function getFilesIn(path?: string, recursive?: boolean | ListOptions): string[] | undefined;
327
+ /**
328
+ * Finds paths matching a glob pattern: `*` (anything but `/`), `**` (any
329
+ * depth), `?`, `[abc]` and `{js,ts}`.
330
+ *
331
+ * A pattern starting from the root of the disk searches there, and its
332
+ * results are absolute.
333
+ *
334
+ * @example
335
+ * nc.glob("src/**\/*.js"); // ["src/index.js", "src/lib/a.js"]
336
+ * nc.glob("**\/*.{png,jpg}", { cwd: "./assets", absolute: true });
337
+ * nc.glob("packages/*", { type: "folders" });
338
+ * nc.glob(`${folder}/**\/*.json`); // absolute pattern, absolute results
339
+ *
340
+ * @param {string | string[]} pattern One or more patterns.
341
+ * @param {GlobOptions} [options]
342
+ * @returns {string[]} Sorted, relative to `cwd` with `/` separators, unless the pattern is absolute or `absolute` is set.
343
+ */
344
+ export function glob(pattern: string | string[], options?: GlobOptions): string[];
345
+ /**
346
+ * Searches a folder tree for the first file or folder with this name,
347
+ * closest first.
348
+ *
349
+ * @example
350
+ * nc.find("config.json");
351
+ * nc.find("fixtures", { type: "folder", cwd: "./test" });
352
+ *
353
+ * @param {string} name
354
+ * @param {FindOptions} [options]
355
+ * @returns {string | undefined} The absolute path.
356
+ */
357
+ export function find(name: string, options?: FindOptions): string | undefined;
358
+ /**
359
+ * Reads a file as text, or as a Buffer with `"buffer"`.
360
+ *
361
+ * @example
362
+ * const text = nc.readFile("./README.md");
363
+ * const bytes = nc.readFile("./logo.png", "buffer");
364
+ *
365
+ * @overload
366
+ * @param {string} path
367
+ * @param {"buffer"} encoding
368
+ * @returns {Buffer | undefined} `undefined` if it can't be read.
369
+ */
370
+ export function readFile(path: string, encoding: "buffer"): Buffer | undefined;
371
+ /**
372
+ * Reads a file as text.
373
+ *
374
+ * @overload
375
+ * @param {string} path
376
+ * @param {BufferEncoding} [encoding="utf8"]
377
+ * @returns {string | undefined} `undefined` if it can't be read.
378
+ */
379
+ export function readFile(path: string, encoding?: BufferEncoding | undefined): string | undefined;
380
+ /**
381
+ * Reads a text file as lines. A final newline doesn't add an empty line.
382
+ *
383
+ * @example
384
+ * for (const url of nc.readLines("./urls.txt") ?? []) await check(url);
385
+ *
386
+ * @param {string} path
387
+ * @returns {string[] | undefined} `undefined` if it can't be read.
388
+ */
389
+ export function readLines(path: string): string[] | undefined;
390
+ /**
391
+ * Reads a JSON file. If it's missing or invalid you get `fallback`, never
392
+ * an error.
393
+ *
394
+ * @example
395
+ * const settings = nc.readJSON("./settings.json", { theme: "light" });
396
+ * const tsconfig = nc.readJSON("./tsconfig.json", {}, { comments: true });
397
+ *
398
+ * @template [T=any]
399
+ * @param {string} path
400
+ * @param {T} [fallback]
401
+ * @param {ReadJSONOptions} [options]
402
+ * @returns {T}
403
+ */
404
+ export function readJSON<T = any>(path: string, fallback?: T, options?: ReadJSONOptions): T;
405
+ /**
406
+ * Writes a file atomically, creating its folders. Objects are written as
407
+ * JSON.
408
+ *
409
+ * @example
410
+ * nc.writeFile("./dist/index.html", html);
411
+ * nc.writeFile("./.secrets/token", token, { mode: 0o600 });
412
+ *
413
+ * @param {string} path
414
+ * @param {string | Buffer | Uint8Array | object} data
415
+ * @param {WriteFileOptions} [options]
416
+ * @returns {boolean} `false` if it failed.
417
+ */
418
+ export function writeFile(path: string, data: string | Buffer | Uint8Array | object, options?: WriteFileOptions): boolean;
419
+ /**
420
+ * Writes a value as JSON, atomically, creating folders.
421
+ *
422
+ * @example
423
+ * nc.writeJSON("./data/users.json", users);
424
+ *
425
+ * @param {string} path
426
+ * @param {unknown} data
427
+ * @param {WriteJSONOptions} [options]
428
+ * @returns {boolean} `false` if it failed, for example on a circular structure.
429
+ */
430
+ export function writeJSON(path: string, data: unknown, options?: WriteJSONOptions): boolean;
431
+ /**
432
+ * Appends to a file, creating it and its folders if needed.
433
+ *
434
+ * @example
435
+ * nc.appendFile("./logs/audit.log", `${new Date().toISOString()} login ${user}\n`);
436
+ *
437
+ * @param {string} path
438
+ * @param {string | Buffer} data
439
+ * @returns {boolean}
440
+ */
441
+ export function appendFile(path: string, data: string | Buffer): boolean;
442
+ /**
443
+ * Creates a file and its folders.
444
+ *
445
+ * @example
446
+ * nc.createFile("./notes.txt", false, "hello"); // only if it doesn't exist
447
+ * nc.createFile("./data.json", true, { ok: true }); // replace it
448
+ *
449
+ * @param {string} path
450
+ * @param {boolean} [force=false] Replace the file if it exists.
451
+ * @param {string | Buffer | object | null} [data] Objects are written as JSON.
452
+ * @returns {boolean | undefined} `false` if it already existed or failed.
453
+ */
454
+ export function createFile(path: string, force?: boolean, data?: string | Buffer | object | null): boolean | undefined;
455
+ /**
456
+ * Creates a folder and its parents.
457
+ *
458
+ * @example
459
+ * nc.createFolder("./uploads");
460
+ * nc.createFolder("./cache", true); // start from an empty folder
461
+ *
462
+ * @param {string} path
463
+ * @param {boolean} [force=false] Delete and recreate it if it exists.
464
+ * @returns {boolean | undefined} `false` if it already existed or failed.
45
465
  */
46
466
  export function createFolder(path: string, force?: boolean): boolean | undefined;
47
467
  /**
48
- * Creates a file.
49
- * @param {string} path - The file path to create.
50
- * @param {boolean} [force=false] - Whether to recreate the file if it already exists.
51
- * @param {string|object|null|undefined} [data] - File content to write.
52
- * @returns {boolean|undefined} True on success, false on failure, undefined if no path was provided.
468
+ * Makes sure a folder exists and returns its absolute path.
469
+ *
470
+ * @example
471
+ * const dir = nc.ensureFolder("./storage/uploads");
472
+ *
473
+ * @param {string} path
474
+ * @returns {string}
475
+ * @throws {Error} If it can't be created.
53
476
  */
54
- export function createFile(path: string, force?: boolean, data?: string | object | null | undefined): boolean | undefined;
477
+ export function ensureFolder(path: string): string;
55
478
  /**
56
- * Deletes folders found inside a path.
57
- * @param {string} [path=process.cwd()] - The base path to inspect.
58
- * @param {(folder: string) => boolean} [filter=() => true] - Filter applied to each folder path.
59
- * @returns {number|undefined} Number of deleted folders, or undefined if the path cannot be resolved.
479
+ * Makes sure a file exists (an empty one if needed) and returns its
480
+ * absolute path. An existing file is left as is.
481
+ *
482
+ * @param {string} path
483
+ * @returns {string}
484
+ * @throws {Error} If it can't be created.
60
485
  */
61
- export function deleteFoldersIn(path?: string, filter?: (folder: string) => boolean): number | undefined;
486
+ export function ensureFile(path: string): string;
62
487
  /**
63
- * Deletes a folder.
64
- * @param {string} path - The folder path to delete.
65
- * @returns {boolean|undefined} True on success, false on failure, undefined if the path is invalid.
488
+ * Updates a file's modification time, creating the file if needed, like
489
+ * the Unix `touch` command.
490
+ *
491
+ * @param {string} path
492
+ * @returns {boolean}
66
493
  */
67
- export function deleteFolder(path: string): boolean | undefined;
494
+ export function touch(path: string): boolean;
68
495
  /**
69
- * Deletes files found inside a path.
70
- * @param {string} [path=process.cwd()] - The base path to inspect.
71
- * @param {boolean} [recursive=false] - Whether to scan recursively.
72
- * @param {(file: string) => boolean} [filter=() => true] - Filter applied to each file path.
73
- * @returns {number|undefined} Number of deleted files, or undefined if the path cannot be resolved.
496
+ * Deletes a folder and everything in it.
497
+ *
498
+ * @param {string} path
499
+ * @returns {boolean | undefined} `undefined` if it doesn't exist.
74
500
  */
75
- export function deleteFilesIn(path?: string, recursive?: boolean, filter?: (file: string) => boolean): number | undefined;
501
+ export function deleteFolder(path: string): boolean | undefined;
76
502
  /**
77
503
  * Deletes a file.
78
- * @param {string} path - The file path to delete.
79
- * @returns {boolean|undefined} True on success, false on failure, undefined if the path is invalid.
504
+ *
505
+ * @param {string} path
506
+ * @returns {boolean | undefined} `undefined` if it doesn't exist.
80
507
  */
81
508
  export function deleteFile(path: string): boolean | undefined;
82
509
  /**
83
- * Copies folders from a source path into a destination folder.
84
- * @param {Object} options - Copy options.
85
- * @param {string} options.dest - Destination path.
86
- * @param {string} [options.path] - Source path.
87
- * @param {boolean} [options.recursive=true] - Whether to recurse into subfolders.
88
- * @param {boolean} [options.withFiles=false] - Whether to copy files as well.
89
- * @param {boolean} [options.force=false] - Whether to overwrite existing folders.
90
- * @param {(folder: string) => boolean} [options.filter=() => true] - Filter applied to each folder.
91
- * @returns {number|undefined} Number of copied folders, or undefined if invalid input.
92
- */
93
- export function copyFoldersIn(options: {
94
- dest: string;
95
- path?: string | undefined;
96
- recursive?: boolean | undefined;
97
- withFiles?: boolean | undefined;
98
- force?: boolean | undefined;
99
- filter?: ((folder: string) => boolean) | undefined;
100
- }): number | undefined;
101
- /**
102
- * Copies a folder to a destination path.
103
- * @param {Object} options - Copy options.
104
- * @param {string} options.dest - Destination path.
105
- * @param {string} [options.path] - Source path.
106
- * @param {boolean} [options.recursive=false] - Whether to copy subfolders.
107
- * @param {boolean} [options.withFiles=false] - Whether to copy files.
108
- * @param {boolean} [options.force=false] - Whether to overwrite the destination.
109
- * @returns {boolean|undefined} True on success, false on failure, undefined if invalid input.
110
- */
111
- export function copyFolder(options: {
112
- dest: string;
113
- path?: string | undefined;
114
- recursive?: boolean | undefined;
115
- withFiles?: boolean | undefined;
116
- force?: boolean | undefined;
117
- }): boolean | undefined;
510
+ * Deletes a file or a folder, whichever it is. Nothing happens if the path
511
+ * doesn't exist.
512
+ *
513
+ * @example
514
+ * nc.remove("./dist");
515
+ *
516
+ * @param {string} path
517
+ * @returns {boolean} `true` if something was deleted.
518
+ */
519
+ export function remove(path: string): boolean;
118
520
  /**
119
- * Copies files from a source path into a destination folder.
120
- * @param {Object} options - Copy options.
121
- * @param {string} options.dest - Destination path.
122
- * @param {string} [options.path] - Source path.
123
- * @param {boolean} [options.recursive=true] - Whether to recurse into subfolders.
124
- * @param {boolean} [options.force=false] - Whether to overwrite existing files.
125
- * @param {(file: string) => boolean} [options.filter=() => true] - Filter applied to each file.
126
- * @returns {number|undefined} Number of copied files, or undefined if invalid input.
521
+ * Deletes the folders inside a folder that pass a test.
522
+ *
523
+ * @example
524
+ * nc.deleteFoldersIn("./packages", (folder) => folder.endsWith("dist"));
525
+ *
526
+ * @param {string} [path] Defaults to the working directory.
527
+ * @param {(folder: string) => boolean} [filter] Gets absolute paths. Defaults to every folder.
528
+ * @returns {number | undefined} How many were deleted.
127
529
  */
128
- export function copyFilesIn(options: {
129
- dest: string;
130
- path?: string | undefined;
131
- recursive?: boolean | undefined;
132
- force?: boolean | undefined;
133
- filter?: ((file: string) => boolean) | undefined;
134
- }): number | undefined;
530
+ export function deleteFoldersIn(path?: string, filter?: (folder: string) => boolean): number | undefined;
135
531
  /**
136
- * Copies a file to a destination path.
137
- * @param {Object} options - Copy options.
138
- * @param {string} options.path - Source file path.
139
- * @param {string} options.dest - Destination path.
140
- * @param {boolean} [options.force=false] - Whether to overwrite the destination file.
141
- * @returns {boolean|undefined} True on success, false on failure, undefined if invalid input.
532
+ * Deletes the files inside a folder that pass a test.
533
+ *
534
+ * @example
535
+ * nc.deleteFilesIn("./logs", false, (file) => file.endsWith(".log"));
536
+ *
537
+ * @param {string} [path] Defaults to the working directory.
538
+ * @param {boolean} [recursive=false]
539
+ * @param {(file: string) => boolean} [filter] Gets absolute paths. Defaults to every file.
540
+ * @returns {number | undefined} How many were deleted.
142
541
  */
143
- export function copyFile(options: {
144
- path: string;
145
- dest: string;
146
- force?: boolean | undefined;
147
- }): boolean | undefined;
542
+ export function deleteFilesIn(path?: string, recursive?: boolean, filter?: (file: string) => boolean): number | undefined;
148
543
  /**
149
- * Moves folders from a source path into a destination folder.
150
- * @param {Object} options - Move options.
151
- * @param {string} options.dest - Destination path.
152
- * @param {string} [options.path] - Source path.
153
- * @param {boolean} [options.recursive=true] - Whether to recurse into subfolders.
154
- * @param {boolean} [options.withFiles=false] - Whether to move files as well.
155
- * @param {boolean} [options.force=false] - Whether to overwrite existing folders.
156
- * @param {(folder: string) => boolean} [options.filter=() => true] - Filter applied to each folder.
157
- * @returns {number|undefined} Number of copied folders, or undefined if invalid input.
158
- */
159
- export function moveFoldersIn(options: {
160
- dest: string;
161
- path?: string | undefined;
162
- recursive?: boolean | undefined;
163
- withFiles?: boolean | undefined;
164
- force?: boolean | undefined;
165
- filter?: ((folder: string) => boolean) | undefined;
166
- }): number | undefined;
167
- /**
168
- * Moves a folder to a destination path.
169
- * @param {Object} options - Move options.
170
- * @param {string} options.path - Source folder path.
171
- * @param {string} options.dest - Destination path.
172
- * @param {boolean} [options.recursive=false] - Whether to move subfolders.
173
- * @param {boolean} [options.withFiles=false] - Whether to move files.
174
- * @param {boolean} [options.force=false] - Whether to overwrite the destination.
175
- * @returns {boolean|undefined} True on success, false on failure, undefined if invalid input.
176
- */
177
- export function moveFolder(options: {
178
- path: string;
179
- dest: string;
180
- recursive?: boolean | undefined;
181
- withFiles?: boolean | undefined;
182
- force?: boolean | undefined;
183
- }): boolean | undefined;
544
+ * Deletes everything inside a folder, keeping the folder.
545
+ *
546
+ * @param {string} path
547
+ * @returns {boolean | undefined} `undefined` if it doesn't exist.
548
+ */
549
+ export function emptyFolder(path: string): boolean | undefined;
184
550
  /**
185
- * Moves files from a source path into a destination folder.
186
- * @param {Object} options - Move options.
187
- * @param {string} options.dest - Destination path.
188
- * @param {string} [options.path] - Source path.
189
- * @param {boolean} [options.recursive=true] - Whether to recurse into subfolders.
190
- * @param {boolean} [options.force=false] - Whether to overwrite existing files.
191
- * @param {(file: string) => boolean} [options.filter=() => true] - Filter applied to each file.
192
- * @returns {number|undefined} Number of copied files, or undefined if invalid input.
551
+ * Copies a file or a whole folder, like `cp -r`.
552
+ *
553
+ * @example
554
+ * nc.copy("./templates", "./dist/templates");
555
+ * nc.copy("./.env.example", "./.env", { overwrite: false });
556
+ *
557
+ * @param {string} source
558
+ * @param {string} destination
559
+ * @param {CopyOptions} [options]
560
+ * @returns {boolean} `false` if the source is missing or the copy failed.
193
561
  */
194
- export function moveFilesIn(options: {
195
- dest: string;
196
- path?: string | undefined;
197
- recursive?: boolean | undefined;
198
- force?: boolean | undefined;
199
- filter?: ((file: string) => boolean) | undefined;
200
- }): number | undefined;
562
+ export function copy(source: string, destination: string, options?: CopyOptions): boolean;
201
563
  /**
202
- * Moves a file to a destination path.
203
- * @param {Object} options - Move options.
204
- * @param {string} options.path - Source file path.
205
- * @param {string} options.dest - Destination path.
206
- * @param {boolean} [options.force=false] - Whether to overwrite the destination file.
207
- * @returns {boolean|undefined} True on success, false on failure, undefined if invalid input.
564
+ * Moves or renames a file or folder, across drives too.
565
+ *
566
+ * @example
567
+ * nc.move("./report.pdf", "./archive/2024/report.pdf");
568
+ *
569
+ * @param {string} source
570
+ * @param {string} destination
571
+ * @param {{ overwrite?: boolean }} [options] Replace an existing destination. Defaults to `true`.
572
+ * @returns {boolean}
208
573
  */
209
- export function moveFile(options: {
574
+ export function move(source: string, destination: string, options?: {
575
+ overwrite?: boolean;
576
+ }): boolean;
577
+ /**
578
+ * Copies the folders inside a folder into another one. `copy()` is simpler
579
+ * for most cases.
580
+ *
581
+ * @param {CopyFoldersOptions} options
582
+ * @returns {number | undefined} How many were copied.
583
+ */
584
+ export function copyFoldersIn(options: CopyFoldersOptions): number | undefined;
585
+ /**
586
+ * Copies a folder. Without `recursive` or `withFiles`, only the empty
587
+ * folder is created; `copy()` copies everything in one call.
588
+ *
589
+ * @param {CopyFolderOptions} options
590
+ * @returns {boolean | undefined}
591
+ */
592
+ export function copyFolder(options: CopyFolderOptions): boolean | undefined;
593
+ /**
594
+ * Copies the files inside a folder into another one, keeping the tree.
595
+ *
596
+ * @example
597
+ * nc.copyFilesIn({ path: "./src", dest: "./dist", filter: (file) => file.endsWith(".css") });
598
+ *
599
+ * @param {CopyFilesOptions} options
600
+ * @returns {number | undefined} How many were copied.
601
+ */
602
+ export function copyFilesIn(options: CopyFilesOptions): number | undefined;
603
+ /**
604
+ * Copies one file. If `dest` ends with `/`, the file keeps its name inside
605
+ * that folder.
606
+ *
607
+ * @example
608
+ * nc.copyFile({ path: "./src/index.js", dest: "./dist/" });
609
+ *
610
+ * @param {CopyFileOptions} options
611
+ * @returns {boolean | undefined}
612
+ */
613
+ export function copyFile(options: CopyFileOptions): boolean | undefined;
614
+ /**
615
+ * Moves the folders inside a folder.
616
+ *
617
+ * @param {CopyFoldersOptions} options
618
+ * @returns {number | undefined} How many were moved.
619
+ */
620
+ export function moveFoldersIn(options: CopyFoldersOptions): number | undefined;
621
+ /**
622
+ * Moves a folder.
623
+ *
624
+ * @param {CopyFolderOptions & { path: string }} options
625
+ * @returns {boolean | undefined}
626
+ */
627
+ export function moveFolder(options: CopyFolderOptions & {
210
628
  path: string;
211
- dest: string;
212
- force?: boolean | undefined;
213
629
  }): boolean | undefined;
214
630
  /**
215
- * Reads a file as UTF-8 text.
216
- * @param {string} path - The file path to read.
217
- * @returns {string|undefined} File content, or undefined if the file cannot be read.
631
+ * Moves the files inside a folder.
632
+ *
633
+ * @param {CopyFilesOptions} options
634
+ * @returns {number | undefined} How many were moved.
218
635
  */
219
- export function readFile(path: string): string | undefined;
636
+ export function moveFilesIn(options: CopyFilesOptions): number | undefined;
220
637
  /**
221
- * Reads and parses a JSON file.
222
- * @template T
223
- * @param {string} path - The JSON file path.
224
- * @param {T} [fallback] - Value returned when the file is missing or invalid.
225
- * @returns {T|any|undefined} The parsed value, or the fallback.
638
+ * Moves one file.
639
+ *
640
+ * @example
641
+ * nc.moveFile({ path: "./logs/app.log", dest: "./logs/archive/" });
642
+ *
643
+ * @param {CopyFileOptions} options
644
+ * @returns {boolean | undefined}
226
645
  */
227
- export function readJSON<T>(path: string, fallback?: T): T | any | undefined;
646
+ export function moveFile(options: CopyFileOptions): boolean | undefined;
228
647
  /**
229
- * Serializes a value to JSON and writes it to a file (creating folders as needed).
230
- * @param {string} path - The destination file path.
231
- * @param {*} data - The value to serialize.
232
- * @param {{ spaces?: number, force?: boolean }} [options] - Formatting options (`spaces` default 2).
233
- * @returns {boolean} True on success, false on failure.
648
+ * Does a file or folder exist at this path?
649
+ *
650
+ * @param {string} path
651
+ * @returns {boolean}
234
652
  */
235
- export function writeJSON(path: string, data: any, options?: {
236
- spaces?: number;
237
- force?: boolean;
238
- }): boolean;
653
+ export function exists(path: string): boolean;
239
654
  /**
240
- * Appends text to a file, creating it (and its folders) if necessary.
241
- * @param {string} path - The file path.
242
- * @param {string} data - The text to append.
243
- * @returns {boolean} True on success, false on failure.
655
+ * Is it an existing file?
656
+ *
657
+ * @param {string} path
658
+ * @returns {boolean}
244
659
  */
245
- export function appendFile(path: string, data: string): boolean;
660
+ export function isFile(path: string): boolean;
246
661
  /**
247
- * Checks whether a path (file or folder) exists.
248
- * @param {string} path - The path to check.
249
- * @returns {boolean} True if the path exists.
662
+ * Is it an existing folder?
663
+ *
664
+ * @param {string} path
665
+ * @returns {boolean}
250
666
  */
251
- export function exists(path: string): boolean;
667
+ export function isFolder(path: string): boolean;
252
668
  /**
253
- * Returns filesystem stats for a path, or undefined if it does not exist.
254
- * @param {string} path - The path to stat.
255
- * @returns {import("node:fs").Stats|undefined} The stats object, or undefined.
669
+ * Size, dates and type of a path.
670
+ *
671
+ * @example
672
+ * nc.stat("./video.mp4")?.mtime;
673
+ *
674
+ * @param {string} path
675
+ * @returns {fs.Stats | undefined} `undefined` if it doesn't exist.
256
676
  */
257
- export function stat(path: string): any | undefined;
677
+ export function stat(path: string): fs.Stats | undefined;
258
678
  /**
259
- * Returns the size of a file in bytes.
260
- * @param {string} path - The file path.
261
- * @returns {number|undefined} Size in bytes, or undefined if not found.
679
+ * A file's size in bytes.
680
+ *
681
+ * @example
682
+ * nc.num.formatBytes(nc.fileSize("./backup.zip") ?? 0); // "1.2 GB"
683
+ *
684
+ * @param {string} path
685
+ * @returns {number | undefined} `undefined` if it doesn't exist.
262
686
  */
263
687
  export function fileSize(path: string): number | undefined;
264
688
  /**
265
- * Computes a hash digest of a file's contents.
266
- * @param {string} path - The file path.
267
- * @param {{ algorithm?: string, encoding?: "hex"|"base64"|"base64url" }} [options] - Hash options.
268
- * @returns {string|undefined} The digest, or undefined if the file cannot be read.
689
+ * The total size of every file in a folder.
690
+ *
691
+ * @param {string} path
692
+ * @returns {number | undefined} `undefined` if it doesn't exist.
693
+ */
694
+ export function folderSize(path: string): number | undefined;
695
+ /**
696
+ * Hashes a file in chunks, so huge files are fine.
697
+ *
698
+ * @example
699
+ * nc.hashFile("./release.zip"); // sha256, hex
700
+ * nc.hashFile("./release.zip", { algorithm: "md5" });
701
+ *
702
+ * @param {string} path
703
+ * @param {{ algorithm?: string, encoding?: "hex" | "base64" | "base64url" }} [options] Defaults to sha256 in hex.
704
+ * @returns {string | undefined} `undefined` if it can't be read.
269
705
  */
270
706
  export function hashFile(path: string, options?: {
271
707
  algorithm?: string;
272
708
  encoding?: "hex" | "base64" | "base64url";
273
709
  }): string | undefined;
274
710
  /**
275
- * Empties a folder's contents while keeping the folder itself.
276
- * @param {string} path - The folder to empty.
277
- * @returns {boolean|undefined} True on success, false on failure, undefined if not found.
711
+ * Creates a new, unique folder in the system's temp directory.
712
+ *
713
+ * @example
714
+ * const dir = nc.tempFolder("export-");
715
+ * try { await exportTo(dir); } finally { nc.remove(dir); }
716
+ *
717
+ * @param {string} [prefix="nc-"]
718
+ * @returns {string}
278
719
  */
279
- export function emptyFolder(path: string): boolean | undefined;
720
+ export function tempFolder(prefix?: string): string;
280
721
  /**
281
- * Watches a path and exposes event listeners.
282
- * @param {Object} [options] - Watch options.
283
- * @param {string} [options.path=process.cwd()] - Path to watch.
284
- * @param {boolean} [options.recursive=false] - Whether to watch recursively.
285
- * @param {(event: "rename"|"change", file: string) => boolean} [options.filter] - Filter applied before dispatch.
286
- * @returns {{
287
- * on: <E extends "change"|"rename"|"all">(event: E, callback: E extends "all" ? (event: "change"|"rename", file: string) => void|Promise<void> : (file: string) => void|Promise<void>) => any,
288
- * stop: () => void,
289
- * pause: () => any,
290
- * resume: () => any,
291
- * }|undefined} Watch controller, or undefined if the path cannot be resolved.
292
- */
293
- export function watch(options?: {
294
- path?: string | undefined;
295
- recursive?: boolean | undefined;
296
- filter?: ((event: "rename" | "change", file: string) => boolean) | undefined;
297
- }): {
298
- on: <E extends "change" | "rename" | "all">(event: E, callback: E extends "all" ? (event: "change" | "rename", file: string) => void | Promise<void> : (file: string) => void | Promise<void>) => any;
299
- stop: () => void;
300
- pause: () => any;
301
- resume: () => any;
302
- } | undefined;
722
+ * Turns any text into a file name that works on Windows, macOS and Linux:
723
+ * forbidden characters are replaced, reserved names like `CON` are
724
+ * prefixed, and the length is capped.
725
+ *
726
+ * @example
727
+ * nc.sanitizeFilename('Report: Q1/Q2 "final"?.pdf'); // "Report_ Q1_Q2 _final__.pdf"
728
+ * nc.sanitizeFilename("CON.txt"); // "_CON.txt"
729
+ *
730
+ * @param {string} name
731
+ * @param {{ replacement?: string }} [options] Defaults to `"_"`.
732
+ * @returns {string}
733
+ */
734
+ export function sanitizeFilename(name: string, options?: {
735
+ replacement?: string;
736
+ }): string;
737
+ /**
738
+ * Watches a file or folder for changes.
739
+ *
740
+ * @example
741
+ * const watcher = nc.watch({ path: "./src", recursive: true, debounce: 100 })
742
+ * .on("change", (file) => nc.info(`Changed: ${file}`))
743
+ * .on("rename", (file) => nc.info(`Added or removed: ${file}`));
744
+ * watcher.stop();
745
+ *
746
+ * @param {WatchOptions} [options]
747
+ * @returns {Watcher | undefined} `undefined` if the path doesn't exist.
748
+ */
749
+ export function watch(options?: WatchOptions): Watcher | undefined;
750
+ import fs = require("node:fs");
303
751
  //# sourceMappingURL=FS.d.ts.map