liferay-npm-bundler-preset-reactjs
Version:
liferay npm bundler preset react
194 lines (158 loc) • 4.08 kB
text/typescript
/**
* SPDX-FileCopyrightText: © 2020 Liferay, Inc. <https://liferay.com>
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
import fs from 'fs-extra';
import path from 'path';
import {Manifest as Data, ModuleFlags, Package} from './api/manifest';
import FilePath from './file-path';
import PkgDesc from './pkg-desc';
import project from './project';
export {ModuleFlags, Package};
/**
* A class to hold information about processed modules and optionally dump/read
* it to/from disk.
*/
export default class Manifest {
/**
* @param filePath an optional path to a file to load initial status
*/
constructor(filePath: string = null) {
this._loadedFromFile = false;
if (filePath) {
this._filePath = filePath;
try {
this._data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
this._loadedFromFile = true;
return;
}
catch (err) {
if (err.code !== 'ENOENT') {
throw err;
}
}
}
this._data = {
packages: {},
};
}
/**
* Set to true when the manifest has been loaded from a file.
*/
get loadedFromFile(): boolean {
return this._loadedFromFile;
}
/**
* Add a processed package entry
* @param srcPkg the source package descriptor
* @param destPkg the destination package descriptor
*/
addPackage(srcPkg: PkgDesc, destPkg: PkgDesc): void {
if (this._data.packages[srcPkg.id] === undefined) {
this._data.packages[srcPkg.id] = {} as Package;
}
const pkg = this._data.packages[srcPkg.id];
pkg.src = {
id: srcPkg.id,
name: srcPkg.name,
version: srcPkg.version,
dir: srcPkg.dir.asPosix,
};
pkg.dest = {
id: destPkg.id,
name: destPkg.name,
version: destPkg.version,
dir: destPkg.dir.asPosix,
};
}
addModuleFlags(
pkgId: string,
moduleName: string,
flags: ModuleFlags
): void {
if (this._data.packages[pkgId] === undefined) {
this._data.packages[pkgId] = {} as Package;
}
const pkg = this._data.packages[pkgId];
if (pkg.modules === undefined) {
pkg.modules = {};
}
if (pkg.modules[moduleName] === undefined) {
pkg.modules[moduleName] = {};
}
if (pkg.modules[moduleName].flags === undefined) {
pkg.modules[moduleName].flags = {};
}
Object.assign(pkg.modules[moduleName].flags, flags);
}
/**
* Get a processed package entry
* @param srcPkg the source package descriptor
* @return the processed package entry (see addPackage for format description)
*/
getPackage(srcPkg: PkgDesc): Package {
return this._data.packages[srcPkg.id];
}
/**
* Tests whether a package must be regenerated
* @param destPkg destination package
* @return true if package is outdated
*/
isOutdated(destPkg: PkgDesc): boolean {
// Unless we use real timestamps or digests, we cannot detect reliably
// if the root package is outdated or up-to-date.
if (destPkg.isRoot) {
return true;
}
const entry = this._data.packages[destPkg.id];
if (entry === undefined) {
return true;
}
if (
!fs.existsSync(
project.dir.join(new FilePath(entry.dest.dir, {posix: true}))
.asNative
)
) {
return true;
}
return false;
}
/**
* Save current manifest to a file
* @param filePath path to file or null to use default path
*/
save(filePath: string = null): void {
filePath = filePath || this._filePath;
if (filePath === undefined) {
throw new Error('No file path given and no default path set');
}
fs.ensureDirSync(path.dirname(filePath));
fs.writeFileSync(filePath, this.toJSON());
}
/**
* Return the JSON serialization of this manifest
*/
toJSON(): string {
return JSON.stringify(this._data, sortObjectKeysReplacer, 2);
}
private _loadedFromFile: boolean;
private _filePath: string;
private _data: Data;
}
/**
* Replacer function for sorting object keys when stringifying
*/
function sortObjectKeysReplacer(key, value) {
if (value instanceof Object && !Array.isArray(value)) {
return Object.keys(value)
.sort()
.reduce((sorted, key) => {
sorted[key] = value[key];
return sorted;
}, {});
}
else {
return value;
}
}