UNPKG

@mieweb/wikigdrive

Version:

Google Drive to MarkDown synchronization

106 lines (105 loc) 3.75 kB
import path from 'node:path'; import fs from 'node:fs'; import os from 'node:os'; import Transport from 'winston-transport'; import { JobLogFileProcessor } from './JobLogFileProcessor.js'; function isValidFileName(filename) { // deno-lint-ignore no-control-regex return !/["<>|:*?\\/\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(filename); } function isValidDirName(dirname) { // deno-lint-ignore no-control-regex return !/["<>|\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]/g.test(dirname); } const loggerDefaults = { file_options: { flags: 'a' }, eol: os.EOL, }; export class JobLogFile extends Transport { constructor(options) { super(options); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: 'jobLogFile' }); Object.defineProperty(this, "options", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "dirname", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "filename", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.options = { ...loggerDefaults, ...options }; this.filename = options.filename; this.dirname = options.dirname; if (!isValidFileName(this.filename) || !isValidDirName(this.dirname)) { throw new Error('Your path or filename contain an invalid character.'); } } log(info, callback) { if (info?.jobId) { const logStream = this.getLogStream(info.driveId, info.jobId); logStream.write(JSON.stringify(info) + this.options.eol); logStream.close(); this.emit('logged', info); } if (callback) { callback(null, true); } } async close() { this.emit('finish'); } getLogStream(driveId, jobId) { driveId = driveId || ''; const dirname = this.dirname .replace('%driveId%', driveId) .replace('%jobId%', jobId) .replace('//', '/'); fs.mkdirSync(dirname, { recursive: true }); const filename = path.join(dirname, this.filename) .replace(/%JOB_ID%/g, jobId); return fs.createWriteStream(filename, this.options.file_options); } async query(options, callback) { if (!this.filename) { throw new Error('query() may not be used when initializing with a stream'); } options = options || {}; if (!options.jobId || !options.driveId) { callback(null, []); return []; } options.order = options.order || 'desc'; const dirname = this.dirname .replace('%driveId%', options.driveId) .replace('%jobId%', options.jobId) .replace('//', '/'); fs.mkdirSync(dirname, { recursive: true }); const filename = path.join(dirname, this.filename) .replace(/%JOB_ID%/g, options.jobId); try { const processor = new JobLogFileProcessor(filename, options); const results = await processor.query(); callback(null, results); return results; } catch (err) { callback(err); throw err; } } }