107 lines
3.9 KiB
JavaScript
107 lines
3.9 KiB
JavaScript
/**
|
|
* @author Adrien Foulon <tofandel@tukan.hu>
|
|
*/
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const util = require('util');
|
|
|
|
const InjectPlugin = require('@bpnetguy/webpack-inject-plugin').default;
|
|
|
|
const execFile = util.promisify(require('child_process').execFile);
|
|
const readFile = util.promisify(fs.readFile);
|
|
const rmFile = util.promisify(fs.rm);
|
|
const writeFile = util.promisify(fs.writeFile);
|
|
const makeDir = util.promisify(fs.mkdir)
|
|
|
|
class FosRouting {
|
|
default = {
|
|
locale: '',
|
|
prettyPrint: false,
|
|
domain: [],
|
|
php: 'php'
|
|
};
|
|
|
|
constructor(options = {}, registerCompileHooks = true) {
|
|
this.options = Object.assign({target: 'var/cache/fosRoutes.json'}, this.default, options, {format: 'json'});
|
|
this.finalTarget = path.resolve(process.cwd(), this.options.target);
|
|
this.options.target = path.resolve(process.cwd(), this.options.target.replace(/\.json$/, '.tmp.json'));
|
|
|
|
if (this.options.target === this.finalTarget) {
|
|
this.options.target += '.tmp';
|
|
}
|
|
this.registerCompileHooks = registerCompileHooks;
|
|
}
|
|
|
|
// Values don't need to be escaped because node already does that
|
|
shellArg(key, value) {
|
|
key = this.kebabize(key);
|
|
return typeof value === 'boolean' ? (value ? '--' + key : '') : '--' + key + '=' + value;
|
|
}
|
|
|
|
kebabize(str) {
|
|
return str.split('').map((letter, idx) => {
|
|
return letter.toUpperCase() === letter
|
|
? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}`
|
|
: letter;
|
|
}).join('');
|
|
}
|
|
|
|
apply(compiler) {
|
|
let prevContent = null;
|
|
try {
|
|
fs.readFileSync(this.finalTarget);
|
|
} catch (e) {
|
|
}
|
|
const compile = async (comp, callback) => {
|
|
const args = Object.keys(this.options).reduce((pass, key) => {
|
|
const val = this.options[key];
|
|
if (val !== this.default[key]) {
|
|
if (Array.isArray(val)) {
|
|
pass.push(...val.map((v) => this.shellArg(key, v)));
|
|
} else {
|
|
pass.push(this.shellArg(key, val));
|
|
}
|
|
}
|
|
return pass;
|
|
}, []);
|
|
await execFile(this.options.php, ['bin/console', 'fos:js-routing:dump', ...args]);
|
|
try {
|
|
const content = await readFile(this.options.target);
|
|
await rmFile(this.options.target);
|
|
if (!prevContent || content.compare(prevContent) !== 0) {
|
|
await makeDir(path.dirname(this.finalTarget), {recursive: true});
|
|
await writeFile(this.finalTarget, content);
|
|
prevContent = content;
|
|
if (comp.modifiedFiles && !comp.modifiedFiles.has(this.finalTarget)) {
|
|
comp.modifiedFiles.add(this.finalTarget);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
const logger = compiler.getInfrastructureLogger('FosRouting');
|
|
logger.error(e.toString());
|
|
}
|
|
callback();
|
|
};
|
|
|
|
if (this.registerCompileHooks === true) {
|
|
compiler.hooks.beforeRun.tapAsync('RouteDump', compile);
|
|
compiler.hooks.watchRun.tapAsync('RouteDump_Watch', (comp, callback) => {
|
|
if (!comp.modifiedFiles || !comp.modifiedFiles.has(this.finalTarget)) {
|
|
compile(comp, callback);
|
|
} else {
|
|
callback();
|
|
}
|
|
});
|
|
}
|
|
|
|
new InjectPlugin(() => {
|
|
return 'import Routing from "fos-router";' +
|
|
'import routes from '+JSON.stringify(this.finalTarget)+';' +
|
|
'Routing.setRoutingData(routes);';
|
|
}).apply(compiler);
|
|
}
|
|
}
|
|
|
|
module.exports = FosRouting;
|
|
module.exports.default = FosRouting;
|