@vendure/cli
Version:
A modern, headless ecommerce framework
229 lines • 11.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.addCommand = addCommand;
const prompts_1 = require("@clack/prompts");
const picocolors_1 = __importDefault(require("picocolors"));
const constants_1 = require("../../constants");
const utils_1 = require("../../utilities/utils");
const command_declarations_1 = require("../command-declarations");
const add_api_extension_1 = require("./api-extension/add-api-extension");
const add_codegen_1 = require("./codegen/add-codegen");
const add_dashboard_1 = require("./dashboard/add-dashboard");
const add_entity_1 = require("./entity/add-entity");
const add_job_queue_1 = require("./job-queue/add-job-queue");
const create_new_plugin_1 = require("./plugin/create-new-plugin");
const add_service_1 = require("./service/add-service");
const add_ui_extensions_1 = require("./ui-extensions/add-ui-extensions");
const cancelledMessage = 'Add feature cancelled.';
async function addCommand(options) {
const nonInteractive = options && Object.values(options).some(v => v !== undefined && v !== false);
if (nonInteractive) {
await handleNonInteractiveMode(options);
}
else {
await handleInteractiveMode();
}
}
async function handleNonInteractiveMode(options) {
try {
if (options.plugin) {
if (typeof options.plugin !== 'string' || !options.plugin.trim()) {
throw new Error('Plugin name is required. Usage: vendure add -p <plugin-name>');
}
await (0, create_new_plugin_1.createNewPlugin)({ name: options.plugin, config: options.config });
prompts_1.log.success(`Plugin "${options.plugin}" created successfully`);
}
else if (options.entity) {
if (typeof options.entity !== 'string' || !options.entity.trim()) {
throw new Error('Entity name is required. Usage: vendure add -e <entity-name> --selected-plugin <plugin-name>');
}
if (!options.selectedPlugin ||
typeof options.selectedPlugin !== 'string' ||
!options.selectedPlugin.trim()) {
throw new Error('Plugin name is required when running in non-interactive mode. Usage: vendure add -e <entity-name> --selected-plugin <plugin-name>');
}
await (0, add_entity_1.addEntity)({
className: options.entity,
isNonInteractive: true,
config: options.config,
pluginName: options.selectedPlugin,
customFields: options.customFields,
translatable: options.translatable,
});
prompts_1.log.success(`Entity "${options.entity}" added successfully to plugin "${options.selectedPlugin}"`);
}
else if (options.service) {
if (typeof options.service !== 'string' || !options.service.trim()) {
throw new Error('Service name is required. Usage: vendure add -s <service-name> --selected-plugin <plugin-name>');
}
if (!options.selectedPlugin ||
typeof options.selectedPlugin !== 'string' ||
!options.selectedPlugin.trim()) {
throw new Error('Plugin name is required when running in non-interactive mode. Usage: vendure add -s <service-name> --selected-plugin <plugin-name>');
}
await (0, add_service_1.addService)({
serviceName: options.service,
isNonInteractive: true,
config: options.config,
pluginName: options.selectedPlugin,
serviceType: options.selectedEntity ? 'entity' : options.type || 'basic',
selectedEntityName: options.selectedEntity,
});
prompts_1.log.success(`Service "${options.service}" added successfully to plugin "${options.selectedPlugin}"`);
}
else if (options.jobQueue) {
const pluginName = typeof options.jobQueue === 'string' ? options.jobQueue : undefined;
if (!options.name || typeof options.name !== 'string' || !options.name.trim()) {
throw new Error('Job queue name is required. Usage: vendure add -j [plugin-name] --name <job-name>');
}
if (!options.selectedService ||
typeof options.selectedService !== 'string' ||
!options.selectedService.trim()) {
throw new Error('Service name is required for job queue. Usage: vendure add -j [plugin-name] --name <job-name> --selected-service <service-name>');
}
await (0, add_job_queue_1.addJobQueue)({
isNonInteractive: true,
config: options.config,
pluginName,
name: options.name,
selectedService: options.selectedService,
});
prompts_1.log.success('Job-queue feature added successfully');
}
else if (options.codegen) {
const pluginName = typeof options.codegen === 'string' ? options.codegen : undefined;
if (typeof options.codegen === 'string' && !options.codegen.trim()) {
throw new Error('Plugin name cannot be empty when specified. Usage: vendure add --codegen [plugin-name]');
}
await (0, add_codegen_1.addCodegen)({
isNonInteractive: true,
config: options.config,
pluginName,
});
prompts_1.log.success('Codegen configuration added successfully');
}
else if (options.apiExtension) {
const pluginName = typeof options.apiExtension === 'string' ? options.apiExtension : undefined;
const hasValidQueryName = options.queryName && typeof options.queryName === 'string' && options.queryName.trim() !== '';
const hasValidMutationName = options.mutationName &&
typeof options.mutationName === 'string' &&
options.mutationName.trim() !== '';
if (!hasValidQueryName && !hasValidMutationName) {
throw new Error('At least one of query-name or mutation-name must be specified as a non-empty string. ' +
'Usage: vendure add -a [plugin-name] --query-name <name> --mutation-name <name>');
}
if (typeof options.apiExtension === 'string' && !options.apiExtension.trim()) {
throw new Error('Plugin name cannot be empty when specified. ' +
'Usage: vendure add -a [plugin-name] --query-name <name> --mutation-name <name>');
}
await (0, add_api_extension_1.addApiExtension)({
isNonInteractive: true,
config: options.config,
pluginName,
queryName: options.queryName,
mutationName: options.mutationName,
selectedService: options.selectedService,
});
prompts_1.log.success('API extension scaffold added successfully');
}
else if (options.uiExtensions) {
const pluginName = typeof options.uiExtensions === 'string' ? options.uiExtensions : undefined;
if (typeof options.uiExtensions === 'string' && !options.uiExtensions.trim()) {
throw new Error('Plugin name cannot be empty when specified. Usage: vendure add --ui-extensions [plugin-name]');
}
await (0, add_ui_extensions_1.addUiExtensions)({
isNonInteractive: true,
config: options.config,
pluginName,
});
prompts_1.log.success('UI extensions added successfully');
}
else if (options.dashboard) {
const pluginName = typeof options.dashboard === 'string' ? options.dashboard : undefined;
if (typeof options.uiExtensions === 'string' && !options.uiExtensions.trim()) {
throw new Error('Plugin name cannot be empty when specified. Usage: vendure add --dashboard [plugin-name]');
}
await (0, add_dashboard_1.addDashboard)({
isNonInteractive: true,
config: options.config,
pluginName,
});
prompts_1.log.success('Dashboard extensions added successfully');
}
else {
prompts_1.log.error('No valid add operation specified');
process.exit(1);
}
}
catch (e) {
if (e.message.includes('Plugin name is required')) {
const errorMessage = e.message;
const stackLines = e.stack.split('\n');
const stackTrace = stackLines.slice(1).join('\n');
prompts_1.log.error(stackTrace);
prompts_1.log.error('');
prompts_1.log.error(picocolors_1.default.red('Error:') + ' ' + String(errorMessage));
}
else {
prompts_1.log.error(e.message);
if (e.stack) {
prompts_1.log.error(e.stack);
}
}
process.exit(1);
}
}
async function handleInteractiveMode() {
var _a, _b;
console.log(`\n`);
(0, prompts_1.intro)(picocolors_1.default.blue("✨ Let's add a new feature to your Vendure project!"));
const addCommandDef = command_declarations_1.cliCommands.find(cmd => cmd.name === 'add');
const addOptions = (_b = (_a = addCommandDef === null || addCommandDef === void 0 ? void 0 : addCommandDef.options) === null || _a === void 0 ? void 0 : _a.filter(opt => opt.interactiveId && opt.interactiveFn).map(opt => ({
value: opt.interactiveId,
label: `${picocolors_1.default.blue(opt.interactiveCategory)} ${opt.description}`,
fn: opt.interactiveFn,
}))) !== null && _b !== void 0 ? _b : [];
const featureType = await (0, utils_1.withInteractiveTimeout)(async () => {
return await (0, prompts_1.select)({
message: 'Which feature would you like to add?',
options: addOptions.map(opt => ({
value: opt.value,
label: opt.label,
})),
});
});
if ((0, prompts_1.isCancel)(featureType)) {
(0, prompts_1.cancel)(cancelledMessage);
process.exit(0);
}
try {
const selectedOption = addOptions.find(opt => opt.value === featureType);
if (!selectedOption) {
throw new Error(`Could not find command with id "${featureType}"`);
}
const { modifiedSourceFiles, project } = await selectedOption.fn();
if (modifiedSourceFiles.length) {
const importsSpinner = (0, prompts_1.spinner)();
importsSpinner.start('Organizing imports...');
await (0, utils_1.pauseForPromptDisplay)();
for (const sourceFile of modifiedSourceFiles) {
sourceFile.organizeImports();
}
await project.save();
importsSpinner.stop('Imports organized');
}
(0, prompts_1.outro)('✅ Done!');
}
catch (e) {
prompts_1.log.error(e.message);
const isCliMessage = Object.values(constants_1.Messages).includes(e.message);
if (!isCliMessage && e.stack) {
prompts_1.log.error(e.stack);
}
(0, prompts_1.outro)('❌ Error');
}
}
//# sourceMappingURL=add.js.map