2015-09-11 14:42:11 +00:00
|
|
|
#!/usr/bin/env node
|
2021-01-19 14:36:21 +00:00
|
|
|
const fs = require('fs');
|
2021-03-11 13:40:11 +00:00
|
|
|
const { promises: fsp } = fs;
|
2021-01-19 14:36:21 +00:00
|
|
|
const path = require('path');
|
|
|
|
const glob = require('glob');
|
2021-01-19 14:45:03 +00:00
|
|
|
const util = require('util');
|
2021-01-19 14:36:21 +00:00
|
|
|
const args = require('minimist')(process.argv);
|
|
|
|
const chokidar = require('chokidar');
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
const componentIndex = path.join('src', 'component-index.js');
|
|
|
|
const componentIndexTmp = componentIndex+".tmp";
|
|
|
|
const componentsDir = path.join('src', 'components');
|
|
|
|
const componentJsGlob = '**/*.js';
|
|
|
|
const componentTsGlob = '**/*.tsx';
|
|
|
|
let prevFiles = [];
|
2015-09-15 12:34:36 +00:00
|
|
|
|
2021-01-19 14:45:03 +00:00
|
|
|
async function reskindex() {
|
2021-01-19 14:36:21 +00:00
|
|
|
const jsFiles = glob.sync(componentJsGlob, {cwd: componentsDir}).sort();
|
|
|
|
const tsFiles = glob.sync(componentTsGlob, {cwd: componentsDir}).sort();
|
|
|
|
const files = [...tsFiles, ...jsFiles];
|
2017-05-15 09:16:47 +00:00
|
|
|
if (!filesHaveChanged(files, prevFiles)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
prevFiles = files;
|
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
const header = args.h || args.header;
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
const strm = fs.createWriteStream(componentIndexTmp);
|
2021-03-11 13:40:11 +00:00
|
|
|
// Wait for the open event to ensure the file descriptor is set
|
|
|
|
await new Promise(resolve => strm.once("open", resolve));
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2017-05-08 13:57:04 +00:00
|
|
|
if (header) {
|
|
|
|
strm.write(fs.readFileSync(header));
|
|
|
|
strm.write('\n');
|
|
|
|
}
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2017-05-08 13:57:04 +00:00
|
|
|
strm.write("/*\n");
|
|
|
|
strm.write(" * THIS FILE IS AUTO-GENERATED\n");
|
|
|
|
strm.write(" * You can edit it you like, but your changes will be overwritten,\n");
|
|
|
|
strm.write(" * so you'd just be trying to swim upstream like a salmon.\n");
|
|
|
|
strm.write(" * You are not a salmon.\n");
|
|
|
|
strm.write(" */\n\n");
|
2019-12-13 02:31:52 +00:00
|
|
|
strm.write("let components = {};\n");
|
2017-05-08 13:57:04 +00:00
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
for (let i = 0; i < files.length; ++i) {
|
|
|
|
const file = files[i].replace('.js', '').replace('.tsx', '');
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
const moduleName = (file.replace(/\//g, '.'));
|
|
|
|
const importName = moduleName.replace(/\./g, "$");
|
2015-11-30 17:33:04 +00:00
|
|
|
|
2017-05-08 13:57:04 +00:00
|
|
|
strm.write("import " + importName + " from './components/" + file + "';\n");
|
2017-05-19 10:44:04 +00:00
|
|
|
strm.write(importName + " && (components['"+moduleName+"'] = " + importName + ");");
|
2017-05-08 13:57:04 +00:00
|
|
|
strm.write('\n');
|
|
|
|
strm.uncork();
|
|
|
|
}
|
|
|
|
|
2017-05-19 10:44:04 +00:00
|
|
|
strm.write("export {components};\n");
|
2021-01-19 14:45:03 +00:00
|
|
|
// Ensure the file has been fully written to disk before proceeding
|
2021-03-11 13:40:11 +00:00
|
|
|
await util.promisify(fs.fsync)(strm.fd);
|
2021-01-19 14:45:03 +00:00
|
|
|
await util.promisify(strm.end);
|
2021-03-11 13:40:11 +00:00
|
|
|
await fsp.rename(componentIndexTmp, componentIndex);
|
2017-05-08 13:57:04 +00:00
|
|
|
}
|
2015-09-11 14:42:11 +00:00
|
|
|
|
2017-05-15 09:16:47 +00:00
|
|
|
// Expects both arrays of file names to be sorted
|
|
|
|
function filesHaveChanged(files, prevFiles) {
|
|
|
|
if (files.length !== prevFiles.length) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Check for name changes
|
2021-01-19 17:58:17 +00:00
|
|
|
for (let i = 0; i < files.length; i++) {
|
2017-05-15 09:16:47 +00:00
|
|
|
if (prevFiles[i] !== files[i]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-03-11 13:40:11 +00:00
|
|
|
// Wrapper since await at the top level is not well supported yet
|
|
|
|
function run() {
|
|
|
|
(async function() {
|
|
|
|
await reskindex();
|
|
|
|
console.log("Reskindex completed");
|
|
|
|
})();
|
|
|
|
}
|
|
|
|
|
2017-05-08 13:57:04 +00:00
|
|
|
// -w indicates watch mode where any FS events will trigger reskindex
|
|
|
|
if (!args.w) {
|
2021-03-11 13:40:11 +00:00
|
|
|
run();
|
2017-05-08 13:57:04 +00:00
|
|
|
return;
|
2015-09-11 14:42:11 +00:00
|
|
|
}
|
2015-09-15 12:34:36 +00:00
|
|
|
|
2021-01-19 14:36:21 +00:00
|
|
|
let watchDebouncer = null;
|
2020-03-11 23:47:18 +00:00
|
|
|
chokidar.watch(path.join(componentsDir, componentJsGlob)).on('all', (event, path) => {
|
2017-05-08 13:57:04 +00:00
|
|
|
if (path === componentIndex) return;
|
|
|
|
if (watchDebouncer) clearTimeout(watchDebouncer);
|
2021-03-11 13:40:11 +00:00
|
|
|
watchDebouncer = setTimeout(run, 1000);
|
2017-05-08 13:57:04 +00:00
|
|
|
});
|