mirror of
https://github.com/sern-handler/handler
synced 2026-06-20 06:42:14 +00:00
79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
import { readdirSync, statSync } from 'fs';
|
|
import { join, basename } from 'path';
|
|
import { type Observable, from, mergeMap } from 'rxjs';
|
|
import { SernError } from './structures/errors';
|
|
import { type Result, Err, Ok } from 'ts-results-es';
|
|
import { ImportPayload } from '../types/handler';
|
|
import { pathToFileURL } from 'node:url';
|
|
|
|
// Courtesy @Townsy45
|
|
function readPath(dir: string, arrayOfFiles: string[] = []): string[] {
|
|
try {
|
|
const files = readdirSync(dir);
|
|
for (const file of files) {
|
|
if (statSync(dir + '/' + file).isDirectory()) readPath(dir + '/' + file, arrayOfFiles);
|
|
else arrayOfFiles.push(join(dir, '/', file));
|
|
}
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
|
|
return arrayOfFiles;
|
|
}
|
|
export const fmtFileName = (n: string) => n.substring(0, n.length - 3);
|
|
// export const isLazy = (n: string) => n.indexOf(".lazy.", n.length-9) !== -1;
|
|
|
|
export async function defaultModuleLoader<T>(
|
|
absPath: string,
|
|
): Promise<Result<ImportPayload<T>, SernError>> {
|
|
// prettier-ignore
|
|
let module: T | undefined
|
|
/// #if MODE === 'esm'
|
|
= (await import(pathToFileURL(absPath).toString())).default
|
|
/// #elif MODE === 'cjs'
|
|
= require(absPath).default; // eslint-disable-line
|
|
/// #endif
|
|
if (module === undefined) {
|
|
return Err(SernError.UndefinedModule);
|
|
}
|
|
try {
|
|
module = new (module as unknown as new () => T)();
|
|
} catch {}
|
|
return Ok({ module, absPath });
|
|
}
|
|
|
|
/**
|
|
* a directory string is converted into a stream of modules.
|
|
* starts the stream of modules that sern needs to process on init
|
|
* @returns {Observable<{ mod: Module; absPath: string; }[]>} data from command files
|
|
* @param commandDir
|
|
*/
|
|
export function buildModuleStream<T>(
|
|
commandDir: string,
|
|
): Observable<Result<ImportPayload<T>, SernError>> {
|
|
const commands = getCommands(commandDir);
|
|
return from(commands).pipe(mergeMap(defaultModuleLoader<T>));
|
|
}
|
|
|
|
export function getCommands(dir: string): string[] {
|
|
return readPath(join(process.cwd(), dir));
|
|
}
|
|
export function filename(path: string) {
|
|
return fmtFileName(basename(path))
|
|
}
|
|
//https://stackoverflow.com/questions/16697791/nodejs-get-filename-of-caller-function
|
|
export function filePath() {
|
|
const err = new Error();
|
|
|
|
Error.prepareStackTrace = (_, stack) => stack;
|
|
|
|
const stack = err.stack as unknown as NodeJS.CallSite[];
|
|
|
|
Error.prepareStackTrace = undefined;
|
|
const path = stack[2].getFileName();
|
|
if(path === null) {
|
|
throw Error("Could not get the name of commandModule.")
|
|
}
|
|
return path;
|
|
}
|