119 lines
3.2 KiB
TypeScript
119 lines
3.2 KiB
TypeScript
import crypto from 'crypto';
|
|
import fs from 'fs/promises';
|
|
import path from 'path';
|
|
|
|
import type {FileRule} from './options';
|
|
|
|
export function checkFileWithRules(filePath: string, rules: FileRule[] = []): boolean {
|
|
for (const rule of rules) {
|
|
if (rule instanceof RegExp) {
|
|
rule.lastIndex = 0;
|
|
if (rule.test(filePath)) {
|
|
return true;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (rule(filePath)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export function getMd5(data: Buffer | string): string {
|
|
return crypto.createHash('md5').update(data).digest('hex').slice(0, 5);
|
|
}
|
|
|
|
export function getAssetType(uri: string): 'absolute' | 'base64' | 'relative' {
|
|
if (/^http/i.test(uri)) {
|
|
return 'absolute';
|
|
}
|
|
|
|
if (/^data:[^;]+;base64,/.test(uri)) {
|
|
return 'base64';
|
|
}
|
|
|
|
return 'relative';
|
|
}
|
|
|
|
export async function readFileText(filePath: string): Promise<string> {
|
|
return fs.readFile(filePath, 'utf8');
|
|
}
|
|
|
|
export async function readFileBuffer(filePath: string): Promise<Buffer> {
|
|
return fs.readFile(filePath);
|
|
}
|
|
|
|
export async function ensureDir(dirPath: string): Promise<void> {
|
|
await fs.mkdir(dirPath, {recursive: true});
|
|
}
|
|
|
|
export async function writeFile(filePath: string, data: Buffer | string): Promise<void> {
|
|
await ensureDir(path.dirname(filePath));
|
|
await fs.writeFile(filePath, data);
|
|
}
|
|
|
|
export async function copyFile(from: string, to: string): Promise<void> {
|
|
await ensureDir(path.dirname(to));
|
|
await fs.copyFile(from, to);
|
|
}
|
|
|
|
export async function copyDir(from: string, to: string): Promise<void> {
|
|
await ensureDir(to);
|
|
const entries = await fs.readdir(from, {withFileTypes: true});
|
|
|
|
for (const entry of entries) {
|
|
const sourcePath = path.join(from, entry.name);
|
|
const targetPath = path.join(to, entry.name);
|
|
if (entry.isDirectory()) {
|
|
await copyDir(sourcePath, targetPath);
|
|
} else {
|
|
await copyFile(sourcePath, targetPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function removeDir(dirPath: string): Promise<void> {
|
|
await fs.rm(dirPath, {recursive: true, force: true});
|
|
}
|
|
|
|
export function bufferToDataUri(buffer: Buffer, mimeType: string): string {
|
|
return `data:${mimeType || ''};base64,${buffer.toString('base64')}`;
|
|
}
|
|
|
|
export function cloneJson<T>(input: T): T {
|
|
return JSON.parse(JSON.stringify(input));
|
|
}
|
|
|
|
export function toPosixPath(inputPath: string): string {
|
|
return inputPath.replace(/\\/g, '/');
|
|
}
|
|
|
|
export function getRelativeOutputDir(rootDir: string, sourceDir: string): string {
|
|
const relativeDir = path.relative(rootDir, sourceDir);
|
|
if (!relativeDir || relativeDir === '.') {
|
|
return '';
|
|
}
|
|
|
|
if (relativeDir.startsWith('..')) {
|
|
return path.basename(sourceDir);
|
|
}
|
|
|
|
return relativeDir;
|
|
}
|
|
|
|
export function getHashedAssetPath(baseDir: string, uri: string, data: Buffer): string {
|
|
const parsed = path.posix.parse(toPosixPath(uri));
|
|
const segments = parsed.dir ? parsed.dir.split('/') : [];
|
|
segments.push(parsed.name, getMd5(data));
|
|
|
|
return path.join(baseDir, `${segments.join('-')}${parsed.ext}`);
|
|
}
|
|
|
|
export function appendHashToFilename(relativePath: string, data: Buffer): string {
|
|
const parsed = path.parse(relativePath);
|
|
return path.join(parsed.dir, `${parsed.name}-${getMd5(data)}${parsed.ext}`);
|
|
}
|