mirror of
https://github.com/fleetbase/fleetbase.git
synced 2025-12-19 14:18:57 +00:00
fix: Router generation and add file watching for extension changes
**Router Generation Fixes:**
- Fix router.js parsing (was looking for non-existent router.map.js)
- Parse Router.map(function() {...}) structure correctly
- Fix console route detection (check for path: '/' config)
- Fix function expression location (3rd arg after path config)
- Fix root extensions to use this.mount() not router.mount()
**File Watching:**
- Add chokidar to watch extension.js files in development
- Regenerate shims and loaders when extension.js changes
- Cache discovered extensions for regeneration
- Only watch in development mode
**Issues Fixed:**
1. Router.js now properly contains engine mounts
2. Extension.js changes trigger automatic regeneration
This commit is contained in:
@@ -24,19 +24,72 @@ module.exports = {
|
||||
console.log('[fleetbase-extensions-generator] included() hook called');
|
||||
console.log('[fleetbase-extensions-generator] Project root:', this.project.root);
|
||||
|
||||
// Discover extensions
|
||||
const extensions = this.discoverExtensions();
|
||||
console.log('[fleetbase-extensions-generator] Found', extensions.length, 'extension(s)');
|
||||
// Discover extensions and cache them
|
||||
this._extensions = this.discoverExtensions();
|
||||
console.log('[fleetbase-extensions-generator] Found', this._extensions.length, 'extension(s)');
|
||||
|
||||
// Generate files directly to app directory
|
||||
this.generateExtensionShims(extensions);
|
||||
this.generateExtensionLoaders(extensions);
|
||||
this.generateRouter(extensions);
|
||||
this.generateExtensionsManifest(extensions);
|
||||
this.generateExtensionShims(this._extensions);
|
||||
this.generateExtensionLoaders(this._extensions);
|
||||
this.generateRouter(this._extensions);
|
||||
this.generateExtensionsManifest(this._extensions);
|
||||
|
||||
// Set up file watching for extension.js files
|
||||
this.setupFileWatching();
|
||||
|
||||
console.log('[fleetbase-extensions-generator] ========================================');
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up file watching for extension.js files to regenerate on changes
|
||||
*/
|
||||
setupFileWatching() {
|
||||
if (this.app.env !== 'development') {
|
||||
return; // Only watch in development
|
||||
}
|
||||
|
||||
const chokidar = require('chokidar');
|
||||
const extensionPaths = [];
|
||||
|
||||
// Collect all extension.js file paths
|
||||
for (const extension of this._extensions) {
|
||||
const extensionPath = path.join(
|
||||
this.project.root,
|
||||
'node_modules',
|
||||
extension.name,
|
||||
'addon',
|
||||
'extension.js'
|
||||
);
|
||||
|
||||
if (fs.existsSync(extensionPath)) {
|
||||
extensionPaths.push(extensionPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (extensionPaths.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[fleetbase-extensions-generator] Watching', extensionPaths.length, 'extension file(s) for changes');
|
||||
|
||||
// Watch extension files
|
||||
const watcher = chokidar.watch(extensionPaths, {
|
||||
persistent: true,
|
||||
ignoreInitial: true
|
||||
});
|
||||
|
||||
watcher.on('change', (changedPath) => {
|
||||
console.log('[fleetbase-extensions-generator] Extension file changed:', changedPath);
|
||||
console.log('[fleetbase-extensions-generator] Regenerating extension files...');
|
||||
|
||||
// Regenerate all extension files
|
||||
this.generateExtensionShims(this._extensions);
|
||||
this.generateExtensionLoaders(this._extensions);
|
||||
|
||||
console.log('[fleetbase-extensions-generator] ✓ Regeneration complete');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Discover Fleetbase extensions from node_modules
|
||||
*/
|
||||
@@ -223,16 +276,15 @@ ${extensionCode}
|
||||
generateRouter(extensions) {
|
||||
console.log('[fleetbase-extensions-generator] Generating router.js...');
|
||||
|
||||
const routerMapFile = path.join(this.project.root, 'app', 'router.map.js');
|
||||
const routerFile = path.join(this.project.root, 'app', 'router.js');
|
||||
|
||||
if (!fs.existsSync(routerMapFile)) {
|
||||
console.error('[fleetbase-extensions-generator] ! router.map.js not found at:', routerMapFile);
|
||||
if (!fs.existsSync(routerFile)) {
|
||||
console.error('[fleetbase-extensions-generator] ! router.js not found at:', routerFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read router.map.js
|
||||
const routerMapContent = fs.readFileSync(routerMapFile, 'utf8');
|
||||
// Read router.js
|
||||
const routerContent = fs.readFileSync(routerFile, 'utf8');
|
||||
|
||||
// Separate extensions by mount location
|
||||
const consoleExtensions = [];
|
||||
@@ -257,7 +309,7 @@ ${extensionCode}
|
||||
const recast = require('recast');
|
||||
const babelParser = require('recast/parsers/babel');
|
||||
|
||||
const ast = recast.parse(routerMapContent, { parser: babelParser });
|
||||
const ast = recast.parse(routerContent, { parser: babelParser });
|
||||
|
||||
let consoleAdded = 0;
|
||||
let rootAdded = 0;
|
||||
@@ -300,17 +352,25 @@ ${extensionCode}
|
||||
visitCallExpression(path) {
|
||||
const node = path.node;
|
||||
|
||||
// Look for this.route('console', ...)
|
||||
// Look for this.route('console', ...) with path: '/'
|
||||
if (n.MemberExpression.check(node.callee) &&
|
||||
n.ThisExpression.check(node.callee.object) &&
|
||||
node.callee.property.name === 'route' &&
|
||||
node.arguments.length > 0 &&
|
||||
n.Literal.check(node.arguments[0]) &&
|
||||
node.arguments[0].value === 'console') {
|
||||
node.arguments[0].value === 'console' &&
|
||||
node.arguments.length > 1 &&
|
||||
n.ObjectExpression.check(node.arguments[1]) &&
|
||||
node.arguments[1].properties.some(p =>
|
||||
n.Property.check(p) &&
|
||||
p.key.name === 'path' &&
|
||||
n.Literal.check(p.value) &&
|
||||
p.value.value === '/'
|
||||
)) {
|
||||
|
||||
// Find the function expression in the second argument
|
||||
if (node.arguments.length > 1 && n.FunctionExpression.check(node.arguments[1])) {
|
||||
const functionExpression = node.arguments[1];
|
||||
// Find the function expression in the third argument (after path config)
|
||||
if (node.arguments.length > 2 && n.FunctionExpression.check(node.arguments[2])) {
|
||||
const functionExpression = node.arguments[2];
|
||||
|
||||
// Add mount statements for each extension
|
||||
extensions.forEach(extension => {
|
||||
@@ -359,12 +419,18 @@ ${extensionCode}
|
||||
let addedCount = 0;
|
||||
|
||||
types.visit(ast, {
|
||||
visitExportDefaultDeclaration(path) {
|
||||
visitCallExpression(path) {
|
||||
const node = path.node;
|
||||
|
||||
// Look for export default function(router) { ... }
|
||||
if (n.FunctionExpression.check(node.declaration)) {
|
||||
const functionExpression = node.declaration;
|
||||
// Look for Router.map(function() { ... })
|
||||
if (n.MemberExpression.check(node.callee) &&
|
||||
n.Identifier.check(node.callee.object) &&
|
||||
node.callee.object.name === 'Router' &&
|
||||
node.callee.property.name === 'map' &&
|
||||
node.arguments.length > 0 &&
|
||||
n.FunctionExpression.check(node.arguments[0])) {
|
||||
|
||||
const functionExpression = node.arguments[0];
|
||||
|
||||
// Add mount statements for each root extension
|
||||
extensions.forEach(extension => {
|
||||
@@ -373,7 +439,7 @@ ${extensionCode}
|
||||
const mountStatement = b.expressionStatement(
|
||||
b.callExpression(
|
||||
b.memberExpression(
|
||||
b.identifier('router'),
|
||||
b.thisExpression(),
|
||||
b.identifier('mount')
|
||||
),
|
||||
[
|
||||
@@ -392,6 +458,9 @@ ${extensionCode}
|
||||
|
||||
return false; // Don't traverse children
|
||||
}
|
||||
|
||||
return false; // Don't traverse children
|
||||
}
|
||||
|
||||
this.traverse(path);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
"broccoli-file-creator": "^2.1.1",
|
||||
"broccoli-funnel": "^3.0.8",
|
||||
"broccoli-merge-trees": "^4.2.0",
|
||||
"chokidar": "^5.0.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"date-fns": "^2.30.0",
|
||||
"dragula": "^3.7.3",
|
||||
|
||||
17
console/pnpm-lock.yaml
generated
17
console/pnpm-lock.yaml
generated
@@ -149,6 +149,9 @@ importers:
|
||||
broccoli-merge-trees:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0
|
||||
chokidar:
|
||||
specifier: ^5.0.0
|
||||
version: 5.0.0
|
||||
concurrently:
|
||||
specifier: ^8.2.2
|
||||
version: 8.2.2
|
||||
@@ -2467,6 +2470,10 @@ packages:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
|
||||
chokidar@5.0.0:
|
||||
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
chrome-trace-event@1.0.4:
|
||||
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -6021,6 +6028,10 @@ packages:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
||||
readdirp@5.0.0:
|
||||
resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
recast@0.18.10:
|
||||
resolution: {integrity: sha512-XNvYvkfdAN9QewbrxeTOjgINkdY/odTgTS56ZNEWL9Ml0weT4T3sFtvnTuF+Gxyu46ANcRm1ntrF6F5LAJPAaQ==}
|
||||
engines: {node: '>= 4'}
|
||||
@@ -10290,6 +10301,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
chokidar@5.0.0:
|
||||
dependencies:
|
||||
readdirp: 5.0.0
|
||||
|
||||
chrome-trace-event@1.0.4: {}
|
||||
|
||||
ci-info@3.9.0: {}
|
||||
@@ -14615,6 +14630,8 @@ snapshots:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
||||
readdirp@5.0.0: {}
|
||||
|
||||
recast@0.18.10:
|
||||
dependencies:
|
||||
ast-types: 0.13.3
|
||||
|
||||
Reference in New Issue
Block a user