@oblique/cli
Version:
Command Line Interface to manage Oblique projects
142 lines (140 loc) • 6.58 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.createObNewCommand = createObNewCommand;
const extra_typings_1 = require("@commander-js/extra-typings");
const cli_utils_1 = require("../utils/cli-utils");
const ob_configure_command_1 = require("../utils/ob-configure-command");
const ob_new_model_1 = require("./ob-new.model");
function createObNewCommand() {
const command = new extra_typings_1.Command();
const initializedCommand = initializeCommand(command);
return configureCommandOptions(initializedCommand);
}
function initializeCommand(command) {
command
.name('new')
.version(cli_utils_1.version, cli_utils_1.optionDescriptions.ob.version.flags, cli_utils_1.optionDescriptions.ob.version.description)
.helpOption(cli_utils_1.optionDescriptions.new.help.flags, cli_utils_1.optionDescriptions.new.help.description)
.usage((0, cli_utils_1.commandUsageText)('new'))
.summary(ob_new_model_1.obNewConfig.obNewSummaryText)
.description(ob_new_model_1.obNewConfig.obNewSummaryText)
.argument(ob_new_model_1.obNewConfig.projectNameArgument.argumentName, ob_new_model_1.obNewConfig.projectNameArgument.description)
.action(projectName => handleAction({ projectName, command }))
.showSuggestionAfterError(true)
.showHelpAfterError(true);
return command;
}
function handleAction(options) {
(0, cli_utils_1.startObCommand)(handleObNewActions, 'Oblique CLI ob new completed in', options);
}
function handleObNewActions(options) {
let cmdOptions = (0, ob_configure_command_1.convertOptionPropertyNames)(options.command.opts());
cmdOptions = cmdOptions.interactive
? { interactive: true }
: cmdOptions;
try {
runNgNewAngularWorkspace(options.projectName, cmdOptions.interactive, cmdOptions.prefix);
if (cmdOptions.interactive) {
console.info(`[Info]: Interactive mode is enabled. All other options will be ignored, and you will be prompted to specify each option.`);
}
const workingDirectory = getApplicationDirectory(options.projectName);
runAddMaterial(workingDirectory);
runAddAdditionalDependencies(workingDirectory);
runAddOblique(cmdOptions, options.projectName, workingDirectory);
cleanupDependencies(workingDirectory);
formatCode(workingDirectory);
}
catch (error) {
console.error('Installation failed: ', error);
}
}
function runNgNewAngularWorkspace(projectName, interactive, prefix) {
console.info(ob_new_model_1.createsWorkspaceMessage);
const baseOptions = Object.entries(ob_new_model_1.immutableOptions)
.map(([key, option]) => ({ key, value: option.value }))
.reduce((options, option) => ({ ...options, [option.key]: option.value }), {});
(0, cli_utils_1.execute)({
name: 'ngNew',
projectName,
options: interactive ? { ...filterValidOptions(baseOptions) } : { ...filterValidOptions(baseOptions), prefix },
});
}
function runAddMaterial(dir) {
console.info(`[Info]: Adds Angular Material`);
(0, cli_utils_1.execute)({
name: 'npmInstall',
dependencies: ['@angular/material', '@angular/cdk', '@angular/animations'],
execSyncOptions: { cwd: dir },
});
}
function runAddAdditionalDependencies(dir) {
console.info(`[Info]: Adds additional Dependencies`);
(0, cli_utils_1.execute)({ name: 'npmInstall', dependencies: ['@angular/platform-browser-dynamic'], execSyncOptions: { cwd: dir } });
}
function runAddOblique(options, projectName, workingDirectory) {
console.info(`[Info]: Adds Oblique`);
const projectTitle = options.title === cli_utils_1.projectNamePlaceholder || options.title === '' ? projectName : options.title;
let commandOptions = { ...options, title: projectTitle };
if (options.interactive === true) {
commandOptions = {};
}
const filteredOptions = filterValidOptions(commandOptions);
(0, cli_utils_1.execute)({ name: 'ngAdd', dependency: '@oblique/toolchain', execSyncOptions: { cwd: workingDirectory } });
(0, cli_utils_1.execute)({
name: 'ngAdd',
dependency: '@oblique/oblique',
options: filteredOptions,
execSyncOptions: { cwd: workingDirectory },
});
}
function cleanupDependencies(workingDirectory) {
console.info(`[Info]: Runs npm dedupe and prune`);
try {
(0, cli_utils_1.execute)({ name: 'npmDedupe', execSyncOptions: { cwd: workingDirectory } });
(0, cli_utils_1.execute)({ name: 'npmPrune', execSyncOptions: { cwd: workingDirectory } });
}
catch (error) {
console.info(error);
}
}
function formatCode(workingDirectory) {
console.info(`[Info]: Runs npm format`);
try {
(0, cli_utils_1.execute)({ name: 'npmFormat', execSyncOptions: { cwd: workingDirectory } });
}
catch (error) {
console.info(error);
}
}
// filter out option 'interactive' or 'no-interactive'
function filterValidOptions(commandOptions) {
return Object.entries(commandOptions)
.map(([key, option]) => ({ key, value: option }))
.filter(({ key }) => !key.includes('interactive'))
.reduce((options, option) => ({ ...options, [option.key]: option.value }), {});
}
function getApplicationDirectory(projectName) {
return [process.cwd(), projectName].join('/');
}
function configureCommandOptions(newCommand) {
const commandWithOptions = (0, ob_configure_command_1.addObNewCommandOptions)(ob_new_model_1.schema, newCommand);
return addImmutableOptionsText(commandWithOptions);
}
function addImmutableOptionsText(command) {
command.addHelpText('after', '\nThese options are set per default:\n');
const padEnd = 36;
Object.entries(ob_new_model_1.immutableOptions).forEach(([key, flag]) => {
const flagValue = (0, cli_utils_1.buildOption)(key, flag.value);
const newFlagValue = ` --${flagValue}`.padEnd(padEnd, ' ');
command.addHelpText('after', `${newFlagValue} ${flag.description}`);
});
return command;
}