forked from FriendsOfSymfony/FOSJsRoutingBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FosRouting.js
107 lines (98 loc) · 3.8 KB
/
FosRouting.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
/**
* @author Adrien Foulon <tofandel@tukan.hu>
*/
const fs = require('fs');
const path = require('path');
const util = require('util');
const webpack = require("webpack");
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 = {}) {
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';
}
}
// 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();
};
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 webpack.BannerPlugin({
entryOnly: true,
include: this.finalTarget ? this.finalTarget + ".js" : /\.js$/,
raw: true,
banner:
'import Routing from "fos-router";' +
"import routes from " +
JSON.stringify(this.finalTarget) +
";" +
"Routing.setRoutingData(routes);",
}).apply(compiler);
}
}
module.exports = FosRouting;
module.exports.default = FosRouting;