//@ts-check import * as fs from 'fs' import * as path from 'path' /** * @typedef {{ name: string, before: string[], after: string[], init(): undefined | Promise }} InitScript */ export async function init() { const initdFiles = fs.readdirSync('/etc/init.d/') const initdScripts = initdFiles.filter( (v) => v.endsWith('.js')) /** * @type { Array } */ const finishedScripts = [] /** * @type { Array } */ const scripts = [] for(const script of initdScripts) { const scriptCandidate = require(path.join('/etc/init.d/', script)) if(scriptCandidate?.before && scriptCandidate?.after && scriptCandidate?.init) scripts.push({ ...scriptCandidate, name: script}) else console.error(`Invalid(missing exports) script error :${script}`) } const befores = processBefores(scripts) let i = 0 while(scripts.length) { const s = scripts[i % scripts.length] i += 1 if(isSubSet(s.after, finishedScripts) && ( !befores[s.name] || isSubSet(befores[s.name], finishedScripts) )) { //on supprime ce service scripts.splice(scripts.indexOf(s), 1) const result = s.init() if(typeof result?.then === 'function') { await result finishedScripts.push(s.name) } } } } /** * @template T * @param {Array} arraya * @param {Array} arrayb */ function isSubSet(arraya, arrayb) { for(const a of arraya) { if(!arrayb.includes(a)) { return false } } return true } /** * * @param {Array} scripts * @returns {{ [key: string]: string[] }} */ function processBefores(scripts) { /** * @type {{ [key: string]: string[] }} */ const result = {} for(const script of scripts) { for(const before of script.before){ if(! result[before]) result[before] = [script.name] else result[before].push(script.name) } } return result }