This repository has been archived by the owner on Dec 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
prebuild.js
127 lines (104 loc) · 4.84 KB
/
prebuild.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const fg = require('fast-glob');
const fs = require('fs');
const path = require('path');
const recast = require('recast');
const babelParser = require('recast/parsers/babel');
const builders = recast.types.builders;
function only(subject, props = []) {
const keys = Object.keys(subject);
const result = {};
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (props.includes(key)) {
result[key] = subject[key];
}
}
return result;
}
function getExtensions() {
return new Promise((resolve, reject) => {
const extensions = [];
const seenPackages = new Set();
return fg(['node_modules/*/package.json', 'node_modules/*/*/package.json'])
.then((results) => {
for (let i = 0; i < results.length; i++) {
const packagePath = results[i];
const packageJson = fs.readFileSync(packagePath);
let packageData = null;
try {
packageData = JSON.parse(packageJson);
} catch (e) {
console.warn(`Could not parse package.json at ${packagePath}:`, e);
continue;
}
if (!packageData || !packageData.keywords || !packageData.keywords.includes('fleetbase-extension') || !packageData.keywords.includes('ember-engine')) {
continue;
}
// If we've seen this package before, skip it
if (seenPackages.has(packageData.name)) {
continue;
}
seenPackages.add(packageData.name);
extensions.push(only(packageData, ['name', 'description', 'version', 'fleetbase', 'keywords', 'license', 'repository']));
}
resolve(extensions);
})
.catch(reject);
});
}
function getRouterFileContents() {
const routerFilePath = path.join(__dirname, 'router.map.js');
const routerFileContents = fs.readFileSync(routerFilePath, 'utf-8');
return routerFileContents;
}
(async () => {
const extensions = await getExtensions();
const routerFileContents = getRouterFileContents();
const ast = recast.parse(routerFileContents, { parser: babelParser });
recast.visit(ast, {
visitCallExpression(path) {
if (path.value.type === 'CallExpression' && path.value.callee.property.name === 'route' && path.value.arguments[0].value === 'console') {
let functionExpression;
// Find the function expression
path.value.arguments.forEach((arg) => {
if (arg.type === 'FunctionExpression') {
functionExpression = arg;
}
});
if (functionExpression) {
// Check and add the new engine mounts
extensions.forEach((extension) => {
const mountName = extension.name.split('/')[1];
const mountPath = mountName.replace('-engine', '');
let route = mountPath;
if (extension.fleetbase && extension.fleetbase.route) {
route = extension.fleetbase.route;
}
// Check if engine is already mounted
const isMounted = functionExpression.body.body.some((expressionStatement) => {
return expressionStatement.expression.arguments[0].value === extension.name;
});
// If not mounted, append to the function body
if (!isMounted) {
functionExpression.body.body.push(
builders.expressionStatement(
builders.callExpression(builders.memberExpression(builders.thisExpression(), builders.identifier('mount')), [
builders.literal(extension.name),
builders.objectExpression([
builders.property('init', builders.identifier('as'), builders.literal(route)),
builders.property('init', builders.identifier('path'), builders.literal(route)),
]),
])
)
);
}
});
return false;
}
}
this.traverse(path);
},
});
const output = recast.print(ast, { quote: 'single' }).code;
fs.writeFileSync(path.join(__dirname, 'app/router.js'), output);
})();