96 lines
2.5 KiB
JavaScript
96 lines
2.5 KiB
JavaScript
const glob = require('glob');
|
|
const {getOptions} = require('loader-utils');
|
|
const path = require('path');
|
|
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',
|
|
],
|
|
};
|
|
|
|
// Dynamically require all traits.
|
|
module.exports = function(source) {
|
|
const options = getOptions(this);
|
|
// Validate schema.
|
|
validateOptions(schema, options, 'Avocado defgen');
|
|
// Extract options.
|
|
const {classTransformer: transformer, paths, registrar, type} = options;
|
|
// Search avocado.
|
|
paths.push(path.resolve(
|
|
__dirname, 'node_modules', '@avocado',
|
|
));
|
|
// Get all trait source paths.
|
|
const sourcePaths = [];
|
|
paths.forEach((path) => {
|
|
const files = glob.sync(`${path}/**/*.${type}.js`, {
|
|
follow: true,
|
|
});
|
|
sourcePaths.push(...files);
|
|
});
|
|
// Build import definitions.
|
|
const importDefinitions = sourcePaths.map((sourcePath) => {
|
|
const relativePath = path.relative(__dirname, sourcePath);
|
|
const basename = path.basename(relativePath, `.${type}.js`);
|
|
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('/')}`
|
|
}
|
|
const importPath = `${importDirectory}/${basename}.${type}`;
|
|
// 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;
|
|
}, '');
|
|
const transformed = transformer ? transformer(className) : className;
|
|
// Import and register.
|
|
return [
|
|
`${registrar.function}(require('${importPath}').${transformed});`,
|
|
].join('\n');
|
|
});
|
|
// Import trait registry first.
|
|
const output = [
|
|
`import {${registrar.function}} from '${registrar.module}'`,
|
|
'',
|
|
...importDefinitions
|
|
].join('\n');
|
|
return output;
|
|
}
|