import fs from 'fs-extra'; import path from 'path'; import { parse } from 'shell-quote'; import _ from 'lodash'; import { EventEmitter } from 'events'; import { FormatError } from './error'; const EMPTY_STR = /^[ \r\n\t]*$/i; export const cmd = parse; export function parseFilename(filePath: string) { const t = filePath.split('/'); return t[t.length - 1]; } export class Queue extends EventEmitter { queue: T[] = []; waiting: any[] = []; get(count = 1) { if (this.queue.length < count) { return new Promise((resolve) => { this.waiting.push({ count, resolve }); }); } const items = []; for (let i = 0; i < count; i++) { items.push(this.queue[i]); } this.queue = _.drop(this.queue, count); return items as T[]; } push(value: T) { this.queue.push(value); if (this.waiting.length && this.waiting[0].count <= this.queue.length) { const items = []; for (let i = 0; i < this.waiting[0].count; i++) { items.push(this.queue[i]); } this.queue = _.drop(this.queue, this.waiting[0].count); this.waiting[0].resolve(items); this.waiting.shift(); } } } export function compilerText(stdout: string, stderr: string) { const ret = []; if (!EMPTY_STR.test(stdout)) ret.push(stdout.substr(0, 1024 * 1024)); if (!EMPTY_STR.test(stderr)) ret.push(stderr.substr(0, 1024 * 1024)); return ret.join('\n'); } export function copyInDir(dir: string) { const files = {}; if (fs.existsSync(dir)) { fs.readdirSync(dir).forEach((f1) => { const p1 = `${dir}/${f1}`; if (fs.statSync(p1).isDirectory()) { fs.readdirSync(p1).forEach((f2) => { files[`${f1}/${f2}`] = { src: `${dir}/${f1}/${f2}` }; }); } else files[f1] = { src: `${dir}/${f1}` }; }); } return files; } export function restrictFile(p: string) { if (!p) return '/'; if (p[0] === '/') p = ''; return p.replace(/\.\./gmi, ''); } export function ensureFile(folder: string) { return (file: string, message: string) => { if (file === '/dev/null') return file; // Historical issue if (file.includes('/')) { const f = path.join(folder, restrictFile(file.split('/')[1])); if (fs.existsSync(f)) { const stat = fs.statSync(f); if (stat.isFile()) return f; } } const f = path.join(folder, restrictFile(file)); if (!fs.existsSync(f)) throw new FormatError(message, [file]); const stat = fs.statSync(f); if (!stat.isFile()) throw new FormatError(message, [file]); return f; }; } export * from '@hydrooj/utils/lib/utils';