UNPKG

beyond

Version:

The Full Stack Universal Typescript Framework

124 lines (100 loc) 3.53 kB
const DynamicProcessor = global.utils.DynamicProcessor(Map); const { crc32, equal } = global.utils; const Package = require('./package'); /** * The packages dependencies are the dependencies configured in the package.json, plus the application libraries. * Only required in local environment to support dynamic imports, (as it is needed to know the version of the packages). */ module.exports = class extends DynamicProcessor { get dp() { return 'application.package_json.dependencies'; } #application; #hash; get hash() { return this.#hash; } #errors = []; get errors() { return this.#errors; } get valid() { return !this.#errors.length; } constructor(application) { super(); this.#application = application; super.setup( new Map([ ['package_json', { child: application.packagejson }], ['libraries', { child: application.libraries }], ]) ); } #packages = new Map(); #previous = []; _prepared(require) { const { valid, json } = this.children.get('package_json').child; if (!valid) { this.#errors = ['File package.json has reported errors']; this.#packages.forEach(pkg => pkg.destroy()); this.#packages.clear(); return; } const { libraries } = this.#application; libraries.forEach(library => require(library)); const setPackages = (updated, dependencies, type = undefined) => { dependencies = dependencies ? Object.keys(dependencies) : []; dependencies.forEach(dependency => { const pkg = this.#packages.has(dependency) ? this.#packages.get(dependency) : new Package(this.#application, dependency, type); updated.set(dependency, pkg); }); }; const updated = new Map(); setPackages(updated, json.dependencies); setPackages(updated, json.devDependencies, 'devDependencies'); // Clean up not required packages this.#packages.forEach((pkg, dependency) => !updated.has(dependency) && pkg.destroy()); this.#packages.clear(); updated.forEach((pkg, name) => { require(pkg); this.#packages.set(name, pkg); }); } _process() { const done = ({ value, errors }) => { if (errors?.length && equal(errors, this.#errors)) return false; this.#errors = errors ? errors : []; if (!this.valid) { this.clear(); return; } const compute = {}; value.forEach((version, pkg) => (compute[pkg] = version)); const hash = crc32(equal.generate(compute)); if (this.#hash === hash) return false; this.#hash = hash; this.clear(); value.forEach((version, pkg) => this.set(pkg, version)); this.#previous = [...this]; if (equal(value, this.#previous)) return false; }; const value = new Map(); const errors = []; this.#application.libraries.forEach(library => value.set(library.pkg, library.version)); const { valid, json } = this.children.get('package_json').child; if (!valid) return done({ value }); const dependencies = json.dependencies ? Object.keys(json.dependencies) : []; const devDependencies = json.devDependencies ? Object.keys(json.devDependencies) : []; const packages = dependencies.concat(devDependencies); packages.forEach(dependency => { const pkg = this.#packages.get(dependency); !pkg.valid && errors.push(pkg.error); }); if (errors.length) return done({ errors }); packages.forEach(dependency => value.set(dependency, this.#packages.get(dependency).version)); return done({ value }); } };