@shuvi/utils 0.0.1-rc.33
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/lib/chalk.d.ts +2 -0
- package/lib/chalk.js +7 -0
- package/lib/deepmerge.d.ts +1 -0
- package/lib/deepmerge.js +26 -0
- package/lib/defer.d.ts +6 -0
- package/lib/defer.js +14 -0
- package/lib/detectTypescript.d.ts +7 -0
- package/lib/detectTypescript.js +26 -0
- package/lib/escapeRegExp.d.ts +1 -0
- package/lib/escapeRegExp.js +6 -0
- package/lib/eventEmitter.d.ts +8 -0
- package/lib/eventEmitter.js +24 -0
- package/lib/fileWatcher.d.ts +13 -0
- package/lib/fileWatcher.js +41 -0
- package/lib/htmlescape.d.ts +2 -0
- package/lib/htmlescape.js +28 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.js +26 -0
- package/lib/invariant.d.ts +2 -0
- package/lib/invariant.js +7 -0
- package/lib/logger.d.ts +7 -0
- package/lib/logger.js +27 -0
- package/lib/noop.d.ts +1 -0
- package/lib/noop.js +2 -0
- package/lib/noopFn.d.ts +2 -0
- package/lib/noopFn.js +3 -0
- package/lib/nullish.d.ts +2 -0
- package/lib/nullish.js +3 -0
- package/lib/once.d.ts +1 -0
- package/lib/once.js +15 -0
- package/lib/recursiveCopy.d.ts +4 -0
- package/lib/recursiveCopy.js +61 -0
- package/lib/recursiveDelete.d.ts +13 -0
- package/lib/recursiveDelete.js +90 -0
- package/lib/recursiveReaddir.d.ts +34 -0
- package/lib/recursiveReaddir.js +87 -0
- package/lib/resolve.d.ts +2 -0
- package/lib/resolve.js +7 -0
- package/lib/schemaUtils.d.ts +2 -0
- package/lib/schemaUtils.js +4 -0
- package/lib/string.d.ts +1 -0
- package/lib/string.js +11 -0
- package/package.json +38 -0
package/lib/chalk.d.ts
ADDED
package/lib/chalk.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
exports.default = chalk_1.default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepmerge(...args: any[]): any;
|
package/lib/deepmerge.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function mergeTwoObject(origin, target) {
|
|
4
|
+
if (target === null || typeof target === 'undefined') {
|
|
5
|
+
return origin;
|
|
6
|
+
}
|
|
7
|
+
Object.keys(target).forEach((key) => {
|
|
8
|
+
const originValue = origin[key];
|
|
9
|
+
const targetValue = target[key];
|
|
10
|
+
if (Array.isArray(originValue) || Array.isArray(targetValue)) {
|
|
11
|
+
origin[key] = targetValue;
|
|
12
|
+
}
|
|
13
|
+
else if (typeof originValue === 'object' &&
|
|
14
|
+
typeof targetValue === 'object') {
|
|
15
|
+
origin[key] = mergeTwoObject(originValue, targetValue);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
origin[key] = targetValue;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
return origin;
|
|
22
|
+
}
|
|
23
|
+
function deepmerge(...args) {
|
|
24
|
+
return args.reduce(mergeTwoObject, {});
|
|
25
|
+
}
|
|
26
|
+
exports.deepmerge = deepmerge;
|
package/lib/defer.d.ts
ADDED
package/lib/defer.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function Defer() {
|
|
4
|
+
let defer = {
|
|
5
|
+
resolve: null,
|
|
6
|
+
reject: null
|
|
7
|
+
};
|
|
8
|
+
defer.promise = new Promise((resolve, reject) => {
|
|
9
|
+
defer.resolve = resolve;
|
|
10
|
+
defer.reject = reject;
|
|
11
|
+
});
|
|
12
|
+
return defer;
|
|
13
|
+
}
|
|
14
|
+
exports.Defer = Defer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const resolve_1 = __importDefault(require("resolve"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const cache = Object.create(null);
|
|
10
|
+
function getTypeScriptInfo(projectRoot) {
|
|
11
|
+
let info = cache[projectRoot];
|
|
12
|
+
if (!info) {
|
|
13
|
+
let typeScriptPath;
|
|
14
|
+
try {
|
|
15
|
+
typeScriptPath = resolve_1.default.sync('typescript', {
|
|
16
|
+
basedir: projectRoot,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch (_) { }
|
|
20
|
+
const tsConfigPath = path_1.default.join(projectRoot, 'tsconfig.json');
|
|
21
|
+
const useTypeScript = Boolean(typeScriptPath && fs_1.default.existsSync(tsConfigPath));
|
|
22
|
+
info = Object.assign({ useTypeScript }, (useTypeScript === true && { typeScriptPath, tsConfigPath }));
|
|
23
|
+
}
|
|
24
|
+
return info;
|
|
25
|
+
}
|
|
26
|
+
exports.getTypeScriptInfo = getTypeScriptInfo;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function escapeRegExp(s: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare type Handler = (...evts: any[]) => void;
|
|
2
|
+
export declare type EventEmitter<F extends Function = Handler> = {
|
|
3
|
+
on(type: string, handler: F): void;
|
|
4
|
+
off(type: string, handler: F): void;
|
|
5
|
+
emit(type: string, ...evts: any[]): void;
|
|
6
|
+
};
|
|
7
|
+
export default function emitter<F extends Function = Handler>(): EventEmitter<F>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function emitter() {
|
|
4
|
+
const all = Object.create(null);
|
|
5
|
+
return {
|
|
6
|
+
on(type, handler) {
|
|
7
|
+
(all[type] || (all[type] = [])).push(handler);
|
|
8
|
+
},
|
|
9
|
+
off(type, handler) {
|
|
10
|
+
if (all[type]) {
|
|
11
|
+
const index = all[type].indexOf(handler);
|
|
12
|
+
if (index >= 0) {
|
|
13
|
+
all[type].splice(index, 1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
emit(type, ...evts) {
|
|
18
|
+
(all[type] || []).slice().forEach((handler) => {
|
|
19
|
+
handler(...evts);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
exports.default = emitter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TimeInfo } from "watchpack";
|
|
2
|
+
export { TimeInfo };
|
|
3
|
+
export interface WatchEvent {
|
|
4
|
+
changes: string[];
|
|
5
|
+
removals: string[];
|
|
6
|
+
getAllFiles: () => string[];
|
|
7
|
+
}
|
|
8
|
+
export interface WatchOptions {
|
|
9
|
+
files?: string[];
|
|
10
|
+
directories?: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare type WatchCallback = (event: WatchEvent) => void;
|
|
13
|
+
export declare function watch({ files, directories }: WatchOptions, cb: WatchCallback): () => void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const watchpack_1 = __importDefault(require("watchpack"));
|
|
7
|
+
const options = {
|
|
8
|
+
// options:
|
|
9
|
+
aggregateTimeout: 300,
|
|
10
|
+
// fire "aggregated" event when after a change for 1000ms no additional change occurred
|
|
11
|
+
// aggregated defaults to undefined, which doesn't fire an "aggregated" event
|
|
12
|
+
ignored: ["**/.git"]
|
|
13
|
+
// ignored: "string" - a glob pattern for files or folders that should not be watched
|
|
14
|
+
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
|
|
15
|
+
// ignored: /regexp/ - a regular expression for files or folders that should not be watched
|
|
16
|
+
// All subdirectories are ignored too
|
|
17
|
+
};
|
|
18
|
+
function watch({ files, directories }, cb) {
|
|
19
|
+
const wp = new watchpack_1.default(options);
|
|
20
|
+
wp.on("aggregated", (changes, removals) => {
|
|
21
|
+
const knownFiles = wp.getTimeInfoEntries();
|
|
22
|
+
cb({
|
|
23
|
+
changes: Array.from(changes),
|
|
24
|
+
removals: Array.from(removals),
|
|
25
|
+
getAllFiles() {
|
|
26
|
+
const res = [];
|
|
27
|
+
for (const [file, timeinfo] of knownFiles.entries()) {
|
|
28
|
+
if (timeinfo && timeinfo.accuracy !== undefined) {
|
|
29
|
+
res.push(file);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return res;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
wp.watch({ files, directories });
|
|
37
|
+
return () => {
|
|
38
|
+
wp.close();
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
exports.watch = watch;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// This utility is based on https://github.com/zertosh/htmlescape
|
|
3
|
+
// License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const JSON_ESCAPE_LOOKUP = {
|
|
6
|
+
'&': '\\u0026',
|
|
7
|
+
'>': '\\u003e',
|
|
8
|
+
'<': '\\u003c',
|
|
9
|
+
'\u2028': '\\u2028',
|
|
10
|
+
'\u2029': '\\u2029',
|
|
11
|
+
};
|
|
12
|
+
const JSON_ESCAPE_REGEX = /[&><\u2028\u2029]/g;
|
|
13
|
+
function htmlEscapeJsonString(str) {
|
|
14
|
+
return str.replace(JSON_ESCAPE_REGEX, (match) => JSON_ESCAPE_LOOKUP[match]);
|
|
15
|
+
}
|
|
16
|
+
exports.htmlEscapeJsonString = htmlEscapeJsonString;
|
|
17
|
+
const CONTENT_ESCAPE_LOOKUP = {
|
|
18
|
+
'&': '&',
|
|
19
|
+
'"': '"',
|
|
20
|
+
"'": ''',
|
|
21
|
+
'>': '>',
|
|
22
|
+
'<': '<',
|
|
23
|
+
};
|
|
24
|
+
const CONTENT_ESCAPE_REGEX = /[&><\'\"]/g;
|
|
25
|
+
function htmlEscapeContent(str) {
|
|
26
|
+
return str.replace(CONTENT_ESCAPE_REGEX, (match) => CONTENT_ESCAPE_LOOKUP[match]);
|
|
27
|
+
}
|
|
28
|
+
exports.htmlEscapeContent = htmlEscapeContent;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { default as NOOP } from './noopFn';
|
|
2
|
+
export * from './defer';
|
|
3
|
+
export declare const EMPTY_OBJ: {};
|
|
4
|
+
export declare const extend: {
|
|
5
|
+
<T, U>(target: T, source: U): T & U;
|
|
6
|
+
<T_1, U_1, V>(target: T_1, source1: U_1, source2: V): T_1 & U_1 & V;
|
|
7
|
+
<T_2, U_2, V_1, W>(target: T_2, source1: U_2, source2: V_1, source3: W): T_2 & U_2 & V_1 & W;
|
|
8
|
+
(target: object, ...sources: any[]): any;
|
|
9
|
+
};
|
|
10
|
+
export declare const isArray: (arg: any) => arg is any[];
|
|
11
|
+
export declare const isObject: (val: unknown) => val is Record<any, any>;
|
|
12
|
+
export declare const isFunction: (val: unknown) => val is Function;
|
|
13
|
+
export declare const hasOwn: (val: object, key: string | symbol) => key is never;
|
|
14
|
+
export declare function getType(obj: any): string;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function __export(m) {
|
|
3
|
+
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
|
4
|
+
}
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
var noopFn_1 = require("./noopFn");
|
|
7
|
+
exports.NOOP = noopFn_1.default;
|
|
8
|
+
__export(require("./defer"));
|
|
9
|
+
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
10
|
+
const toString = Object.prototype.toString;
|
|
11
|
+
exports.EMPTY_OBJ = {};
|
|
12
|
+
exports.extend = Object.assign;
|
|
13
|
+
exports.isArray = Array.isArray;
|
|
14
|
+
exports.isObject = (val) => val !== null && typeof val === 'object';
|
|
15
|
+
exports.isFunction = (val) => typeof val === 'function';
|
|
16
|
+
exports.hasOwn = (val, key) => hasOwnProperty.call(val, key);
|
|
17
|
+
const objectRegExp = /^\[object (\S+)\]$/;
|
|
18
|
+
function getType(obj) {
|
|
19
|
+
var type = typeof obj;
|
|
20
|
+
if (type !== 'object') {
|
|
21
|
+
return type;
|
|
22
|
+
}
|
|
23
|
+
// inspect [[Class]] for objects
|
|
24
|
+
return toString.call(obj).replace(objectRegExp, '$1');
|
|
25
|
+
}
|
|
26
|
+
exports.getType = getType;
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const tiny_invariant_1 = __importDefault(require("tiny-invariant"));
|
|
7
|
+
exports.default = tiny_invariant_1.default;
|
package/lib/logger.d.ts
ADDED
package/lib/logger.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const debug_1 = __importDefault(require("debug"));
|
|
7
|
+
class LoggerImpl {
|
|
8
|
+
constructor(namespace) {
|
|
9
|
+
this._debug = debug_1.default(namespace);
|
|
10
|
+
}
|
|
11
|
+
debug(formatter, ...args) {
|
|
12
|
+
this._debug(formatter, ...args);
|
|
13
|
+
}
|
|
14
|
+
info(...args) {
|
|
15
|
+
console.log("INFO:", ...args);
|
|
16
|
+
}
|
|
17
|
+
warn(...args) {
|
|
18
|
+
console.warn("WARN:", ...args);
|
|
19
|
+
}
|
|
20
|
+
error(...args) {
|
|
21
|
+
console.error("ERROR:", ...args);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function logger(namespace) {
|
|
25
|
+
return new LoggerImpl(namespace);
|
|
26
|
+
}
|
|
27
|
+
exports.default = logger;
|
package/lib/noop.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/noop.js
ADDED
package/lib/noopFn.d.ts
ADDED
package/lib/noopFn.js
ADDED
package/lib/nullish.d.ts
ADDED
package/lib/nullish.js
ADDED
package/lib/once.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function once<T extends Function>(fn: T): T;
|
package/lib/once.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function once(fn) {
|
|
4
|
+
let hasRun = false;
|
|
5
|
+
let result;
|
|
6
|
+
function wrapped(...args) {
|
|
7
|
+
if (!hasRun) {
|
|
8
|
+
hasRun = true;
|
|
9
|
+
result = fn.apply(this, args);
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
return wrapped;
|
|
14
|
+
}
|
|
15
|
+
exports.once = once;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const util_1 = require("util");
|
|
18
|
+
const async_sema_1 = require("async-sema");
|
|
19
|
+
const fsMkdir = util_1.promisify(fs_1.default.mkdir);
|
|
20
|
+
const fsStat = util_1.promisify(fs_1.default.stat);
|
|
21
|
+
const fsReaddir = util_1.promisify(fs_1.default.readdir);
|
|
22
|
+
const fsCopyFile = util_1.promisify(fs_1.default.copyFile);
|
|
23
|
+
const COPYFILE_EXCL = fs_1.default.constants.COPYFILE_EXCL;
|
|
24
|
+
function recursiveCopy(source, dest, { concurrency = 255, filter = () => true, } = {}) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
const cwdPath = process.cwd();
|
|
27
|
+
const from = path_1.default.resolve(cwdPath, source);
|
|
28
|
+
const to = path_1.default.resolve(cwdPath, dest);
|
|
29
|
+
const sema = new async_sema_1.Sema(concurrency);
|
|
30
|
+
function _copy(item) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
const target = item.replace(from, to);
|
|
33
|
+
const stats = yield fsStat(item);
|
|
34
|
+
yield sema.acquire();
|
|
35
|
+
if (stats.isDirectory()) {
|
|
36
|
+
try {
|
|
37
|
+
yield fsMkdir(target);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
// do not throw `folder already exists` errors
|
|
41
|
+
if (err.code !== 'EEXIST') {
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const files = yield fsReaddir(item);
|
|
46
|
+
yield Promise.all(files.map(file => _copy(path_1.default.join(item, file))));
|
|
47
|
+
}
|
|
48
|
+
else if (stats.isFile() &&
|
|
49
|
+
// before we send the path to filter
|
|
50
|
+
// we remove the base path (from) and replace \ by / (windows)
|
|
51
|
+
filter(item.replace(from, '').replace(/\\/g, '/'))) {
|
|
52
|
+
yield fsCopyFile(item, target, COPYFILE_EXCL);
|
|
53
|
+
}
|
|
54
|
+
sema.release();
|
|
55
|
+
return;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
yield _copy(from);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
exports.recursiveCopy = recursiveCopy;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively read directory
|
|
3
|
+
* @param {string} dir Directory to delete
|
|
4
|
+
* @param {Object} options
|
|
5
|
+
* @param {RegExp} options.filter Filter for the file name, only the relative file path is considered, not the full path
|
|
6
|
+
* @param {RegExp} options.ignore Ignore certain files, only the relative file path is considered, not the full path
|
|
7
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
8
|
+
*/
|
|
9
|
+
export declare function recursiveDelete(dir: string, { filter, ignore, rootDir, }?: {
|
|
10
|
+
filter?: RegExp;
|
|
11
|
+
ignore?: RegExp;
|
|
12
|
+
rootDir?: string;
|
|
13
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
const util_1 = require("util");
|
|
18
|
+
const fsReaddir = util_1.promisify(fs_1.default.readdir);
|
|
19
|
+
const fsStat = util_1.promisify(fs_1.default.stat);
|
|
20
|
+
const fsRmdir = util_1.promisify(fs_1.default.rmdir);
|
|
21
|
+
const fsUnlink = util_1.promisify(fs_1.default.unlink);
|
|
22
|
+
const sleep = util_1.promisify(setTimeout);
|
|
23
|
+
const unlinkFile = (p, t = 1) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
try {
|
|
25
|
+
yield fsUnlink(p);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
if ((e.code === 'EBUSY' ||
|
|
29
|
+
e.code === 'ENOTEMPTY' ||
|
|
30
|
+
e.code === 'EPERM' ||
|
|
31
|
+
e.code === 'EMFILE') &&
|
|
32
|
+
t < 3) {
|
|
33
|
+
yield sleep(t * 100);
|
|
34
|
+
return unlinkFile(p, t++);
|
|
35
|
+
}
|
|
36
|
+
if (e.code === 'ENOENT') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
/**
|
|
43
|
+
* Recursively read directory
|
|
44
|
+
* @param {string} dir Directory to delete
|
|
45
|
+
* @param {Object} options
|
|
46
|
+
* @param {RegExp} options.filter Filter for the file name, only the relative file path is considered, not the full path
|
|
47
|
+
* @param {RegExp} options.ignore Ignore certain files, only the relative file path is considered, not the full path
|
|
48
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
49
|
+
*/
|
|
50
|
+
function recursiveDelete(dir, { filter, ignore, rootDir = dir, } = {}) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
let result;
|
|
53
|
+
try {
|
|
54
|
+
result = yield fsReaddir(dir);
|
|
55
|
+
}
|
|
56
|
+
catch (e) {
|
|
57
|
+
if (e.code === 'ENOENT') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
throw e;
|
|
61
|
+
}
|
|
62
|
+
yield Promise.all(result.map((part) => __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
const absolutePath = path_1.join(dir, part);
|
|
64
|
+
const pathStat = yield fsStat(absolutePath).catch((e) => {
|
|
65
|
+
if (e.code !== 'ENOENT')
|
|
66
|
+
throw e;
|
|
67
|
+
});
|
|
68
|
+
if (!pathStat) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const pp = absolutePath.replace(rootDir, '');
|
|
72
|
+
if (ignore && ignore.test(pp)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (filter && !filter.test(part)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (pathStat.isDirectory()) {
|
|
79
|
+
yield recursiveDelete(absolutePath, {
|
|
80
|
+
filter,
|
|
81
|
+
ignore,
|
|
82
|
+
rootDir: pp,
|
|
83
|
+
});
|
|
84
|
+
return fsRmdir(absolutePath);
|
|
85
|
+
}
|
|
86
|
+
return unlinkFile(absolutePath);
|
|
87
|
+
})));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
exports.recursiveDelete = recursiveDelete;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
declare type Test = RegExp | ((v: string) => boolean);
|
|
2
|
+
/**
|
|
3
|
+
* Recursively read directory
|
|
4
|
+
* @param {string} dir Directory to read
|
|
5
|
+
* @param {Object} options
|
|
6
|
+
* @param {RegExp} options.filter Filter for the file name, only the name part is considered, not the full path
|
|
7
|
+
* @param {RegExp} options.ignore Ignore certain files, only the name part is considered, not the full path
|
|
8
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
9
|
+
* @param {string} options.arr This doesn't have to be provided, it's used for the recursion
|
|
10
|
+
* @returns {Promise<string[]>} Promise array holding all relative paths
|
|
11
|
+
*/
|
|
12
|
+
export declare function recursiveReadDir(dir: string, { filter, ignore, rootDir, arr }?: {
|
|
13
|
+
filter?: Test;
|
|
14
|
+
ignore?: RegExp;
|
|
15
|
+
rootDir?: string;
|
|
16
|
+
arr?: string[];
|
|
17
|
+
}): Promise<string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Recursively read directory
|
|
20
|
+
* @param {string} dir Directory to read
|
|
21
|
+
* @param {Object} options
|
|
22
|
+
* @param {RegExp} options.filter Filter for the file name, only the name part is considered, not the full path
|
|
23
|
+
* @param {RegExp} options.ignore Ignore certain files, only the name part is considered, not the full path
|
|
24
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
25
|
+
* @param {string} options.arr This doesn't have to be provided, it's used for the recursion
|
|
26
|
+
* @returns {string[]} Promise array holding all relative paths
|
|
27
|
+
*/
|
|
28
|
+
export declare function recursiveReadDirSync(dir: string, { filter, ignore, rootDir, arr }?: {
|
|
29
|
+
filter?: RegExp;
|
|
30
|
+
ignore?: RegExp;
|
|
31
|
+
rootDir?: string;
|
|
32
|
+
arr?: string[];
|
|
33
|
+
}): string[];
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
const util_1 = require("util");
|
|
18
|
+
const fsReaddir = util_1.promisify(fs_1.default.readdir);
|
|
19
|
+
const fsStat = util_1.promisify(fs_1.default.stat);
|
|
20
|
+
function runTest(test, v) {
|
|
21
|
+
if (typeof test === "function") {
|
|
22
|
+
return test(v);
|
|
23
|
+
}
|
|
24
|
+
return test.test(v);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Recursively read directory
|
|
28
|
+
* @param {string} dir Directory to read
|
|
29
|
+
* @param {Object} options
|
|
30
|
+
* @param {RegExp} options.filter Filter for the file name, only the name part is considered, not the full path
|
|
31
|
+
* @param {RegExp} options.ignore Ignore certain files, only the name part is considered, not the full path
|
|
32
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
33
|
+
* @param {string} options.arr This doesn't have to be provided, it's used for the recursion
|
|
34
|
+
* @returns {Promise<string[]>} Promise array holding all relative paths
|
|
35
|
+
*/
|
|
36
|
+
function recursiveReadDir(dir, { filter, ignore, rootDir = dir, arr = [] } = {}) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
const result = yield fsReaddir(dir);
|
|
39
|
+
yield Promise.all(result.map((part) => __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const absolutePath = path_1.default.join(dir, part);
|
|
41
|
+
const pp = absolutePath.replace(rootDir, "");
|
|
42
|
+
if (ignore && ignore.test(pp)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const pathStat = yield fsStat(absolutePath);
|
|
46
|
+
if (pathStat.isDirectory()) {
|
|
47
|
+
yield recursiveReadDir(absolutePath, { filter, ignore, arr, rootDir });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (filter && !runTest(filter, part)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
arr.push(pp);
|
|
54
|
+
})));
|
|
55
|
+
return arr.sort();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
exports.recursiveReadDir = recursiveReadDir;
|
|
59
|
+
/**
|
|
60
|
+
* Recursively read directory
|
|
61
|
+
* @param {string} dir Directory to read
|
|
62
|
+
* @param {Object} options
|
|
63
|
+
* @param {RegExp} options.filter Filter for the file name, only the name part is considered, not the full path
|
|
64
|
+
* @param {RegExp} options.ignore Ignore certain files, only the name part is considered, not the full path
|
|
65
|
+
* @param {string} options.rootDir Used to replace the initial path, only the relative path is left, it's faster than path.relative.
|
|
66
|
+
* @param {string} options.arr This doesn't have to be provided, it's used for the recursion
|
|
67
|
+
* @returns {string[]} Promise array holding all relative paths
|
|
68
|
+
*/
|
|
69
|
+
function recursiveReadDirSync(dir, { filter, ignore, rootDir = dir, arr = [] } = {}) {
|
|
70
|
+
const result = fs_1.default.readdirSync(dir);
|
|
71
|
+
result.forEach((part) => {
|
|
72
|
+
const absolutePath = path_1.default.join(dir, part);
|
|
73
|
+
if (ignore && ignore.test(part))
|
|
74
|
+
return;
|
|
75
|
+
const pathStat = fs_1.default.statSync(absolutePath);
|
|
76
|
+
if (pathStat.isDirectory()) {
|
|
77
|
+
recursiveReadDirSync(absolutePath, { filter, ignore, arr, rootDir });
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (filter && !filter.test(part)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
arr.push(absolutePath.replace(rootDir, ""));
|
|
84
|
+
});
|
|
85
|
+
return arr.sort();
|
|
86
|
+
}
|
|
87
|
+
exports.recursiveReadDirSync = recursiveReadDirSync;
|
package/lib/resolve.d.ts
ADDED
package/lib/resolve.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const resolve_1 = __importDefault(require("resolve"));
|
|
7
|
+
exports.default = resolve_1.default;
|
package/lib/string.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function joinPath(lead: string, ...paths: string[]): string;
|
package/lib/string.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function joinPath(lead, ...paths) {
|
|
4
|
+
if (paths.length < 1) {
|
|
5
|
+
return lead;
|
|
6
|
+
}
|
|
7
|
+
return (lead.replace(/\/+$/, '') +
|
|
8
|
+
'/' +
|
|
9
|
+
paths.join('/').replace(/\\/g, '/').replace(/\/+/g, '/').replace(/^\/+/, ''));
|
|
10
|
+
}
|
|
11
|
+
exports.joinPath = joinPath;
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shuvi/utils",
|
|
3
|
+
"version": "0.0.1-rc.33",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/shuvijs/shuvi.git",
|
|
7
|
+
"directory": "packages/utils"
|
|
8
|
+
},
|
|
9
|
+
"author": "liximomo",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"main": "lib/index.js",
|
|
12
|
+
"files": [
|
|
13
|
+
"lib"
|
|
14
|
+
],
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "tsc -p tsconfig.build.json -w",
|
|
18
|
+
"prebuild": "rimraf lib",
|
|
19
|
+
"build": "tsc -p tsconfig.build.json"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">= 12.0.0"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"async-sema": "3.1.0",
|
|
26
|
+
"chalk": "4.1.0",
|
|
27
|
+
"debug": "4.3.1",
|
|
28
|
+
"resolve": "1.19.0",
|
|
29
|
+
"schema-utils": "^3.0.0",
|
|
30
|
+
"tiny-invariant": "1.1.0",
|
|
31
|
+
"watchpack": "2.1.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/debug": "^4.1.5",
|
|
35
|
+
"@types/resolve": "^1.14.0"
|
|
36
|
+
},
|
|
37
|
+
"gitHead": "e698d54691f08c02150b9ff8a41125e6b0db2898"
|
|
38
|
+
}
|