@oblique/cli
Version:
Command Line Interface to manage Oblique projects
153 lines (151 loc) • 6.57 kB
JavaScript
/**
* @file Oblique, The front-end framework for your Swiss branded UI.
* @copyright 2020 - 2025 Federal Office of Information Technology, Systems and Telecommunication FOITT {@link https://www.bit.admin.ch}
* @version 14.1.2 (released on 2025-12-01, supported at least until 2026-09-30)
* @author Oblique team, FOITT, BS-BSC-EN4 <oblique@bit.admin.ch>
* @license MIT {@link https://github.com/oblique-bit/oblique/blob/master/LICENSE}
* @see https://oblique.bit.admin.ch
*/
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createObUpdateCommand = createObUpdateCommand;
exports.initializeCommand = initializeCommand;
exports.handleObUpdateActions = handleObUpdateActions;
exports.checkNeededDependencies = checkNeededDependencies;
exports.addSchematicsAngular = addSchematicsAngular;
exports.runUpdateDependencies = runUpdateDependencies;
exports.outputOutdatedDependencies = outputOutdatedDependencies;
exports.isDependencyInPackage = isDependencyInPackage;
exports.findPackage = findPackage;
const tslib_1 = require("tslib");
const extra_typings_1 = require("@commander-js/extra-typings");
const path = tslib_1.__importStar(require("node:path"));
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
const cli_utils_1 = require("../utils/cli-utils");
const ob_update_model_1 = require("./ob-update.model");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const child_process_1 = require("child_process");
function createObUpdateCommand() {
const command = new extra_typings_1.Command();
return initializeCommand(command);
}
function initializeCommand(command) {
command
.name('update')
.helpOption('-h, --help', (0, cli_utils_1.getHelpText)('ob update'))
.usage((0, cli_utils_1.commandUsageText)('update', ' '))
.summary(ob_update_model_1.updateDescriptions.summaryText)
.action(() => handleAction())
.showSuggestionAfterError(true)
.showHelpAfterError(true);
return command;
}
function handleAction() {
(0, cli_utils_1.startObCommand)(handleObUpdateActions, 'Oblique CLI ob update completed in', undefined);
}
function handleObUpdateActions() {
try {
checkNeededDependencies();
addSchematicsAngular();
runUpdateDependencies();
runUpdateSave();
runNpmDedupe();
runNpmPrune();
}
catch (error) {
console.error(chalk_1.default.red('Update failed: '), error);
process.exit(1);
}
// this have to be done at the end, because npm outdated exits with a non-zero exit code (status: 1 in the output) which causes execSync to throw and catch an error.
outputOutdatedDependencies();
}
function checkNeededDependencies() {
if (!isDependencyInPackage('@oblique/oblique')) {
console.error(chalk_1.default.red(`Package @oblique/oblique not found. Please install Oblique with '${cli_utils_1.ngAddOblique.command}' to ${cli_utils_1.ngAddOblique.description}.`));
process.exit(1);
}
}
function addSchematicsAngular() {
// This is temporary until a better solution is found
// The problem is that @schematics/angular, which is a dependency of Oblique, needs to be updated at the same time as the other packages,
// otherwise @angular-devkit/core won't be installed as a root dependency, but as a nested one. This can be solved with npm dedupe,
// but there's no way to execute this function in the middle of the update command.
// The solution is then to ensure that @schematics/angular is listed as a devDependency so that the update command also updates it
if (!isDependencyInPackage('@schematics/angular')) {
const pkg = findPackage();
if (pkg.dependencies) {
const groups = /[^~](?<major>\d+)\.\d+\.\d+"/u.exec(pkg.dependencies['@angular/core'])?.groups ?? { major: '18' };
(0, child_process_1.execSync)(`npm i @schematics/angular@${groups['major']} --save-dev`, { stdio: 'inherit' });
}
}
}
function runUpdateDependencies() {
try {
const dependencies = Object.entries(cli_utils_1.currentVersions)
.map(([dependency]) => dependency)
.filter(dependency => isDependencyInPackage(dependency));
(0, cli_utils_1.execute)({ name: 'ngUpdate', dependencies, options: { force: true } });
}
catch (error) {
console.error(error);
}
}
function runUpdateSave() {
console.info(chalk_1.default.blue('[Info]: Runs npm update'));
try {
(0, cli_utils_1.execute)({ name: 'npmUpdate' });
}
catch (error) {
console.info(error);
}
}
function runNpmDedupe() {
console.info(chalk_1.default.blue('[Info]: Runs npm dedupe'));
try {
(0, cli_utils_1.execute)({ name: 'npmDedupe' });
}
catch (error) {
console.info(error);
}
}
function runNpmPrune() {
console.info(chalk_1.default.blue('[Info]: Runs npm prune'));
try {
(0, cli_utils_1.execute)({ name: 'npmPrune' });
}
catch (error) {
console.info(error);
}
}
function outputOutdatedDependencies() {
console.info(chalk_1.default.blue('[Info]: Following dependencies should also be manually updated.\n'));
try {
(0, cli_utils_1.execute)({ name: 'npmOutdated' });
}
catch (error) {
// npm outdated always fails, but no error management is needed since the execute function will already print its output.
// the try..catch block only serves to avoid the error being thrown
}
}
function isDependencyInPackage(dependency) {
try {
const packageJson = findPackage();
const dependencies = packageJson.dependencies ?? {};
const devDependencies = packageJson.devDependencies ?? {};
return dependency in dependencies || dependency in devDependencies;
}
catch (error) {
console.error(chalk_1.default.red(`[Error]: This command is not available when running the Oblique CLI outside a workspace`), error);
/* eslint-disable @typescript-eslint/no-magic-numbers */
process.exit(3);
/* eslint-enable @typescript-eslint/no-magic-numbers */
}
return false;
}
function findPackage() {
const packageJsonPath = path.resolve(process.cwd(), 'package.json');
if (packageJsonPath) {
return JSON.parse(node_fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
}
throw new Error(`Cant find the package.json at path: ${[process.cwd(), 'package.json'].join('/')}. Please navigate to the level of your package.json and try "ob update" again.`);
}