@majkapp/plugin-kit 1.0.7 → 1.0.8
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/plugin-kit.d.ts +12 -0
- package/dist/plugin-kit.d.ts.map +1 -1
- package/dist/plugin-kit.js +30 -8
- package/package.json +1 -1
package/dist/plugin-kit.d.ts
CHANGED
|
@@ -33,6 +33,18 @@ export interface FluentBuilder<Id extends string> {
|
|
|
33
33
|
onReady(fn: (ctx: PluginContext, cleanup: (fn: CleanupFn) => void) => void | Promise<void>): this;
|
|
34
34
|
/** Custom health check */
|
|
35
35
|
health(fn: HealthCheckFn): this;
|
|
36
|
+
/**
|
|
37
|
+
* Set the plugin root directory explicitly (use __dirname from your plugin entry file).
|
|
38
|
+
* This ensures plugin-kit can find your files in both local development and npm installed scenarios.
|
|
39
|
+
* If not provided, falls back to the pluginRoot from MAJK's context.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* const plugin = definePlugin('my-plugin', 'My Plugin', '1.0.0')
|
|
43
|
+
* .pluginRoot(__dirname) // Use Node's __dirname
|
|
44
|
+
* .ui({ appDir: 'dist' }) // Now resolves relative to __dirname
|
|
45
|
+
* .build();
|
|
46
|
+
*/
|
|
47
|
+
pluginRoot(dir: string): this;
|
|
36
48
|
/** Build the plugin */
|
|
37
49
|
build(): InProcessPlugin;
|
|
38
50
|
}
|
package/dist/plugin-kit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-kit.d.ts","sourceRoot":"","sources":["../src/plugin-kit.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,UAAU,EACV,SAAS,EACT,aAAa,EAIb,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin-kit.d.ts","sourceRoot":"","sources":["../src/plugin-kit.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,eAAe,EACf,QAAQ,EACR,WAAW,EACX,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,UAAU,EACV,SAAS,EACT,aAAa,EAIb,eAAe,EACf,gBAAgB,EACjB,MAAM,SAAS,CAAC;AA8qBjB;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,EAAE,SAAS,MAAM;IAC9C,mDAAmD;IACnD,MAAM,CAAC,KAAK,EAAE,mBAAmB,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAE7G,0CAA0C;IAC1C,EAAE,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAE5B,yBAAyB;IACzB,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAE3C,yBAAyB;IACzB,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAEzC,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAEnC,iBAAiB;IACjB,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAE/D,oEAAoE;IACpE,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAEtD,8DAA8D;IAC9D,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;IAE5C,+DAA+D;IAC/D,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAE9C,wBAAwB;IACxB,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAAC;IAEzC,0BAA0B;IAC1B,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAEjC,sCAAsC;IACtC,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAElG,0BAA0B;IAC1B,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAAC;IAEhC;;;;;;;;;;OAUG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B,uBAAuB;IACvB,KAAK,IAAI,eAAe,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAClD,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,EAAE,CAAC,CAkVnB"}
|
package/dist/plugin-kit.js
CHANGED
|
@@ -286,7 +286,7 @@ function serveSpa(ui, req, res, ctx) {
|
|
|
286
286
|
* Main plugin class built by the fluent API
|
|
287
287
|
*/
|
|
288
288
|
class BuiltPlugin {
|
|
289
|
-
constructor(id, name, version, capabilities, tools, apiRoutes, uiConfig, reactScreens, htmlScreens, wizard, onReadyFn, healthCheckFn) {
|
|
289
|
+
constructor(id, name, version, capabilities, tools, apiRoutes, uiConfig, reactScreens, htmlScreens, wizard, onReadyFn, healthCheckFn, userProvidedPluginRoot) {
|
|
290
290
|
this.capabilities = capabilities;
|
|
291
291
|
this.tools = tools;
|
|
292
292
|
this.apiRoutes = apiRoutes;
|
|
@@ -296,6 +296,7 @@ class BuiltPlugin {
|
|
|
296
296
|
this.wizard = wizard;
|
|
297
297
|
this.onReadyFn = onReadyFn;
|
|
298
298
|
this.healthCheckFn = healthCheckFn;
|
|
299
|
+
this.userProvidedPluginRoot = userProvidedPluginRoot;
|
|
299
300
|
this.cleanups = [];
|
|
300
301
|
this.router = [];
|
|
301
302
|
this.id = id;
|
|
@@ -334,27 +335,40 @@ class BuiltPlugin {
|
|
|
334
335
|
};
|
|
335
336
|
}
|
|
336
337
|
async onLoad(context) {
|
|
337
|
-
|
|
338
|
+
// Use user-provided pluginRoot (from __dirname) if available, otherwise fall back to context.pluginRoot
|
|
339
|
+
// The user-provided path comes from Node's __dirname which automatically resolves to the real directory
|
|
340
|
+
// (following symlinks), making it work correctly in both local development and npm installed scenarios
|
|
341
|
+
const effectivePluginRoot = this.userProvidedPluginRoot || context.pluginRoot;
|
|
342
|
+
this.context = {
|
|
343
|
+
...context,
|
|
344
|
+
pluginRoot: effectivePluginRoot
|
|
345
|
+
};
|
|
338
346
|
context.logger.info('═══════════════════════════════════════════════════════');
|
|
339
347
|
context.logger.info(`🚀 Loading Plugin: ${this.name} (${this.id}) v${this.version}`);
|
|
340
|
-
context.logger.info(`📍 Plugin Root: ${
|
|
348
|
+
context.logger.info(`📍 Plugin Root: ${effectivePluginRoot}`);
|
|
349
|
+
if (this.userProvidedPluginRoot) {
|
|
350
|
+
context.logger.info(` (user-provided via .pluginRoot(__dirname))`);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
context.logger.info(` (from MAJK context - consider using .pluginRoot(__dirname) for better reliability)`);
|
|
354
|
+
}
|
|
341
355
|
context.logger.info(`🌐 HTTP Port: ${context.http.port}`);
|
|
342
356
|
context.logger.info(`🔗 Base URL: ${context.http.baseUrl}`);
|
|
343
357
|
context.logger.info('═══════════════════════════════════════════════════════');
|
|
344
358
|
// Validate file paths now that we have pluginRoot context
|
|
345
359
|
if (this.reactScreens.length > 0 && this.uiConfig) {
|
|
346
|
-
const indexPath = path_1.default.join(context.pluginRoot, this.uiConfig.appDir || '', 'index.html');
|
|
360
|
+
const indexPath = path_1.default.join(this.context.pluginRoot, this.uiConfig.appDir || '', 'index.html');
|
|
347
361
|
if (!fs_1.default.existsSync(indexPath)) {
|
|
348
|
-
throw new PluginRuntimeError(`React app not built: ${indexPath} does not exist. Run "npm run build" in your UI directory to build the React app.`, 'onLoad', { appDir: this.uiConfig.appDir, indexPath, pluginRoot: context.pluginRoot });
|
|
362
|
+
throw new PluginRuntimeError(`React app not built: ${indexPath} does not exist. Run "npm run build" in your UI directory to build the React app.`, 'onLoad', { appDir: this.uiConfig.appDir, indexPath, pluginRoot: this.context.pluginRoot });
|
|
349
363
|
}
|
|
350
364
|
context.logger.info(`✅ React UI found at: ${indexPath}`);
|
|
351
365
|
}
|
|
352
366
|
// Validate HTML screen files
|
|
353
367
|
for (const screen of this.htmlScreens) {
|
|
354
368
|
if ('htmlFile' in screen) {
|
|
355
|
-
const filePath = path_1.default.join(context.pluginRoot, screen.htmlFile);
|
|
369
|
+
const filePath = path_1.default.join(this.context.pluginRoot, screen.htmlFile);
|
|
356
370
|
if (!fs_1.default.existsSync(filePath)) {
|
|
357
|
-
throw new PluginRuntimeError(`HTML screen file not found: ${screen.htmlFile}. Create the HTML file at ${filePath} or fix the path.`, 'onLoad', { screen: screen.id, file: screen.htmlFile, resolvedPath: filePath, pluginRoot: context.pluginRoot });
|
|
371
|
+
throw new PluginRuntimeError(`HTML screen file not found: ${screen.htmlFile}. Create the HTML file at ${filePath} or fix the path.`, 'onLoad', { screen: screen.id, file: screen.htmlFile, resolvedPath: filePath, pluginRoot: this.context.pluginRoot });
|
|
358
372
|
}
|
|
359
373
|
context.logger.info(`✅ HTML screen file found: ${screen.htmlFile}`);
|
|
360
374
|
}
|
|
@@ -601,6 +615,7 @@ function definePlugin(id, name, version) {
|
|
|
601
615
|
let _settings = null;
|
|
602
616
|
let _onReady = null;
|
|
603
617
|
let _healthCheck = null;
|
|
618
|
+
let _pluginRoot = undefined;
|
|
604
619
|
const builder = {
|
|
605
620
|
topbar(route, opts) {
|
|
606
621
|
_topbars.push({
|
|
@@ -718,6 +733,13 @@ function definePlugin(id, name, version) {
|
|
|
718
733
|
_healthCheck = fn;
|
|
719
734
|
return this;
|
|
720
735
|
},
|
|
736
|
+
pluginRoot(dir) {
|
|
737
|
+
if (!dir || typeof dir !== 'string') {
|
|
738
|
+
throw new PluginBuildError('pluginRoot must be a non-empty string', 'Pass __dirname from your plugin entry file: .pluginRoot(__dirname)', { provided: dir });
|
|
739
|
+
}
|
|
740
|
+
_pluginRoot = dir;
|
|
741
|
+
return this;
|
|
742
|
+
},
|
|
721
743
|
build() {
|
|
722
744
|
// ========== Build-Time Validation ==========
|
|
723
745
|
// Validate React UI setup
|
|
@@ -811,7 +833,7 @@ function definePlugin(id, name, version) {
|
|
|
811
833
|
// Return a class that instantiates BuiltPlugin
|
|
812
834
|
return class extends BuiltPlugin {
|
|
813
835
|
constructor() {
|
|
814
|
-
super(id, name, version, _capabilities, _tools, _apiRoutes, _uiConfigured ? _ui : null, _reactScreens, _htmlScreens, _wizard, _onReady, _healthCheck);
|
|
836
|
+
super(id, name, version, _capabilities, _tools, _apiRoutes, _uiConfigured ? _ui : null, _reactScreens, _htmlScreens, _wizard, _onReady, _healthCheck, _pluginRoot);
|
|
815
837
|
}
|
|
816
838
|
};
|
|
817
839
|
}
|