lugger
Version:
Lugger is an automation framework running on customizable Typescript DSL
358 lines (335 loc) • 15.6 kB
text/typescript
// DSL SKIP
import { CallContextEvent, CCE, dedent, getRuntime, PostfixReturn, dslIfaceGuard } from "ts-dsl";
import { FileOperationOptions, FileOperationReturn } from "./fs.model";
import * as fs from 'fs';
import * as YAML from 'yaml';
import * as prependFile from 'prepend-file';
import { promise, TaggedTemplateSelfChain } from 'ts-basis';
export { YAML };
// ====================================================
// Facade
// ====================================================
class fileModel {
static exists(file: FileOperationOptions): PostfixReturn<boolean>;
static exists(file: string): PostfixReturn<boolean>;
static exists(command) { dslIfaceGuard('lugger:file:exists', __filename); return null; }
static read(file: FileOperationOptions): PostfixReturn<string>;
static read(file: FileOperationOptions, encoding: 'buffer'): PostfixReturn<Buffer>;
static read(file: FileOperationOptions, encoding: BufferEncoding): PostfixReturn<string>;
static read(file: string): PostfixReturn<string>;
static read(file: string, encoding: 'buffer'): PostfixReturn<Buffer>;
static read(file: string, encoding: BufferEncoding): PostfixReturn<string>;
static read(strArr: TemplateStringsArray, ...args: any[]): TaggedTemplateSelfChain<PostfixReturn<string>>;
static read(command) { dslIfaceGuard('lugger:file:read', __filename); return null; }
static readJSON<T extends Object = any>(file: string, encoding?: BufferEncoding): PostfixReturn<T>;
static readJSON(command) { dslIfaceGuard('lugger:file:readJSON', __filename); return null; }
static readYAML<T extends Object = any>(file: string, encoding?: BufferEncoding): PostfixReturn<T>;
static readYAML(command) { dslIfaceGuard('lugger:file:readYAML', __filename); return null; }
static writeJSON<T extends Object = any>(file: string, object: T, encoding?: BufferEncoding): PostfixReturn<void>;
static writeJSON(command) { dslIfaceGuard('lugger:file:writeJSON', __filename); return null; }
static writeYAML<T extends Object = any>(file: string, object: T, encoding?: BufferEncoding): PostfixReturn<void>;
static writeYAML(command) { dslIfaceGuard('lugger:file:writeYAML', __filename); return null; }
static write(file: FileOperationOptions, content: Buffer): PostfixReturn<void>;
static write(file: FileOperationOptions, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static write(file: string, content: Buffer): PostfixReturn<void>;
static write(file: string, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static write(strArr: TemplateStringsArray, ...args: any[]): TaggedTemplateSelfChain<PostfixReturn<void>>;
static write(command) { dslIfaceGuard('lugger:file:write', __filename); return null; }
static append(file: FileOperationOptions, content: Buffer): PostfixReturn<void>;
static append(file: FileOperationOptions, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static append(file: string, content: Buffer): PostfixReturn<void>;
static append(file: string, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static append(strArr: TemplateStringsArray, ...args: any[]): TaggedTemplateSelfChain<PostfixReturn<void>>;
static append(command) { dslIfaceGuard('lugger:file:append', __filename); return null; }
static prepend(file: FileOperationOptions, content: Buffer): PostfixReturn<void>;
static prepend(file: FileOperationOptions, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static prepend(file: string, content: Buffer): PostfixReturn<void>;
static prepend(file: string, content: string, encoding?: BufferEncoding): PostfixReturn<void>;
static prepend(strArr: TemplateStringsArray, ...args: any[]): TaggedTemplateSelfChain<PostfixReturn<void>>;
static prepend(command) { dslIfaceGuard('lugger:file:prepend', __filename); return null; }
static truncate(file: FileOperationOptions): PostfixReturn<void>;
static truncate(file: string): PostfixReturn<void>;
static truncate(command) { dslIfaceGuard('lugger:file:truncate', __filename); return null; }
static delete(file: FileOperationOptions): PostfixReturn<void>;
static delete(file: string): PostfixReturn<void>;
static delete(command) { dslIfaceGuard('lugger:file:delete', __filename); return null; }
static unlink(file: FileOperationOptions): PostfixReturn<void>;
static unlink(file: string): PostfixReturn<void>;
static unlink(command) { dslIfaceGuard('lugger:file:unlink', __filename); return null; }
static stat(file: FileOperationOptions): PostfixReturn<fs.Stats>;
static stat(file: string): PostfixReturn<fs.Stats>;
static stat(command) { dslIfaceGuard('lugger:file:stat', __filename); return null; }
}
export const file = fileModel as (typeof fileModel & ((filename: string) => FileOperationReturn));
// ====================================================
// Implemenation
// ====================================================
function fileModel__(cce: CallContextEvent, ...args) {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
return resolve(Object.assign({
isFileTarget: true,
'on a >> this': (cce: CCE, opName, self, a, b, c) => {
const content = Buffer.isBuffer(a) ? a: typeof a === 'string' ? Buffer.from(a, self.encoding) : null;
return promise(async (resolve2, reject2) => {
fs.appendFile(self.file, content, { encoding }, e => { if (e) { return reject2(e); } return resolve2(void 0); });
});
},
'on this << b': (cce: CCE, opName, self, a, b, c) => {
const content = Buffer.isBuffer(b) ? b: typeof b === 'string' ? Buffer.from(b, self.encoding) : null;
return promise(async (resolve2, reject2) => {
fs.appendFile(self.file, content, { encoding }, e => { if (e) { return reject2(e); } return resolve2(void 0); });
});
},
'on a > this': (cce: CCE, opName, self, a, b, c) => {
const content = Buffer.isBuffer(a) ? a: typeof a === 'string' ? Buffer.from(a, self.encoding) : null;
return promise(async (resolve2, reject2) => {
fs.writeFile(self.file, content, { encoding }, e => { if (e) { return reject2(e); } return resolve2(void 0); });
});
},
'on this < b': (cce: CCE, opName, self, a, b, c) => {
const content = Buffer.isBuffer(b) ? b: typeof b === 'string' ? Buffer.from(b, self.encoding) : null;
return promise(async (resolve2, reject2) => {
fs.writeFile(self.file, content, { encoding }, e => { if (e) { return reject2(e); } return resolve2(void 0); });
});
},
}, fileOp) as any as FileOperationReturn);
} catch (e) { reject(e); }
});
}
(fileModel__ as any).exists = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.exists', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.access(fileOp.file, fs.constants.F_OK, e => {
return resolve(e ? false : true);
})
} catch (e) { reject(e); }
});
}
(fileModel__ as any).read = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.read', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
if ((encoding as any) === 'buffer') {
fs.readFile(fileOp.file, (e, data) => {
if (e) { return reject(e); }
return resolve(data);
});
} else {
fs.readFile(fileOp.file, encoding, (e, data) => {
if (e) { return reject(e); }
return resolve(data);
});
}
} catch (e) { reject(e); }
});
}
(fileModel__ as any).readJSON = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.readJSON', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.readFile(fileOp.file, encoding, (e, data) => {
if (e) { return reject(e); }
try { return resolve(JSON.parse(data)); } catch (e2) { return reject(e2); }
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).readYAML = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.readYAML', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.readFile(fileOp.file, encoding, (e, data) => {
if (e) { return reject(e); }
try { return resolve(YAML.parse(data)); } catch (e2) { return reject(e2); }
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).write = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, content, error } = getWriteArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.write', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.writeFile(fileOp.file, content, { encoding }, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).writeJSON = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, content, error } = getWriteArg(cce, args, 'json');
return getRuntime().scopedExec(
cce, 'lugger:fs:file.writeJSON', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.writeFile(fileOp.file, content, { encoding }, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).writeYAML = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, content, error } = getWriteArg(cce, args, 'yaml');
return getRuntime().scopedExec(
cce, 'lugger:fs:file.writeYAML', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.writeFile(fileOp.file, content, { encoding }, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).append = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, content, error } = getWriteArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.append', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.appendFile(fileOp.file, content, { encoding }, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).prepend = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, content, error } = getWriteArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.prepend', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
await prependFile.default(fileOp.file, content);
} catch (e) { reject(e); }
});
}
(fileModel__ as any).truncate = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.prepend', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.truncate(fileOp.file, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).delete = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.delete', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.unlink(fileOp.file, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).unlink = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.unlink', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.unlink(fileOp.file, e => {
if (e) { return reject(e); }
return resolve(void 0);
});
} catch (e) { reject(e); }
});
}
(fileModel__ as any).stat = (cce: CallContextEvent, ...args) => {
const { fileOp, encoding, error } = getReadArg(cce, args);
return getRuntime().scopedExec(
cce, 'lugger:fs:file.stat', { data: { fileOp } },
async (resolve, reject, scopeContext) => {
if (error) { return reject(error); }
try {
fs.stat(fileOp.file, (e, data) => {
if (e) { return reject(e); }
return resolve(data);
});
} catch (e) { reject(e); }
});
}
export const file__ = fileModel__ as any as (typeof file);
function getReadArg(cce: CCE, args: any[]) {
let error: Error;
const arg0 = args[0];
let fileOp: FileOperationOptions = (arg0 as any);
if (typeof arg0 === 'string') {
fileOp = cce.fromTaggedTemplate ? { file: arg0 } as FileOperationOptions : { file: arg0 } as FileOperationOptions;
}
if (!fileOp.file) {
error = new Error(`cannot operate on file without file location`);
}
let encoding = args[1] as BufferEncoding;
if (!encoding) { encoding = 'utf8'; fileOp.encoding = encoding; }
return { fileOp, encoding, error };
}
function getWriteArg(cce: CCE, args: any[] , contentType: 'default' | 'json' | 'yaml' = 'default') {
let error: Error;
const arg0 = args[0];
let arg1 = args[1];
let fileOp: FileOperationOptions = (arg0 as any);
if (typeof arg0 === 'string') {
fileOp = cce.fromTaggedTemplate ? { file: arg0 } as FileOperationOptions : { file: arg0 } as FileOperationOptions;
}
let encoding = args[2] as BufferEncoding;
if (!encoding) { encoding = 'utf8'; fileOp.encoding = encoding; }
let content: Buffer = null;
try {
if (fileOp?.dedent && typeof arg1 === 'string') {
arg1 = dedent(arg1);
}
if (contentType === 'default') {
content = Buffer.isBuffer(arg1) ? arg1:
typeof arg1 === 'string' ? Buffer.from(arg1, encoding) :
null;
} else if (contentType === 'json') {
content = Buffer.from(JSON.stringify(arg1, null, 4), encoding);
} else if (contentType === 'yaml') {
content = Buffer.from(YAML.stringify(arg1), encoding);
}
} catch (e) {
error = e;
}
if (!fileOp.file) {
error = new Error(`cannot operate on file without file location`);
}
return { fileOp, encoding, content, error };
}