chore: 整理 third-party Dark Reader 目录并移除本地说明文件跟踪
This commit is contained in:
+201
@@ -0,0 +1,201 @@
|
||||
// @ts-check
|
||||
import {exec} from 'node:child_process';
|
||||
import {accessSync} from 'node:fs';
|
||||
import fs from 'node:fs/promises';
|
||||
import https from 'node:https';
|
||||
import path from 'node:path';
|
||||
|
||||
/** @type {{[color: string]: (text: string) => string}} */
|
||||
const colors = Object.entries({
|
||||
gray: '\x1b[90m',
|
||||
green: '\x1b[32m',
|
||||
red: '\x1b[31m',
|
||||
yellow: '\x1b[33m',
|
||||
}).reduce((map, [key, value]) => Object.assign(map, {[key]: (/** @type {string} */text) => `${value}${text}\x1b[0m`}), {});
|
||||
|
||||
/**
|
||||
* @param {string} command
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function execute(command) {
|
||||
return new Promise((resolve, reject) => exec(command, (error, stdout) => {
|
||||
if (error) {
|
||||
reject(`Failed to execute command ${command}`);
|
||||
} else {
|
||||
resolve(stdout);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @returns
|
||||
*/
|
||||
export function logWithTime(text) {
|
||||
const now = new Date();
|
||||
const hours = now.getHours();
|
||||
const minutes = now.getMinutes();
|
||||
const seconds = now.getSeconds();
|
||||
const leftpad = (/** @type {number} */n) => String(n).padStart(2, '0');
|
||||
return console.log(`${colors.gray([hours, minutes, seconds].map(leftpad).join(':'))} ${text}`);
|
||||
}
|
||||
|
||||
export const log = Object.assign((/** @type {string} */text) => logWithTime(text), {
|
||||
ok: (/** @type {string} */text) => logWithTime(colors.green(text)),
|
||||
warn: (/** @type {string} */text) => logWithTime(colors.yellow(text)),
|
||||
error: (/** @type {string} */text) => logWithTime(colors.red(text)),
|
||||
clearLine: () => {
|
||||
process.stdout.moveCursor(0, -1);
|
||||
process.stdout.clearLine(1);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} dest
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
export async function pathExists(dest) {
|
||||
try {
|
||||
await fs.access(dest);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dest
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function pathExistsSync(dest) {
|
||||
try {
|
||||
accessSync(dest);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dir
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function removeFolder(dir) {
|
||||
if (await pathExists(dir)) {
|
||||
await fs.rm(dir, {recursive: true});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dest
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function mkDirIfMissing(dest) {
|
||||
const dir = path.dirname(dest);
|
||||
if (!(await pathExists(dir))) {
|
||||
await fs.mkdir(dir, {recursive: true});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} src
|
||||
* @param {string} dest
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function copyFile(src, dest) {
|
||||
await mkDirIfMissing(dest);
|
||||
await fs.copyFile(src, dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} src
|
||||
* @param {BufferEncoding} [encoding]
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function readFile(src, encoding = 'utf8') {
|
||||
return await fs.readFile(src, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} src
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
export async function fileExists(src) {
|
||||
try {
|
||||
await fs.access(src, fs.constants.R_OK);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dest
|
||||
* @param {string} content
|
||||
* @param {BufferEncoding | null | undefined} encoding
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function writeFile(dest, content, encoding = 'utf8') {
|
||||
await mkDirIfMissing(dest);
|
||||
await fs.writeFile(dest, content, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function readJSON(path) {
|
||||
const file = await readFile(path);
|
||||
return JSON.parse(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} dest
|
||||
* @param {string} content
|
||||
* @param {string | number | undefined} space
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function writeJSON(dest, content, space = 4) {
|
||||
const string = JSON.stringify(content, null, space);
|
||||
return await writeFile(dest, string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | string[]} patterns
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
export async function getPaths(patterns) {
|
||||
const {globby} = await import('globby');
|
||||
return await globby(patterns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} delay
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export function timeout(delay) {
|
||||
return new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {Promise<{buffer(): Buffer; text(encoding?: BufferEncoding): string; type(): string}>}
|
||||
*/
|
||||
export function httpsRequest(url) {
|
||||
return new Promise((resolve) => {
|
||||
/** @type {Uint8Array[]} */
|
||||
const data = [];
|
||||
https.get(url, (response) => {
|
||||
response
|
||||
.on('data', (chunk) => data.push(chunk))
|
||||
.on('end', () => {
|
||||
const buffer = Buffer.concat(data);
|
||||
resolve({
|
||||
buffer: () => buffer,
|
||||
text: (encoding = 'utf8') => buffer.toString(encoding),
|
||||
type: () => response.headers['content-type'] || '',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user