UNPKG

nwjs-builder-phoenix

Version:

A possible solution to build and package a ready for distribution NW.js app for Windows, macOS and Linux.

183 lines (120 loc) 4.23 kB
import { basename, dirname, relative } from 'path'; import { createHash } from 'crypto'; import { exists, readJsonAsync, writeJsonAsync, createReadStream } from 'fs-extra-promise'; import * as semver from 'semver'; interface IInstaller { arch: string; path: string; hash: string; created: number; } interface IVersion { version: string; changelog: string; source: string; installers: IInstaller[]; updaters: IUpdater[]; } interface IVersionInfoData { latest: string; versions: IVersion[]; } export class NsisVersionInfo { protected outputDir: string; protected data: IVersionInfoData; constructor(protected path: string) { this.outputDir = dirname(path); } public async addVersion(version: string, changelog: string, source: string) { const data = await this.getData(); if(!data.versions.find(item => item.version == version)) { data.versions.push({ version, changelog, source: basename(source), installers: [], updaters: [], }); } this.updateLatestVersion(); } public async getVersions(): Promise<string[]> { const data = await this.getData(); return data.versions.map(item => item.version); } public async getVersion(version: string): Promise<IVersion> { const data = await this.getData(); const item = data.versions.find(item => item.version == version); if(!item) { throw new Error('ERROR_VERSION_NOT_FOUND'); } return item; } public async addInstaller(version: string, arch: string, path: string) { const data = await this.getData(); const versionItem: IVersion = data.versions.find(item => item.version == version); if(!versionItem) { throw new Error('ERROR_VERSION_NOT_FOUND'); } if(!versionItem.installers.find(item => item.arch == arch)) { versionItem.installers.push({ arch, path: relative(this.outputDir, path), hash: await this.hashFile('sha256', path), created: Date.now(), }); } } public async addUpdater(version: string, fromVersion: string, arch: string, path: string) { const data = await this.getData(); const versionItem: IVersion = data.versions.find(item => item.version == version); if(!versionItem) { throw new Error('ERROR_VERSION_NOT_FOUND'); } if(!versionItem.updaters.find(item => item.fromVersion == fromVersion && item.arch == arch)) { versionItem.updaters.push({ fromVersion, arch, path: relative(this.outputDir, path), hash: await this.hashFile('sha256', path), created: Date.now(), }); } } public async save() { await writeJsonAsync(this.path, this.data); } protected async getData() { if(!this.data) { this.data = (await new Promise((resolve, reject) => exists(this.path, resolve))) ? await readJsonAsync(this.path) : { latest: undefined, versions: [], }; } return this.data; } protected updateLatestVersion() { if(this.data.versions.length == 0) { return; } const versions = [ ...this.data.versions ]; versions.sort((a, b) => semver.gt(a.version, b.version) ? -1 : 1); this.data.latest = versions[0].version; } protected hashFile(type: string, path: string): Promise<string> { return new Promise((resolve, reject) => { const hasher = createHash(type); hasher.on('error', reject); hasher.on('readable', () => { const data = hasher.read(); if(data) { hasher.end(); resolve((<any>data).toString('hex')); } }); createReadStream(path).pipe(hasher); }); } }