const fs = require('fs/promises'); const path = require('path'); /** * purely convienience */ class FileDependecy { name; folder; path() { return this.folder + '/' + this.name; } } /** * Object Access Object * purely convienience */ class OAO { constructor() { /** * @type {boolean|Map} */ this.orderedGroups /** * @type {Array} */ this.keys = []; /** * @type {map} */ this.objects = {}; /** * @type {boolean} */ this.isOrdered = false; } } const copyright_disclaimer = ` /** * This file is part of the jps-like-websites lib * URL: https://git.labos.goip.de/chris/jpc-like-websites * @copyright by its creator Christian Martin */ `; let fileOrder = Object.assign(new OAO(), require('./fileOrder.json')); fileOrder.objects = fileOrder.keys .reduce((a, fileName) => Object.assign( a, { [fileName]: Object.assign(new FileDependecy(), fileOrder.objects[fileName]) } ), {}); /** * Kept for future reference, might be that we will return to the dependency resolvement approach. * @param {OAO} oao * @returns {OAO} */ function resolveDependencyOrder(oao) { let roots = oao.keys.filter(k => oao.objects[k].dependencies.length === 0); let folderList = [...new Set(oao.keys.map(k => oao.objects[k].folder))]; console.log("Folders", folderList); /** * * @param {OAO} oao * @param {Array>} dealt */ function recursiveResolvement(oao, dealtLvls, dealt) { const arrsEqualSize = (arr1, arr2) => arr1.length === arr2.length; const arrHasAll = (arr1, arr2) => arr2.every(k => arr1.includes(k)) if (oao.keys.length === dealt.length) { return [...dealt, ...current]; } else { console.log(`Received ${dealt.length} dealt of ${oao.keys.length}`); } let remaining = oao.keys .filter(k => !dealt.includes(k)); if (remaining.length < 2) { return [...dealt, ...remaining]; } let current = remaining .filter(k => oao.objects[k].dependencies.every(sk => dealt.includes(sk))); if (current.length === 0) { console.log("Couldn't resolve", remaining); return remaining; } dealtLvls.push(current); if (arrsEqualSize(remaining, current)) { return [...dealt, ...current]; } return recursiveResolvement(oao, dealtLvls, [...dealt, ...current]); } let recursiveResolved = recursiveResolvement(oao, [roots], roots); recursiveResolved .forEach((k, i) => { oao.objects[k].orderNr = i; }); oao.isOrdered = recursiveResolved.slice(-1).length <= 2; if (oao.isOrdered) { oao.keys = recursiveResolved; } return oao; } /** * * @param {string} srcFile path to src file * @param {string} targetFile path of target file that will contain all scripts */ async function appendContent(srcFile, targetFile) { try { let content = await fs.readFile(srcFile, 'utf8'); console.log(`Processing '${srcFile}'`); console.log(` READ: successfully!`); console.log(` Adding Copyright disclaimer!`); console.log(` Attepting to append to default script variant`); content = [ ...copyright_disclaimer.split('\r\n'), ...content.split('\r\n') ]; await fs.appendFile(targetFile, content.join('\r\n')); console.log(` Adding export to "modulize"!`); /** * Checks weither the given line starts with any of the exportable values. * @param {string} line * @returns {boolean} */ const isExpStarter = line => ["function", "const", "let", "class"].some(starter => line.startsWith(starter)); console.log(` Attepting to append to module variant`); await fs.appendFile( targetFileModule, content .map(l => (isExpStarter(l) ? "export " : "") + l) .join('\r\n') ); console.log(` Append/Write: successfully!`); } catch (error) { console.error(`Error reading/writing files: ${error.message}`); } } let orderedJoinList = Object.keys(fileOrder.orderedGroups) .flatMap(groupName => fileOrder.orderedGroups[groupName]) .map(fileName => fileOrder.objects[fileName].path()); /* // Kept for future reference, might be that we will return to the dependency resolvement approach. fileOrder = resolveDependencyOrder(fileOrder); let orderedJoinList = fileOrder.keys .map(fileName => fileOrder.objects[k].path()); */ const targetFile = "./jpc-like-websites.js"; const targetFileModule = "./jpc-like-websites.module.js"; console.log("(Re-) Creating target file: '" + targetFile + "'"); /* EMPTY (create?) TARGET FILE */ fs.writeFile(targetFile, "", err => { }); fs.writeFile(targetFileModule, "", err => { }); orderedJoinList .reduce((prevPromise, filePath) => prevPromise .then( () => appendContent(filePath, targetFile) ), Promise.resolve())