@tsed/cli-core
Version:
Build your CLI with TypeScript and Decorators
280 lines (279 loc) • 8.43 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { dirname, join } from "node:path";
import { getValue, setValue } from "@tsed/core";
import { configuration, constant, inject, Injectable } from "@tsed/di";
import { readPackageUpSync } from "read-pkg-up";
import { isValidVersion } from "../utils/isValidVersion.js";
import { CliFs } from "./CliFs.js";
function sortKeys(obj) {
return Object.entries(obj)
.sort((k1, k2) => {
return k1[0] < k2[0] ? -1 : 1;
})
.reduce((obj, [key, value]) => {
return {
...obj,
[key]: value
};
}, {});
}
function mapPackages(deps) {
return Object.entries(deps).reduce((deps, [key, version]) => {
if (isValidVersion(version)) {
deps.valid[key] = version;
}
else {
deps.invalid[key] = version;
}
return deps;
}, { valid: {}, invalid: {} });
}
let ProjectPackageJson = class ProjectPackageJson {
constructor() {
this.rewrite = false;
this.reinstall = false;
this.fs = inject(CliFs);
this.setRaw({
name: "",
version: "1.0.0",
description: "",
type: "module",
scripts: {},
dependencies: {},
devDependencies: {}
});
}
get path() {
return join(this.dir, "package.json");
}
get dir() {
return String(constant("project.rootDir"));
}
set dir(dir) {
configuration().set("project.rootDir", dir);
this.read();
}
get name() {
return this.raw.name;
}
set name(name) {
this.raw.name = name;
this.rewrite = true;
}
get version() {
return this.raw.version;
}
get description() {
return this.raw.description;
}
get scripts() {
return this.raw.scripts;
}
get dependencies() {
return this.raw.dependencies;
}
get devDependencies() {
return this.raw.devDependencies;
}
get allDependencies() {
return {
...(this.dependencies || {}),
...(this.devDependencies || {})
};
}
get preferences() {
return this.raw[constant("name")];
}
$loadPackageJson() {
return this.read();
}
toJSON() {
return this.raw;
}
read() {
const pkg = this.getPackageJson();
this.setRaw(pkg);
return this;
}
setRaw(pkg) {
const config = configuration();
const projectPreferences = config.get("defaultProjectPreferences");
const preferences = getValue(pkg, config.get("name"));
this.raw = {
...pkg,
[config.get("name")]: {
...(projectPreferences && projectPreferences(pkg)),
...preferences
}
};
}
addDevDependency(pkg, version) {
this.devDependencies[pkg] = version;
this.reinstall = true;
this.rewrite = true;
return this;
}
addDevDependencies(modules, scope = {}) {
const replacer = (match, key) => getValue(key, scope);
Object.entries(modules).forEach(([pkg, version]) => {
if (!this.dependencies[pkg]) {
this.addDevDependency(pkg, (version || "").replace(/{{([\w.]+)}}/gi, replacer));
}
});
return this;
}
addDependency(pkg, version) {
this.dependencies[pkg] = version;
this.reinstall = true;
this.rewrite = true;
return this;
}
addDependencies(modules, ctx = {}) {
const replacer = (match, key) => getValue(key, ctx);
Object.entries(modules).forEach(([pkg, version]) => {
this.addDependency(pkg, (version || "").replace("{{tsedVersion}}", ctx.tsedVersion).replace(/{{([\w.]+)}}/gi, replacer));
});
return this;
}
addScript(task, cmd) {
this.scripts[task] = cmd;
this.rewrite = true;
return this;
}
addScripts(scripts) {
Object.entries(scripts).forEach(([task, cmd]) => {
this.addScript(task, cmd);
});
return this;
}
add(key, data) {
this.raw[key] = data;
this.rewrite = true;
return this;
}
setPreference(key, value) {
setValue(this.raw, `${constant("name")}.${key}`, value);
this.rewrite = true;
return;
}
set(key, value) {
this.raw[key] = value;
this.rewrite = true;
if (["dependencies", "devDependencies", "peerDependencies"].includes(key)) {
this.reinstall = true;
}
}
get(key) {
return this.raw[key];
}
write() {
const originalPkg = this.getPackageJson();
const { valid: dependencies, invalid: pendingDependencies } = mapPackages(this.raw.dependencies);
const { valid: devDependencies, invalid: pendingDevDependencies } = mapPackages(this.raw.devDependencies);
this.rewrite = false;
this.raw = {
...originalPkg,
...this.raw,
type: "module",
scripts: {
...(originalPkg.scripts || {}),
...(this.raw.scripts || {})
},
dependencies: sortKeys({
...originalPkg.dependencies,
...dependencies
}),
devDependencies: sortKeys({
...originalPkg.devDependencies,
...devDependencies
}),
readme: undefined,
_id: undefined
};
this.fs.writeFileSync(this.path, JSON.stringify(this.raw, null, 2), { encoding: "utf8" });
this.raw.dependencies = {
...this.raw.dependencies,
...pendingDependencies
};
this.raw.devDependencies = {
...this.raw.devDependencies,
...pendingDevDependencies
};
return this;
}
/**
* Import a module from the project workspace
* @param mod
*/
importModule(mod) {
return this.fs.importModule(mod, this.dir);
}
setGhToken(GH_TOKEN) {
this.GH_TOKEN = GH_TOKEN;
}
refresh() {
this.reinstall = false;
this.rewrite = false;
const cwd = constant("project.rootDir");
const pkgPath = join(String(cwd), "package.json");
const pkg = this.fs.readJsonSync(pkgPath, { encoding: "utf8" });
pkg.scripts = {
...this.raw.scripts,
...pkg.scripts
};
pkg.dependencies = {
...this.raw.dependencies,
...pkg.dependencies
};
pkg.devDependencies = {
...this.raw.devDependencies,
...pkg.devDependencies
};
const name = constant("name");
pkg[name] = {
...this.raw[name],
...pkg[name]
};
this.raw = pkg;
return this;
}
getPackageJson() {
const cwd = constant("project.rootDir");
const disableReadUpPkg = constant("command.metadata.disableReadUpPkg");
const name = constant("name");
const pkgPath = join(String(cwd), "package.json");
const fileExists = this.fs.exists(pkgPath);
if (!disableReadUpPkg && !fileExists) {
const result = readPackageUpSync({
cwd
});
if (result && result.path) {
const pkgPath = dirname(result.path);
configuration().set("project.root", pkgPath);
const pkg = this.fs.readJsonSync(result.path, { encoding: "utf8" });
return { ...this.getEmptyPackageJson(name), ...pkg };
}
}
if (disableReadUpPkg && fileExists) {
const pkg = this.fs.readJsonSync(pkgPath, { encoding: "utf8" });
configuration().set("project.root", pkgPath);
return { ...this.getEmptyPackageJson(name), ...pkg };
}
return this.getEmptyPackageJson(name);
}
getEmptyPackageJson(name) {
return {
name,
version: "1.0.0",
description: "",
scripts: {},
dependencies: {},
devDependencies: {}
};
}
};
ProjectPackageJson = __decorate([
Injectable({}),
__metadata("design:paramtypes", [])
], ProjectPackageJson);
export { ProjectPackageJson };