@storm-stack/plugin-system
Version:
A library used to create and manage a plugin-styled architecture in a TypeScript application.
84 lines (83 loc) • 2.62 kB
JavaScript
import { StormError } from "@storm-stack/errors";
import { joinPaths, loadTsConfigFile } from "@storm-stack/file-system";
import { isString } from "@storm-stack/types";
import { CachedInputFileSystem, ResolverFactory } from "enhanced-resolve";
import fs from "node:fs";
import { PluginSystemErrorCode } from "../errors.mjs";
import { install } from "./run.mjs";
export const createResolver = (rootPath = __dirname, tsconfig = "tsconfig.json", autoInstall = true) => {
const tsconfigJson = loadTsConfigFile(
tsconfig.includes(rootPath) ? tsconfig : joinPaths(rootPath, tsconfig)
);
const resolverFactory = ResolverFactory.createResolver({
alias: tsconfigJson?.data?.compilerOptions?.paths,
fileSystem: new CachedInputFileSystem(fs, 4e3),
extensions: [
".js",
".cjs",
".mjs",
".jsx",
".json",
".node",
".ts",
".tsx"
],
mainFields: ["main", "module"],
mainFiles: ["index"],
descriptionFiles: ["package.json"]
});
return (request) => {
const resolveContext = {
issuer: rootPath
};
return new Promise((resolve, reject) => {
resolverFactory.resolve(
resolveContext,
rootPath,
request,
{},
(error, result) => {
if (error || !result || !isString(result)) {
if (autoInstall) {
install(request, rootPath).then(() => {
resolverFactory.resolve(
resolveContext,
rootPath,
request,
{},
(innerError, innerResult) => {
if (innerError) {
reject(innerError);
} else if (!innerResult || !isString(innerResult)) {
reject(
StormError.create({
code: PluginSystemErrorCode.module_not_found,
message: `Cannot find plugin ${request}`
})
);
} else {
resolve(innerResult);
}
}
);
resolve(result);
});
}
if (error) {
reject(error);
} else {
reject(
StormError.create({
code: PluginSystemErrorCode.module_not_found,
message: `Cannot find plugin ${request}`
})
);
}
} else {
resolve(result);
}
}
);
});
};
};