@tsed/cli-core
Version:
Build your CLI with TypeScript and Decorators
128 lines (127 loc) • 4.9 kB
JavaScript
import { inject, injectable, injectMany } from "@tsed/di";
import { EMPTY, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { ProjectPackageJson } from "../services/ProjectPackageJson.js";
import { isValidVersion } from "../utils/isValidVersion.js";
import { BaseManager } from "./supports/BaseManager.js";
import { BunManager } from "./supports/BunManager.js";
import { NpmManager } from "./supports/NpmManager.js";
import { PNpmManager } from "./supports/PNpmManager.js";
import { YarnBerryManager } from "./supports/YarnBerryManager.js";
import { YarnManager } from "./supports/YarnManager.js";
function mapPackagesWithInvalidVersion(deps) {
const toString = (info) => {
return info[1] === "latest" ? info[0] : info.join("@");
};
return Object.entries(deps)
.filter(([, version]) => !isValidVersion(version))
.map(toString);
}
export class PackageManagersModule {
constructor() {
this.projectPackageJson = inject(ProjectPackageJson);
this.packageManagers = injectMany("package:manager").filter((manager) => {
return manager.has();
});
}
init(options = {}) {
const packageManager = this.get(options.packageManager);
options.packageManager = packageManager.name;
options = {
...options,
cwd: this.projectPackageJson.cwd,
env: {
...process.env,
GH_TOKEN: this.projectPackageJson.GH_TOKEN
}
};
this.projectPackageJson.write();
this.projectPackageJson.rewrite = true;
return packageManager.init(options);
}
task(title, ctx = {}) {
return {
title,
type: "progress",
task: () => this.install(ctx)
};
}
install(options = {}) {
const packageManager = this.get(options.packageManager);
options.packageManager = packageManager.name;
const devDeps = mapPackagesWithInvalidVersion(this.projectPackageJson.devDependencies);
const deps = mapPackagesWithInvalidVersion(this.projectPackageJson.dependencies);
options = {
...options,
cwd: this.projectPackageJson.cwd,
env: {
...process.env,
GH_TOKEN: this.projectPackageJson.GH_TOKEN
}
};
return [
{
title: "Write package.json",
skip: () => !this.projectPackageJson.rewrite,
task: () => {
this.projectPackageJson.write();
}
},
{
title: `Installing dependencies using ${packageManager.name}`,
skip: () => !this.projectPackageJson.reinstall,
task: () => packageManager.install(options)
},
{
title: `Add dependencies using ${packageManager.name}`,
enabled: !!deps.length,
task: () => packageManager.add(deps, options)
},
{
title: `Add devDependencies using ${packageManager.name}`,
enabled: !!devDeps.length,
task: () => packageManager.addDev(devDeps, options)
},
{
title: `Installing dependencies using ${packageManager.name}`,
skip: () => !this.projectPackageJson.reinstall,
task: () => packageManager.install(options)
},
{
title: "Refresh",
task: () => {
return this.projectPackageJson.refresh();
}
}
];
}
list() {
return this.packageManagers.map((manager) => manager.name);
}
get(name) {
if (this.projectPackageJson.preferences.packageManager) {
name = this.projectPackageJson.preferences.packageManager;
}
name = name || "yarn";
let selectedPackageManager = this.packageManagers.find((manager) => manager.name === name);
if (!selectedPackageManager) {
selectedPackageManager = this.packageManagers.find((manager) => manager.name === "npm");
}
this.projectPackageJson.setPreference("packageManager", selectedPackageManager.name);
return selectedPackageManager;
}
runScript(scriptName, { ignoreError, ...opts } = {}) {
const options = {
cwd: this.projectPackageJson.dir,
...opts
};
const errorPipe = () => catchError((error) => {
if (ignoreError) {
return EMPTY;
}
return throwError(error);
});
return this.get().runScript(scriptName, options).pipe(errorPipe());
}
}
injectable(PackageManagersModule).imports([NpmManager, YarnBerryManager, PNpmManager, BunManager, YarnManager]);