@mieweb/wikigdrive
Version:
Google Drive to MarkDown synchronization
106 lines (105 loc) • 3.75 kB
JavaScript
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;
}
}
}