humus-old/defgen.js

96 lines
2.5 KiB
JavaScript
Raw Normal View History

2019-03-20 22:45:57 -05:00
const glob = require('glob');
2019-04-14 20:10:44 -05:00
const {getOptions} = require('loader-utils');
const path = require('path');
2019-04-14 21:06:58 -05:00
const validateOptions = require('schema-utils');
const schema = {
type: 'object',
properties: {
paths: {
items: {
type: 'string',
},
type: 'array',
},
registrar: {
type: 'object',
properties: {
function: {
type: 'string',
},
module: {
type: 'string',
},
},
required: [
'function',
'module',
],
},
type: {
type: 'string',
},
},
required: [
'registrar',
'type',
],
};
2019-03-20 22:45:57 -05:00
// Dynamically require all traits.
2019-04-14 20:10:44 -05:00
module.exports = function(source) {
const options = getOptions(this);
2019-04-14 21:06:58 -05:00
// Validate schema.
validateOptions(schema, options, 'Avocado defgen');
// Extract options.
2019-04-14 21:32:48 -05:00
const {classTransformer: transformer, paths, registrar, type} = options;
2019-04-14 20:10:44 -05:00
// Search avocado.
2019-04-14 21:32:48 -05:00
paths.push(path.resolve(
2019-04-14 20:10:44 -05:00
__dirname, 'node_modules', '@avocado',
));
// Get all trait source paths.
const sourcePaths = [];
2019-04-14 21:06:58 -05:00
paths.forEach((path) => {
const files = glob.sync(`${path}/**/*.${type}.js`, {
2019-04-14 20:10:44 -05:00
follow: true,
2019-03-20 22:45:57 -05:00
});
2019-04-14 20:10:44 -05:00
sourcePaths.push(...files);
});
// Build import definitions.
const importDefinitions = sourcePaths.map((sourcePath) => {
const relativePath = path.relative(__dirname, sourcePath);
2019-04-14 21:06:58 -05:00
const basename = path.basename(relativePath, `.${type}.js`);
2019-04-14 20:10:44 -05:00
const parts = relativePath.split('/');
// Chop off basename.
parts.pop();
// Module or local?
let importDirectory;
if ('node_modules' === parts[0]) {
importDirectory = `${parts.slice(1).join('/')}`;
}
else {
importDirectory = `./${parts.join('/')}`
}
2019-04-14 21:06:58 -05:00
const importPath = `${importDirectory}/${basename}.${type}`;
2019-04-14 20:10:44 -05:00
// Extract class name.
const baseparts = basename.split('-');
const className = baseparts.reduce((className, part) => {
const firstLetter = part.charAt(0).toUpperCase();
const rest = part.substr(1).toLowerCase();
return className + firstLetter + rest;
}, '');
2019-04-14 21:32:48 -05:00
const transformed = transformer ? transformer(className) : className;
2019-04-14 20:10:44 -05:00
// Import and register.
return [
2019-04-25 00:00:34 -05:00
`${registrar.function}(require('${importPath}').${transformed});`,
2019-04-14 20:10:44 -05:00
].join('\n');
2019-03-20 22:45:57 -05:00
});
2019-04-14 20:10:44 -05:00
// Import trait registry first.
2019-04-14 21:32:48 -05:00
const output = [
2019-04-14 21:06:58 -05:00
`import {${registrar.function}} from '${registrar.module}'`,
2019-04-14 20:10:44 -05:00
'',
...importDefinitions
].join('\n');
2019-04-14 21:32:48 -05:00
return output;
2019-03-20 22:45:57 -05:00
}