forked from plone/volto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
create-addons-loader.js
113 lines (99 loc) · 2.98 KB
/
create-addons-loader.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
const fs = require('fs');
const tmp = require('tmp');
const cryptoRandomString = require('crypto-random-string');
const titleCase = (w) => w.slice(0, 1).toUpperCase() + w.slice(1, w.length);
/*
* Transforms a package name to javascript variable name
*/
function nameFromPackage(name) {
name =
name.replace(/[@~./\\:\s]/gi, '') ||
cryptoRandomString({ length: 10, characters: 'abcdefghijk' });
return name
.split('-')
.map((w, i) => (i > 0 ? titleCase(w) : w))
.join('');
}
/*
* Creates a static file with code necessary to load the addons configuration
*
*/
function getAddonsLoaderCode(addons = [], addonsInfo) {
let buf = `/*
This file is autogenerated. Don't change it directly.
Instead, change the "addons" setting in your package.json file.
*/
const projectConfigLoader = require('@root/config');
`;
let configsToLoad = [],
counter = 0;
addons.forEach((addonConfigString) => {
let extras = [];
const addonConfigLoadInfo = addonConfigString.split(':');
const pkgName = addonConfigLoadInfo[0];
const defaultImport = nameFromPackage(pkgName);
if (addonConfigLoadInfo.length > 1) {
extras = addonConfigLoadInfo[1].split(',');
}
extras = extras.map((name) => [name, `${name}${counter++}`]);
const line = `import ${defaultImport}${
extras.length
? `, { ${extras
.map((ex) => {
return `${ex[0]} as ${ex[1]}`;
})
.join(', ')} }`
: ''
} from '${pkgName}';\n`;
buf += line;
configsToLoad = [
...configsToLoad,
defaultImport,
...extras.map((ex) => ex[1]),
];
});
buf += `
${
addonsInfo
? `const addonsInfo = ${JSON.stringify(addonsInfo)}`
: 'const addonsInfo = {}'
};
export { addonsInfo };
`;
buf += `
const safeWrapper = (func) => (config) => {
const res = func(config);
if (typeof res === 'undefined') {
throw new Error("Configuration function doesn't return config");
}
return res;
}
const projectConfig = (config) => {
return typeof projectConfigLoader.default === "function" ? projectConfigLoader.default(config) : config;
}
const load = (config) => {
const addonLoaders = [${configsToLoad.join(', ')}];
if(!addonLoaders.every((el) => typeof el === "function")) {
throw new TypeError(
'Each addon has to provide a function applying its configuration to the projects configuration.',
);
}
return projectConfig(addonLoaders.reduce((acc, apply) => safeWrapper(apply)(acc), config));
};
export default load;
`;
return buf;
}
module.exports = (addons, addonsInfo) => {
// const addonsLoaderPath = path.join(
// process.cwd(),
// 'src',
// 'load-volto-addons.js',
// );
const addonsLoaderPath = tmp.tmpNameSync({ postfix: '.js' });
const code = getAddonsLoaderCode(addons, addonsInfo);
fs.writeFileSync(addonsLoaderPath, new Buffer.from(code));
return addonsLoaderPath;
};
module.exports.getAddonsLoaderCode = getAddonsLoaderCode;
module.exports.nameFromPackage = nameFromPackage;