schemantic
Version:
A fully typed, extensible TypeScript type generator for FastAPI OpenAPI schemas
245 lines • 8.19 kB
JavaScript
;
/**
* Plugin loader for dynamic plugin loading
* Handles loading plugins from various sources (files, packages, etc.)
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.PluginLoader = void 0;
exports.loadPluginFromFile = loadPluginFromFile;
exports.loadPluginFromPackage = loadPluginFromPackage;
exports.loadPluginsFromDirectory = loadPluginsFromDirectory;
const fs = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
/**
* Plugin loader class
*/
class PluginLoader {
constructor() {
this.loadedPlugins = new Map();
}
/**
* Load plugin from file path
*/
async loadPluginFromFile(filePath) {
try {
// Check if file exists
await fs.access(filePath);
// Load the module
const pluginModule = await Promise.resolve(`${path.resolve(filePath)}`).then(s => __importStar(require(s)));
// Extract plugin from module
const plugin = this.extractPluginFromModule(pluginModule);
if (!plugin) {
throw new Error(`No valid plugin found in ${filePath}`);
}
// Validate plugin
this.validatePlugin(plugin);
// Store loaded plugin
this.loadedPlugins.set(plugin.name, plugin);
return plugin;
}
catch (error) {
throw new Error(`Failed to load plugin from ${filePath}: ${error}`);
}
}
/**
* Load plugin from package
*/
async loadPluginFromPackage(packageName) {
try {
// Load the package
const pluginModule = await Promise.resolve(`${packageName}`).then(s => __importStar(require(s)));
// Extract plugin from module
const plugin = this.extractPluginFromModule(pluginModule);
if (!plugin) {
throw new Error(`No valid plugin found in package ${packageName}`);
}
// Validate plugin
this.validatePlugin(plugin);
// Store loaded plugin
this.loadedPlugins.set(plugin.name, plugin);
return plugin;
}
catch (error) {
throw new Error(`Failed to load plugin from package ${packageName}: ${error}`);
}
}
/**
* Load plugins from directory
*/
async loadPluginsFromDirectory(directoryPath) {
try {
const plugins = [];
// Read directory contents
const entries = await fs.readdir(directoryPath, { withFileTypes: true });
for (const entry of entries) {
if (entry.isFile() &&
(entry.name.endsWith(".js") || entry.name.endsWith(".ts"))) {
const filePath = path.join(directoryPath, entry.name);
try {
const plugin = await this.loadPluginFromFile(filePath);
plugins.push(plugin);
}
catch (error) {
console.warn(`Failed to load plugin from ${filePath}:`, error);
}
}
}
return plugins;
}
catch (error) {
throw new Error(`Failed to load plugins from directory ${directoryPath}: ${error}`);
}
}
/**
* Load plugin from object
*/
loadPluginFromObject(plugin) {
// Validate plugin
this.validatePlugin(plugin);
// Store loaded plugin
this.loadedPlugins.set(plugin.name, plugin);
return plugin;
}
/**
* Extract plugin from module
*/
extractPluginFromModule(module) {
// Try different export patterns
if (typeof module === "object" &&
module !== null &&
"default" in module &&
this.isValidPlugin(module.default)) {
return module.default;
}
if (typeof module === "object" &&
module !== null &&
"plugin" in module &&
this.isValidPlugin(module.plugin)) {
return module.plugin;
}
if (this.isValidPlugin(module)) {
return module;
}
// Look for plugin in exports
if (typeof module === "object" && module !== null) {
for (const [, value] of Object.entries(module)) {
if (this.isValidPlugin(value)) {
return value;
}
}
}
return undefined;
}
/**
* Check if object is a valid plugin
*/
isValidPlugin(obj) {
if (!obj || typeof obj !== "object")
return false;
const maybe = obj;
return (typeof maybe.name === "string" &&
typeof maybe.version === "string" &&
typeof maybe.description === "string");
}
/**
* Validate plugin
*/
validatePlugin(plugin) {
if (!plugin.name || typeof plugin.name !== "string") {
throw new Error("Plugin must have a valid name");
}
if (!plugin.version || typeof plugin.version !== "string") {
throw new Error("Plugin must have a valid version");
}
if (!plugin.description || typeof plugin.description !== "string") {
throw new Error("Plugin must have a valid description");
}
// Check for duplicate names
if (this.loadedPlugins.has(plugin.name)) {
throw new Error(`Plugin with name '${plugin.name}' is already loaded`);
}
}
/**
* Get loaded plugin
*/
getLoadedPlugin(name) {
return this.loadedPlugins.get(name);
}
/**
* Get all loaded plugins
*/
getAllLoadedPlugins() {
return Array.from(this.loadedPlugins.values());
}
/**
* Clear loaded plugins
*/
clear() {
this.loadedPlugins.clear();
}
/**
* Get loading statistics
*/
getStatistics() {
return {
loadedPlugins: this.loadedPlugins.size,
pluginNames: Array.from(this.loadedPlugins.keys()),
};
}
}
exports.PluginLoader = PluginLoader;
/**
* Convenience function to load plugin from file
*/
async function loadPluginFromFile(filePath) {
const loader = new PluginLoader();
return loader.loadPluginFromFile(filePath);
}
/**
* Convenience function to load plugin from package
*/
async function loadPluginFromPackage(packageName) {
const loader = new PluginLoader();
return loader.loadPluginFromPackage(packageName);
}
/**
* Convenience function to load plugins from directory
*/
async function loadPluginsFromDirectory(directoryPath) {
const loader = new PluginLoader();
return loader.loadPluginsFromDirectory(directoryPath);
}
//# sourceMappingURL=loader.js.map