@yumerijs/loader 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -0
- package/dist/index.js +71 -23
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,14 @@ interface Plugin {
|
|
|
7
7
|
render?: string;
|
|
8
8
|
config?: Schema<any>;
|
|
9
9
|
}
|
|
10
|
+
export interface PluginConfigEntry {
|
|
11
|
+
id: string;
|
|
12
|
+
moduleName: string;
|
|
13
|
+
config: any;
|
|
14
|
+
configKey: string;
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
legacy: boolean;
|
|
17
|
+
}
|
|
10
18
|
export declare class PluginLoader {
|
|
11
19
|
private pluginsDir;
|
|
12
20
|
core: Core;
|
|
@@ -25,6 +33,13 @@ export declare class PluginLoader {
|
|
|
25
33
|
private pluginContexts;
|
|
26
34
|
private isDev;
|
|
27
35
|
constructor(core?: Core, pluginsDir?: string);
|
|
36
|
+
/**
|
|
37
|
+
* Normalize both the legacy `{ "package-name": { ...config } }` form and
|
|
38
|
+
* the named instance form `{ "instance-id": { module, config } }`.
|
|
39
|
+
*/
|
|
40
|
+
getPluginEntry(pluginId: string): PluginConfigEntry | undefined;
|
|
41
|
+
setPluginConfig(pluginId: string, config: any): boolean;
|
|
42
|
+
private getEnabledPluginEntries;
|
|
28
43
|
/**
|
|
29
44
|
* Reloads the config file from disk into memory and emits a 'config-reloaded' event.
|
|
30
45
|
* This does NOT reload any plugins.
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,55 @@ export class PluginLoader {
|
|
|
25
25
|
this.isDev = process.env.NODE_ENV === 'development';
|
|
26
26
|
Logger.setCore(this.core);
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Normalize both the legacy `{ "package-name": { ...config } }` form and
|
|
30
|
+
* the named instance form `{ "instance-id": { module, config } }`.
|
|
31
|
+
*/
|
|
32
|
+
getPluginEntry(pluginId) {
|
|
33
|
+
const plugins = this.config?.plugins;
|
|
34
|
+
if (!plugins || typeof plugins !== 'object')
|
|
35
|
+
return undefined;
|
|
36
|
+
const configKey = Object.prototype.hasOwnProperty.call(plugins, pluginId)
|
|
37
|
+
? pluginId
|
|
38
|
+
: Object.prototype.hasOwnProperty.call(plugins, `~${pluginId}`)
|
|
39
|
+
? `~${pluginId}`
|
|
40
|
+
: undefined;
|
|
41
|
+
if (!configKey)
|
|
42
|
+
return undefined;
|
|
43
|
+
const enabled = !configKey.startsWith('~');
|
|
44
|
+
const id = enabled ? configKey : configKey.substring(1);
|
|
45
|
+
const value = plugins[configKey];
|
|
46
|
+
const isInstance = value && typeof value === 'object' && !Array.isArray(value)
|
|
47
|
+
&& typeof value.module === 'string';
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
moduleName: isInstance ? value.module : id,
|
|
51
|
+
config: isInstance ? (value.config ?? {}) : (value ?? {}),
|
|
52
|
+
configKey,
|
|
53
|
+
enabled,
|
|
54
|
+
legacy: !isInstance,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
setPluginConfig(pluginId, config) {
|
|
58
|
+
const entry = this.getPluginEntry(pluginId);
|
|
59
|
+
if (!entry)
|
|
60
|
+
return false;
|
|
61
|
+
if (entry.legacy) {
|
|
62
|
+
this.config.plugins[entry.configKey] = config;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.config.plugins[entry.configKey].config = config;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
getEnabledPluginEntries() {
|
|
70
|
+
if (!this.config || typeof this.config.plugins !== 'object' || this.config.plugins === null) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
return Object.keys(this.config.plugins)
|
|
74
|
+
.map(key => this.getPluginEntry(key.startsWith('~') ? key.substring(1) : key))
|
|
75
|
+
.filter(entry => entry && entry.enabled);
|
|
76
|
+
}
|
|
28
77
|
/**
|
|
29
78
|
* Reloads the config file from disk into memory and emits a 'config-reloaded' event.
|
|
30
79
|
* This does NOT reload any plugins.
|
|
@@ -84,18 +133,14 @@ export class PluginLoader {
|
|
|
84
133
|
this.logger.info('No plugins configuration found. No plugins to load.');
|
|
85
134
|
return;
|
|
86
135
|
}
|
|
87
|
-
const
|
|
136
|
+
const allEntries = Object.keys(this.config.plugins)
|
|
137
|
+
.map(key => this.getPluginEntry(key.startsWith('~') ? key.substring(1) : key))
|
|
138
|
+
.filter(Boolean);
|
|
88
139
|
this.pluginStatus = {}; // Reset status
|
|
89
|
-
for (const
|
|
90
|
-
|
|
91
|
-
const actualName = name.substring(1);
|
|
92
|
-
this.pluginStatus[actualName] = "disabled" /* PluginStatus.DISABLED */;
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
this.pluginStatus[name] = "pending" /* PluginStatus.PENDING */;
|
|
96
|
-
}
|
|
140
|
+
for (const entry of allEntries) {
|
|
141
|
+
this.pluginStatus[entry.id] = entry.enabled ? "pending" /* PluginStatus.PENDING */ : "disabled" /* PluginStatus.DISABLED */;
|
|
97
142
|
}
|
|
98
|
-
const enabledPlugins =
|
|
143
|
+
const enabledPlugins = allEntries.filter(entry => entry.enabled).map(entry => entry.id);
|
|
99
144
|
const currentlyLoaded = Object.keys(this.plugins);
|
|
100
145
|
for (const loadedName of currentlyLoaded) {
|
|
101
146
|
if (!enabledPlugins.includes(loadedName)) {
|
|
@@ -170,13 +215,13 @@ export class PluginLoader {
|
|
|
170
215
|
return false;
|
|
171
216
|
}
|
|
172
217
|
this.plugins[pluginName] = pluginInstance;
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
218
|
+
const entry = this.getPluginEntry(pluginName);
|
|
219
|
+
if (!entry) {
|
|
220
|
+
throw new Error(`Plugin configuration not found for instance "${pluginName}".`);
|
|
221
|
+
}
|
|
222
|
+
const schema = pluginInstance.config || Schema.object({});
|
|
223
|
+
const finalConfig = fallback(schema, entry.config);
|
|
224
|
+
this.setPluginConfig(pluginName, finalConfig);
|
|
180
225
|
const context = this.getContext(pluginName, {});
|
|
181
226
|
if (pluginInstance.render) {
|
|
182
227
|
context.renderer = this.core.renderers.get(pluginInstance.render || '');
|
|
@@ -188,14 +233,15 @@ export class PluginLoader {
|
|
|
188
233
|
}
|
|
189
234
|
if (this.isDev) {
|
|
190
235
|
let pluginPathToWatch = null;
|
|
236
|
+
const moduleName = entry.moduleName;
|
|
191
237
|
try {
|
|
192
|
-
const packageJsonUrl = import.meta.resolve(`${
|
|
238
|
+
const packageJsonUrl = import.meta.resolve(`${moduleName}/package.json`);
|
|
193
239
|
const pkgJsonPath = fileURLToPath(packageJsonUrl);
|
|
194
240
|
pluginPathToWatch = path.dirname(pkgJsonPath);
|
|
195
241
|
}
|
|
196
242
|
catch (e) {
|
|
197
|
-
const localPluginPath = path.resolve(process.cwd(),
|
|
198
|
-
const localPluginPathInPlugins = path.resolve(process.cwd(), 'plugins',
|
|
243
|
+
const localPluginPath = path.resolve(process.cwd(), moduleName);
|
|
244
|
+
const localPluginPathInPlugins = path.resolve(process.cwd(), 'plugins', moduleName);
|
|
199
245
|
if (fs.existsSync(localPluginPath)) {
|
|
200
246
|
pluginPathToWatch = localPluginPath;
|
|
201
247
|
}
|
|
@@ -315,10 +361,12 @@ export class PluginLoader {
|
|
|
315
361
|
this.pluginWatchers[pluginName] = watcher;
|
|
316
362
|
}
|
|
317
363
|
async loadModule(pluginName) {
|
|
318
|
-
const
|
|
364
|
+
const entry = this.getPluginEntry(pluginName);
|
|
365
|
+
if (!entry)
|
|
366
|
+
throw new Error(`Plugin configuration not found for instance "${pluginName}".`);
|
|
367
|
+
const pluginModule = await import(entry.moduleName);
|
|
319
368
|
const context = this.getContext(pluginName, {});
|
|
320
|
-
|
|
321
|
-
return resolvePluginModule(pluginModule, context, rawConfig);
|
|
369
|
+
return resolvePluginModule(pluginModule, context, entry.config);
|
|
322
370
|
}
|
|
323
371
|
async checkPluginDependencies(pluginPath) {
|
|
324
372
|
return true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yumerijs/loader",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Module loader for yumeri",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/js-yaml": "^4.0.9",
|
|
31
31
|
"@types/node": "^22.13.10",
|
|
32
|
-
"@yumerijs/core": "^3.0.
|
|
32
|
+
"@yumerijs/core": "^3.0.5",
|
|
33
33
|
"esbuild-register": "^3.6.0",
|
|
34
34
|
"typescript": "^6.0.3"
|
|
35
35
|
},
|
|
@@ -41,6 +41,6 @@
|
|
|
41
41
|
"js-yaml": "^4.1.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@yumerijs/core": "^3.0.
|
|
44
|
+
"@yumerijs/core": "^3.0.5"
|
|
45
45
|
}
|
|
46
46
|
}
|