@naturalcycles/nodejs-lib 13.37.2 → 13.39.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.
@@ -16,7 +16,7 @@ function getEncryptCLIOptions() {
16
16
  pattern: {
17
17
  type: 'string',
18
18
  array: true,
19
- desc: 'Globby pattern for secrets. Can be multiple.',
19
+ desc: 'Glob pattern for secrets. Can be multiple.',
20
20
  // demandOption: true,
21
21
  default: './secret/**',
22
22
  },
package/dist/fs/kpy.js CHANGED
@@ -10,7 +10,7 @@ const index_1 = require("../index");
10
10
  async function kpy(opt) {
11
11
  const started = Date.now();
12
12
  kpyPrepare(opt);
13
- const filenames = await (0, index_1.globby)(opt.inputPatterns, {
13
+ const filenames = await (0, index_1.fastGlob)(opt.inputPatterns, {
14
14
  cwd: opt.baseDir,
15
15
  dot: opt.dotfiles,
16
16
  });
@@ -39,7 +39,7 @@ async function kpy(opt) {
39
39
  function kpySync(opt) {
40
40
  const started = Date.now();
41
41
  kpyPrepare(opt);
42
- const filenames = index_1.globby.sync(opt.inputPatterns, {
42
+ const filenames = index_1.fastGlob.sync(opt.inputPatterns, {
43
43
  cwd: opt.baseDir,
44
44
  dot: opt.dotfiles,
45
45
  });
package/dist/index.d.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import Ajv from 'ajv';
2
2
  import type { Options as FastGlobOptions } from 'fast-glob';
3
3
  import fastGlob from 'fast-glob';
4
- import type { GlobbyOptions } from 'globby';
5
- import globby from 'globby';
6
4
  import type { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FunctionSchema, ObjectSchema, ValidationErrorItem } from 'joi';
7
5
  export * from './buffer/buffer.util';
8
6
  export * from './colors/colors';
@@ -10,13 +8,11 @@ export * from './csv/csvReader';
10
8
  export * from './csv/csvWriter';
11
9
  export * from './csv/transformToCSV';
12
10
  export * from './diff/tableDiff';
13
- export * from './fs/del';
14
11
  export * from './fs/fs2';
15
12
  export * from './fs/json2env';
16
13
  export * from './fs/kpy';
17
14
  export * from './infra/process.util';
18
15
  export * from './jwt/jwt.service';
19
- export * from './log/debug';
20
16
  export * from './log/log.util';
21
17
  export * from './script/runScript';
22
18
  export * from './security/crypto.util';
@@ -76,5 +72,5 @@ export * from './validation/joi/joi.shared.schemas';
76
72
  export * from './validation/joi/joi.validation.error';
77
73
  export * from './validation/joi/joi.validation.util';
78
74
  export type { StringSchema } from './validation/joi/string.extensions';
79
- export type { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FastGlobOptions, FunctionSchema, GlobbyOptions, ObjectSchema, ValidationErrorItem, };
80
- export { Ajv, fastGlob, globby };
75
+ export type { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FastGlobOptions, FunctionSchema, ObjectSchema, ValidationErrorItem, };
76
+ export { Ajv, fastGlob };
package/dist/index.js CHANGED
@@ -1,26 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.globby = exports.fastGlob = exports.Ajv = void 0;
3
+ exports.fastGlob = exports.Ajv = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const ajv_1 = tslib_1.__importDefault(require("ajv"));
6
6
  exports.Ajv = ajv_1.default;
7
7
  const fast_glob_1 = tslib_1.__importDefault(require("fast-glob"));
8
8
  exports.fastGlob = fast_glob_1.default;
9
- const globby_1 = tslib_1.__importDefault(require("globby"));
10
- exports.globby = globby_1.default;
11
9
  tslib_1.__exportStar(require("./buffer/buffer.util"), exports);
12
10
  tslib_1.__exportStar(require("./colors/colors"), exports);
13
11
  tslib_1.__exportStar(require("./csv/csvReader"), exports);
14
12
  tslib_1.__exportStar(require("./csv/csvWriter"), exports);
15
13
  tslib_1.__exportStar(require("./csv/transformToCSV"), exports);
16
14
  tslib_1.__exportStar(require("./diff/tableDiff"), exports);
17
- tslib_1.__exportStar(require("./fs/del"), exports);
18
15
  tslib_1.__exportStar(require("./fs/fs2"), exports);
19
16
  tslib_1.__exportStar(require("./fs/json2env"), exports);
20
17
  tslib_1.__exportStar(require("./fs/kpy"), exports);
21
18
  tslib_1.__exportStar(require("./infra/process.util"), exports);
22
19
  tslib_1.__exportStar(require("./jwt/jwt.service"), exports);
23
- tslib_1.__exportStar(require("./log/debug"), exports);
24
20
  tslib_1.__exportStar(require("./log/log.util"), exports);
25
21
  tslib_1.__exportStar(require("./script/runScript"), exports);
26
22
  tslib_1.__exportStar(require("./security/crypto.util"), exports);
@@ -27,3 +27,10 @@ export declare function stringIdBase64(size?: number): string;
27
27
  * Base64url always produces strings without a padding character `=`, by design.
28
28
  */
29
29
  export declare function stringIdBase64Url(size?: number): string;
30
+ /**
31
+ * Generate cryptographically-secure string id with non-ambiguous characters only,
32
+ * e.g. missing O and 0, I and 1 and l etc.
33
+ *
34
+ * Default length is 16.
35
+ */
36
+ export declare function stringIdNonAmbiguous(size?: number): string;
@@ -4,6 +4,7 @@ exports.stringIdBase62 = void 0;
4
4
  exports.stringId = stringId;
5
5
  exports.stringIdBase64 = stringIdBase64;
6
6
  exports.stringIdBase64Url = stringIdBase64Url;
7
+ exports.stringIdNonAmbiguous = stringIdNonAmbiguous;
7
8
  const tslib_1 = require("tslib");
8
9
  const node_crypto_1 = tslib_1.__importDefault(require("node:crypto"));
9
10
  const nanoid_1 = require("./nanoid");
@@ -42,3 +43,12 @@ function stringIdBase64(size = 16) {
42
43
  function stringIdBase64Url(size = 16) {
43
44
  return node_crypto_1.default.randomBytes(size * 0.75).toString('base64url');
44
45
  }
46
+ /**
47
+ * Generate cryptographically-secure string id with non-ambiguous characters only,
48
+ * e.g. missing O and 0, I and 1 and l etc.
49
+ *
50
+ * Default length is 16.
51
+ */
52
+ function stringIdNonAmbiguous(size = 16) {
53
+ return stringId(size, nanoid_1.ALPHABET_NONAMBIGUOUS);
54
+ }
@@ -1,3 +1,4 @@
1
+ export declare const ALPHABET_NONAMBIGUOUS = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
1
2
  export declare const ALPHABET_NUMBER = "0123456789";
2
3
  export declare const ALPHABET_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
3
4
  export declare const ALPHABET_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
@@ -6,11 +6,12 @@ https://github.com/ai/nanoid/
6
6
 
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.ALPHABET_BASE64_URL = exports.ALPHABET_BASE64 = exports.ALPHABET_ALPHANUMERIC = exports.ALPHABET_ALPHANUMERIC_UPPERCASE = exports.ALPHABET_ALPHANUMERIC_LOWERCASE = exports.ALPHABET_UPPERCASE = exports.ALPHABET_LOWERCASE = exports.ALPHABET_NUMBER = void 0;
9
+ exports.ALPHABET_BASE64_URL = exports.ALPHABET_BASE64 = exports.ALPHABET_ALPHANUMERIC = exports.ALPHABET_ALPHANUMERIC_UPPERCASE = exports.ALPHABET_ALPHANUMERIC_LOWERCASE = exports.ALPHABET_UPPERCASE = exports.ALPHABET_LOWERCASE = exports.ALPHABET_NUMBER = exports.ALPHABET_NONAMBIGUOUS = void 0;
10
10
  exports.nanoIdCustomAlphabet = nanoIdCustomAlphabet;
11
11
  exports.nanoid = nanoid;
12
12
  /* eslint-disable */
13
13
  const node_crypto_1 = require("node:crypto");
14
+ exports.ALPHABET_NONAMBIGUOUS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
14
15
  exports.ALPHABET_NUMBER = '0123456789';
15
16
  exports.ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';
16
17
  exports.ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
- "version": "13.37.2",
3
+ "version": "13.39.0",
4
4
  "scripts": {
5
5
  "prepare": "husky",
6
6
  "build": "dev-lib build",
@@ -15,7 +15,6 @@
15
15
  "secrets-encrypt-debug": "tsn ./src/bin/secrets-encrypt.ts",
16
16
  "secrets-decrypt-debug": "tsn ./src/bin/secrets-decrypt.ts",
17
17
  "kpy-debug": "tsn ./src/bin/kpy.ts node_modules dist",
18
- "del-debug": "tsn ./src/bin/del.ts dist --verbose --debug",
19
18
  "json2env-debug": "tsn ./src/bin/json2env.ts ./src/test/someFile.json"
20
19
  },
21
20
  "dependencies": {
@@ -26,10 +25,8 @@
26
25
  "ajv-formats": "^3.0.1",
27
26
  "ajv-keywords": "^5.0.0",
28
27
  "chalk": "^4.0.0",
29
- "debug": "^4.1.1",
30
28
  "dotenv": "^16.0.0",
31
29
  "fast-glob": "^3.2.11",
32
- "globby": "^11.0.0",
33
30
  "joi": "^17.9.2",
34
31
  "js-yaml": "^4.1.0",
35
32
  "jsonwebtoken": "^9.0.0",
@@ -46,7 +43,6 @@
46
43
  "jest": "^29.0.0"
47
44
  },
48
45
  "bin": {
49
- "del": "dist/bin/del.js",
50
46
  "kpy": "dist/bin/kpy.js",
51
47
  "json2env": "dist/bin/json2env.js",
52
48
  "generate-build-info": "dist/bin/generate-build-info.js",
@@ -18,7 +18,7 @@ function getEncryptCLIOptions(): EncryptCLIOptions {
18
18
  pattern: {
19
19
  type: 'string',
20
20
  array: true,
21
- desc: 'Globby pattern for secrets. Can be multiple.',
21
+ desc: 'Glob pattern for secrets. Can be multiple.',
22
22
  // demandOption: true,
23
23
  default: './secret/**',
24
24
  },
package/src/fs/kpy.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path'
2
2
  import { _since, UnixTimestampMillis } from '@naturalcycles/js-lib'
3
3
  import { boldWhite, dimGrey, grey, yellow } from '../colors/colors'
4
- import { fs2, globby } from '../index'
4
+ import { fastGlob, fs2 } from '../index'
5
5
 
6
6
  /**
7
7
  * Everything defaults to `undefined`.
@@ -47,7 +47,7 @@ export async function kpy(opt: KpyOptions): Promise<void> {
47
47
 
48
48
  kpyPrepare(opt)
49
49
 
50
- const filenames = await globby(opt.inputPatterns!, {
50
+ const filenames = await fastGlob(opt.inputPatterns!, {
51
51
  cwd: opt.baseDir,
52
52
  dot: opt.dotfiles,
53
53
  })
@@ -86,7 +86,7 @@ export function kpySync(opt: KpyOptions): void {
86
86
 
87
87
  kpyPrepare(opt)
88
88
 
89
- const filenames = globby.sync(opt.inputPatterns!, {
89
+ const filenames = fastGlob.sync(opt.inputPatterns!, {
90
90
  cwd: opt.baseDir,
91
91
  dot: opt.dotfiles,
92
92
  })
package/src/index.ts CHANGED
@@ -1,8 +1,6 @@
1
1
  import Ajv from 'ajv'
2
2
  import type { Options as FastGlobOptions } from 'fast-glob'
3
3
  import fastGlob from 'fast-glob'
4
- import type { GlobbyOptions } from 'globby'
5
- import globby from 'globby'
6
4
  import type {
7
5
  AlternativesSchema,
8
6
  AnySchema,
@@ -20,13 +18,11 @@ export * from './csv/csvReader'
20
18
  export * from './csv/csvWriter'
21
19
  export * from './csv/transformToCSV'
22
20
  export * from './diff/tableDiff'
23
- export * from './fs/del'
24
21
  export * from './fs/fs2'
25
22
  export * from './fs/json2env'
26
23
  export * from './fs/kpy'
27
24
  export * from './infra/process.util'
28
25
  export * from './jwt/jwt.service'
29
- export * from './log/debug'
30
26
  export * from './log/log.util'
31
27
  export * from './script/runScript'
32
28
  export * from './security/crypto.util'
@@ -96,7 +92,6 @@ export type {
96
92
  DateSchema,
97
93
  FastGlobOptions,
98
94
  FunctionSchema,
99
- GlobbyOptions,
100
95
  ObjectSchema,
101
96
  ValidationErrorItem,
102
97
  // extended
@@ -104,4 +99,4 @@ export type {
104
99
  // StringSchema,
105
100
  }
106
101
 
107
- export { Ajv, fastGlob, globby }
102
+ export { Ajv, fastGlob }
@@ -2,6 +2,7 @@ import crypto from 'node:crypto'
2
2
  import {
3
3
  ALPHABET_ALPHANUMERIC,
4
4
  ALPHABET_ALPHANUMERIC_LOWERCASE,
5
+ ALPHABET_NONAMBIGUOUS,
5
6
  nanoIdCustomAlphabet,
6
7
  } from './nanoid'
7
8
 
@@ -43,3 +44,13 @@ export function stringIdBase64(size = 16): string {
43
44
  export function stringIdBase64Url(size = 16): string {
44
45
  return crypto.randomBytes(size * 0.75).toString('base64url')
45
46
  }
47
+
48
+ /**
49
+ * Generate cryptographically-secure string id with non-ambiguous characters only,
50
+ * e.g. missing O and 0, I and 1 and l etc.
51
+ *
52
+ * Default length is 16.
53
+ */
54
+ export function stringIdNonAmbiguous(size = 16): string {
55
+ return stringId(size, ALPHABET_NONAMBIGUOUS)
56
+ }
@@ -11,6 +11,7 @@ import { randomFillSync } from 'node:crypto'
11
11
 
12
12
  type RandomFn = (bytes: number) => Buffer
13
13
 
14
+ export const ALPHABET_NONAMBIGUOUS = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'
14
15
  export const ALPHABET_NUMBER = '0123456789'
15
16
  export const ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz'
16
17
  export const ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
package/dist/bin/del.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
package/dist/bin/del.js DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const tslib_1 = require("tslib");
5
- const yargs_1 = tslib_1.__importDefault(require("yargs"));
6
- const del_1 = require("../fs/del");
7
- const runScript_1 = require("../script/runScript");
8
- (0, runScript_1.runScript)(async () => {
9
- const { _: patterns, ...opt } = yargs_1.default.demandCommand(1).options({
10
- verbose: {
11
- type: 'boolean',
12
- },
13
- silent: {
14
- type: 'boolean',
15
- },
16
- debug: {
17
- type: 'boolean',
18
- },
19
- dry: {
20
- type: 'boolean',
21
- },
22
- concurrency: {
23
- type: 'number',
24
- },
25
- }).argv;
26
- (0, del_1.delSync)({ patterns: patterns, ...opt });
27
- });
package/dist/fs/del.d.ts DELETED
@@ -1,22 +0,0 @@
1
- export interface DelOptions {
2
- /**
3
- * Globby patterns.
4
- */
5
- patterns: string[];
6
- /**
7
- * @default 0 (infinite)
8
- */
9
- concurrency?: number;
10
- verbose?: boolean;
11
- silent?: boolean;
12
- debug?: boolean;
13
- dry?: boolean;
14
- }
15
- export type DelSingleOption = string;
16
- /**
17
- * Delete files that match input patterns.
18
- *
19
- * @experimental
20
- */
21
- export declare function del(_opt: DelOptions | DelSingleOption): Promise<void>;
22
- export declare function delSync(_opt: DelOptions | DelSingleOption): void;
package/dist/fs/del.js DELETED
@@ -1,133 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.del = del;
4
- exports.delSync = delSync;
5
- const js_lib_1 = require("@naturalcycles/js-lib");
6
- const colors_1 = require("../colors/colors");
7
- const index_1 = require("../index");
8
- const DEF_OPT = {
9
- patterns: [],
10
- concurrency: Number.POSITIVE_INFINITY,
11
- };
12
- /**
13
- * Delete files that match input patterns.
14
- *
15
- * @experimental
16
- */
17
- async function del(_opt) {
18
- const started = Date.now();
19
- // Convert DelSingleOption to DelOptions
20
- if (typeof _opt === 'string') {
21
- _opt = {
22
- patterns: [_opt],
23
- };
24
- }
25
- const opt = {
26
- ...DEF_OPT,
27
- ..._opt,
28
- concurrency: _opt.concurrency || DEF_OPT.concurrency,
29
- };
30
- const { patterns, concurrency, verbose, silent, debug, dry } = opt;
31
- if (debug) {
32
- console.log(opt);
33
- }
34
- // 1. glob only files, expand dirs, delete
35
- const filenames = await (0, index_1.globby)(patterns, {
36
- dot: true,
37
- expandDirectories: true,
38
- onlyFiles: true,
39
- });
40
- if (verbose || debug || dry) {
41
- console.log(`Will delete ${(0, colors_1.yellow)(filenames.length)} files:`, filenames);
42
- }
43
- if (dry)
44
- return;
45
- await (0, js_lib_1.pMap)(filenames, filepath => index_1.fs2.removePath(filepath), { concurrency });
46
- // 2. glob only dirs, expand, delete only empty!
47
- let dirnames = await (0, index_1.globby)(patterns, {
48
- dot: true,
49
- expandDirectories: true,
50
- onlyDirectories: true,
51
- });
52
- // Add original patterns (if any of them are dirs)
53
- dirnames = dirnames.concat(await (0, js_lib_1.pFilter)(patterns, async (pattern) => {
54
- return (await index_1.fs2.pathExistsAsync(pattern)) && (await index_1.fs2.lstatAsync(pattern)).isDirectory();
55
- }));
56
- const dirnamesSorted = dirnames.sort().reverse();
57
- // console.log({ dirnamesSorted })
58
- const deletedDirs = [];
59
- for (const dirpath of dirnamesSorted) {
60
- if (await isEmptyDir(dirpath)) {
61
- // console.log(`empty dir: ${dirpath}`)
62
- await index_1.fs2.removePathAsync(dirpath);
63
- deletedDirs.push(dirpath);
64
- }
65
- }
66
- if (verbose || debug)
67
- console.log({ deletedDirs });
68
- if (!silent) {
69
- console.log(`del deleted ${(0, colors_1.yellow)(filenames.length)} files and ${(0, colors_1.yellow)(deletedDirs.length)} dirs ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))}`);
70
- }
71
- }
72
- function delSync(_opt) {
73
- const started = Date.now();
74
- // Convert DelSingleOption to DelOptions
75
- if (typeof _opt === 'string') {
76
- _opt = {
77
- patterns: [_opt],
78
- };
79
- }
80
- const opt = {
81
- ...DEF_OPT,
82
- ..._opt,
83
- };
84
- const { patterns, verbose, silent, debug, dry } = opt;
85
- if (debug) {
86
- console.log(opt);
87
- }
88
- // 1. glob only files, expand dirs, delete
89
- const filenames = index_1.globby.sync(patterns, {
90
- dot: true,
91
- expandDirectories: true,
92
- onlyFiles: true,
93
- });
94
- if (verbose || debug || dry) {
95
- console.log(`Will delete ${(0, colors_1.yellow)(filenames.length)} files:`, filenames);
96
- }
97
- if (dry)
98
- return;
99
- filenames.forEach(filepath => index_1.fs2.removePath(filepath));
100
- // 2. glob only dirs, expand, delete only empty!
101
- let dirnames = index_1.globby.sync(patterns, {
102
- dot: true,
103
- expandDirectories: true,
104
- onlyDirectories: true,
105
- });
106
- // Add original patterns (if any of them are dirs)
107
- dirnames = dirnames.concat(patterns.filter(p => index_1.fs2.pathExists(p) && index_1.fs2.lstat(p).isDirectory()));
108
- const dirnamesSorted = dirnames.sort().reverse();
109
- // console.log({ dirnamesSorted })
110
- const deletedDirs = [];
111
- for (const dirpath of dirnamesSorted) {
112
- if (isEmptyDirSync(dirpath)) {
113
- // console.log(`empty dir: ${dirpath}`)
114
- index_1.fs2.removePath(dirpath);
115
- deletedDirs.push(dirpath);
116
- }
117
- }
118
- if (verbose || debug)
119
- console.log({ deletedDirs });
120
- if (!silent) {
121
- console.log(`del deleted ${(0, colors_1.yellow)(filenames.length)} files and ${(0, colors_1.yellow)(deletedDirs.length)} dirs ${(0, colors_1.dimGrey)((0, js_lib_1._since)(started))}`);
122
- }
123
- }
124
- // Improved algorithm:
125
- // 1. glob only files, expand dirs, delete
126
- // 2. glob only dirs, expand, delete only empty!
127
- // 3. test each original pattern, if it exists and is directory and is empty - delete
128
- async function isEmptyDir(dir) {
129
- return (await index_1.fs2.readdirAsync(dir)).length === 0;
130
- }
131
- function isEmptyDirSync(dir) {
132
- return index_1.fs2.readdir(dir).length === 0;
133
- }
@@ -1,23 +0,0 @@
1
- export interface IDebug {
2
- (namespace: string): IDebugger;
3
- coerce: (val: any) => any;
4
- disable: () => string;
5
- enable: (namespaces: string) => void;
6
- enabled: (namespaces: string) => boolean;
7
- log: (...args: any[]) => any;
8
- names: RegExp[];
9
- skips: RegExp[];
10
- formatters: DebugFormatters;
11
- }
12
- export interface DebugFormatters {
13
- [formatter: string]: (v: any) => string;
14
- }
15
- export interface IDebugger {
16
- (...args: any[]): void;
17
- color: string;
18
- enabled: boolean;
19
- log: (...args: any[]) => any;
20
- namespace: string;
21
- destroy: () => boolean;
22
- }
23
- export declare const Debug: IDebug;
package/dist/log/debug.js DELETED
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Debug = void 0;
4
- const originalDebug = require('debug');
5
- // eslint-disable-next-line @typescript-eslint/naming-convention
6
- exports.Debug = ((namespace) => {
7
- const instance = originalDebug(namespace);
8
- instance.log = console.log.bind(console); // this enables colors for objects
9
- return instance;
10
- });
11
- exports.Debug.coerce = originalDebug.coerce.bind(originalDebug);
12
- exports.Debug.disable = originalDebug.disable.bind(originalDebug);
13
- exports.Debug.enable = originalDebug.enable.bind(originalDebug);
14
- exports.Debug.enabled = originalDebug.enabled.bind(originalDebug);
15
- exports.Debug.log = originalDebug.log.bind(originalDebug);
16
- exports.Debug.names = originalDebug.names;
17
- exports.Debug.skips = originalDebug.skips;
18
- exports.Debug.formatters = originalDebug.formatters;
package/src/bin/del.ts DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import yargs from 'yargs'
4
- import { delSync } from '../fs/del'
5
- import { runScript } from '../script/runScript'
6
-
7
- runScript(async () => {
8
- const { _: patterns, ...opt } = yargs.demandCommand(1).options({
9
- verbose: {
10
- type: 'boolean',
11
- },
12
- silent: {
13
- type: 'boolean',
14
- },
15
- debug: {
16
- type: 'boolean',
17
- },
18
- dry: {
19
- type: 'boolean',
20
- },
21
- concurrency: {
22
- type: 'number',
23
- },
24
- }).argv
25
-
26
- delSync({ patterns: patterns as string[], ...opt })
27
- })
package/src/fs/del.ts DELETED
@@ -1,193 +0,0 @@
1
- import { _since, pFilter, pMap, UnixTimestampMillis } from '@naturalcycles/js-lib'
2
- import { dimGrey, yellow } from '../colors/colors'
3
- import { fs2, globby } from '../index'
4
-
5
- export interface DelOptions {
6
- /**
7
- * Globby patterns.
8
- */
9
- patterns: string[]
10
-
11
- /**
12
- * @default 0 (infinite)
13
- */
14
- concurrency?: number
15
-
16
- verbose?: boolean
17
-
18
- silent?: boolean
19
-
20
- debug?: boolean
21
-
22
- dry?: boolean
23
- }
24
-
25
- export type DelSingleOption = string
26
-
27
- const DEF_OPT: DelOptions = {
28
- patterns: [],
29
- concurrency: Number.POSITIVE_INFINITY,
30
- }
31
-
32
- /**
33
- * Delete files that match input patterns.
34
- *
35
- * @experimental
36
- */
37
- export async function del(_opt: DelOptions | DelSingleOption): Promise<void> {
38
- const started = Date.now() as UnixTimestampMillis
39
-
40
- // Convert DelSingleOption to DelOptions
41
- if (typeof _opt === 'string') {
42
- _opt = {
43
- patterns: [_opt],
44
- }
45
- }
46
-
47
- const opt = {
48
- ...DEF_OPT,
49
- ..._opt,
50
- concurrency: _opt.concurrency || DEF_OPT.concurrency,
51
- }
52
- const { patterns, concurrency, verbose, silent, debug, dry } = opt
53
-
54
- if (debug) {
55
- console.log(opt)
56
- }
57
-
58
- // 1. glob only files, expand dirs, delete
59
-
60
- const filenames = await globby(patterns, {
61
- dot: true,
62
- expandDirectories: true,
63
- onlyFiles: true,
64
- })
65
-
66
- if (verbose || debug || dry) {
67
- console.log(`Will delete ${yellow(filenames.length)} files:`, filenames)
68
- }
69
-
70
- if (dry) return
71
-
72
- await pMap(filenames, filepath => fs2.removePath(filepath), { concurrency })
73
-
74
- // 2. glob only dirs, expand, delete only empty!
75
- let dirnames = await globby(patterns, {
76
- dot: true,
77
- expandDirectories: true,
78
- onlyDirectories: true,
79
- })
80
-
81
- // Add original patterns (if any of them are dirs)
82
- dirnames = dirnames.concat(
83
- await pFilter(patterns, async pattern => {
84
- return (await fs2.pathExistsAsync(pattern)) && (await fs2.lstatAsync(pattern)).isDirectory()
85
- }),
86
- )
87
-
88
- const dirnamesSorted = dirnames.sort().reverse()
89
-
90
- // console.log({ dirnamesSorted })
91
-
92
- const deletedDirs: string[] = []
93
- for (const dirpath of dirnamesSorted) {
94
- if (await isEmptyDir(dirpath)) {
95
- // console.log(`empty dir: ${dirpath}`)
96
- await fs2.removePathAsync(dirpath)
97
- deletedDirs.push(dirpath)
98
- }
99
- }
100
-
101
- if (verbose || debug) console.log({ deletedDirs })
102
-
103
- if (!silent) {
104
- console.log(
105
- `del deleted ${yellow(filenames.length)} files and ${yellow(
106
- deletedDirs.length,
107
- )} dirs ${dimGrey(_since(started))}`,
108
- )
109
- }
110
- }
111
-
112
- export function delSync(_opt: DelOptions | DelSingleOption): void {
113
- const started = Date.now() as UnixTimestampMillis
114
-
115
- // Convert DelSingleOption to DelOptions
116
- if (typeof _opt === 'string') {
117
- _opt = {
118
- patterns: [_opt],
119
- }
120
- }
121
-
122
- const opt = {
123
- ...DEF_OPT,
124
- ..._opt,
125
- }
126
- const { patterns, verbose, silent, debug, dry } = opt
127
-
128
- if (debug) {
129
- console.log(opt)
130
- }
131
-
132
- // 1. glob only files, expand dirs, delete
133
-
134
- const filenames = globby.sync(patterns, {
135
- dot: true,
136
- expandDirectories: true,
137
- onlyFiles: true,
138
- })
139
-
140
- if (verbose || debug || dry) {
141
- console.log(`Will delete ${yellow(filenames.length)} files:`, filenames)
142
- }
143
-
144
- if (dry) return
145
-
146
- filenames.forEach(filepath => fs2.removePath(filepath))
147
-
148
- // 2. glob only dirs, expand, delete only empty!
149
- let dirnames = globby.sync(patterns, {
150
- dot: true,
151
- expandDirectories: true,
152
- onlyDirectories: true,
153
- })
154
-
155
- // Add original patterns (if any of them are dirs)
156
- dirnames = dirnames.concat(patterns.filter(p => fs2.pathExists(p) && fs2.lstat(p).isDirectory()))
157
-
158
- const dirnamesSorted = dirnames.sort().reverse()
159
-
160
- // console.log({ dirnamesSorted })
161
-
162
- const deletedDirs: string[] = []
163
- for (const dirpath of dirnamesSorted) {
164
- if (isEmptyDirSync(dirpath)) {
165
- // console.log(`empty dir: ${dirpath}`)
166
- fs2.removePath(dirpath)
167
- deletedDirs.push(dirpath)
168
- }
169
- }
170
-
171
- if (verbose || debug) console.log({ deletedDirs })
172
-
173
- if (!silent) {
174
- console.log(
175
- `del deleted ${yellow(filenames.length)} files and ${yellow(
176
- deletedDirs.length,
177
- )} dirs ${dimGrey(_since(started))}`,
178
- )
179
- }
180
- }
181
-
182
- // Improved algorithm:
183
- // 1. glob only files, expand dirs, delete
184
- // 2. glob only dirs, expand, delete only empty!
185
- // 3. test each original pattern, if it exists and is directory and is empty - delete
186
-
187
- async function isEmptyDir(dir: string): Promise<boolean> {
188
- return (await fs2.readdirAsync(dir)).length === 0
189
- }
190
-
191
- function isEmptyDirSync(dir: string): boolean {
192
- return fs2.readdir(dir).length === 0
193
- }
package/src/log/debug.ts DELETED
@@ -1,48 +0,0 @@
1
- // Types based on @types/debug
2
- export interface IDebug {
3
- (namespace: string): IDebugger
4
- coerce: (val: any) => any
5
- disable: () => string
6
- enable: (namespaces: string) => void
7
- enabled: (namespaces: string) => boolean
8
- log: (...args: any[]) => any
9
-
10
- names: RegExp[]
11
- skips: RegExp[]
12
-
13
- formatters: DebugFormatters
14
- }
15
-
16
- export interface DebugFormatters {
17
- [formatter: string]: (v: any) => string
18
- }
19
-
20
- export interface IDebugger {
21
- // (formatter: any, ...args: any[]): void;
22
- (...args: any[]): void
23
-
24
- color: string
25
- enabled: boolean
26
- log: (...args: any[]) => any
27
- namespace: string
28
- destroy: () => boolean
29
- // extend: (namespace: string, delimiter?: string) => IDebugger
30
- }
31
-
32
- const originalDebug = require('debug') as IDebug
33
-
34
- // eslint-disable-next-line @typescript-eslint/naming-convention
35
- export const Debug = ((namespace: string) => {
36
- const instance = originalDebug(namespace)
37
- instance.log = console.log.bind(console) // this enables colors for objects
38
- return instance
39
- }) as IDebug
40
-
41
- Debug.coerce = originalDebug.coerce.bind(originalDebug)
42
- Debug.disable = originalDebug.disable.bind(originalDebug)
43
- Debug.enable = originalDebug.enable.bind(originalDebug)
44
- Debug.enabled = originalDebug.enabled.bind(originalDebug)
45
- Debug.log = originalDebug.log.bind(originalDebug)
46
- Debug.names = originalDebug.names
47
- Debug.skips = originalDebug.skips
48
- Debug.formatters = originalDebug.formatters