UNPKG

@swell/cli

Version:

Swell's command line interface/utility

140 lines (139 loc) 5.53 kB
import { checkbox } from '@inquirer/prompts'; import { Args, Flags } from '@oclif/core'; import { CreateCollectionCommand } from '../../create-collection-command.js'; import { ConfigType } from '../../lib/apps/index.js'; import { parseFields, parseViews, validateViews, } from '../../lib/create/content.js'; import { toCollectionLabel, toCollectionName, toFileName, } from '../../lib/create/index.js'; import { SCHEMAS } from '../../lib/create/schemas.js'; export default class CreateContent extends CreateCollectionCommand { static args = { collection: Args.string({ default: '', description: 'Collection ID to create or extend (e.g., products)', }), }; static description = 'Interactive mode lets you choose to create a new collection or extend a standard one.\nTo discover standard collections: swell inspect models'; static examples = [ '$ swell create content', '$ swell create content products -y', '$ swell create content visitors -v list,edit,new -f name:short_text,verified:boolean -y', ]; static helpMeta = { usageDirect: '<collection> [...] -y', }; static flags = { label: Flags.string({ char: 'l', default: '', description: 'Display label (default: capitalized collection)', }), description: Flags.string({ char: 'd', default: '', description: 'Description', }), fields: Flags.string({ char: 'f', default: '', description: 'Fields as id:type pairs (e.g., name:short_text,verified:boolean)', }), views: Flags.string({ char: 'v', default: '', description: 'Views to enable: list | edit | new', }), overwrite: Flags.boolean({ default: false, description: 'Overwrite existing file', }), yes: Flags.boolean({ char: 'y', description: 'Skip prompts, require all arguments', }), }; static summary = 'Create a content UI model configuration in the content folder.'; createType = ConfigType.CONTENT; async run() { const { args, flags } = await this.parse(CreateContent); const confirmYes = Boolean(flags.yes); // NON-INTERACTIVE PATH if (confirmYes) { // Validate required arguments const argCollection = args.collection; if (!argCollection) { this.error('Missing required argument for non-interactive mode: COLLECTION\n\nExample: swell create content products -y\n\nTip: run `swell models` to list standard collections you can extend.', { exit: 1 }); } // Process and normalize collection name const collection = toCollectionName(argCollection); // Apply defaults for optional values const label = flags.label || toCollectionLabel(collection); const description = flags.description || ''; // Validate and parse views let viewsList; if (flags.views) { viewsList = flags.views .split(',') .map((v) => v.trim()) .filter(Boolean); validateViews(viewsList, this.error.bind(this)); } else { // Default views when not specified viewsList = ['list', 'edit', 'new']; } // Parse fields (no validation - trust user input) const fieldsRaw = (flags.fields || ''); const fieldPairs = fieldsRaw ? fieldsRaw .split(',') .map((v) => v.trim()) .filter(Boolean) : []; // Build file body const fileName = toFileName(collection); const fileBody = { $schema: SCHEMAS.CONTENT, collection, description, fields: parseFields(fieldPairs), label, views: parseViews(viewsList), }; // Create file with overwrite handling await this.createFile({ fileBody, fileName }, flags.overwrite, /* shouldConfirm */ false); return; } // INTERACTIVE PATH (existing logic) const { collection, description, label } = await this.promptCollection(); const fileName = toFileName(collection); const fileBody = { $schema: SCHEMAS.CONTENT, collection, }; const { fields, overwrite, views } = flags; if (label) { fileBody.label = label; } fileBody.description = description; fileBody.fields = fields ? parseFields(fields.split(',')) : []; if (views) { fileBody.views = views ? parseViews(views.split(',')) : []; } else { const viewsInput = await checkbox({ choices: [ { name: 'List view', value: 'list' }, { name: 'Edit view', value: 'edit' }, { name: 'New view', value: 'new' }, ], message: 'Which views does your content have?', }); fileBody.views = parseViews(viewsInput); } await this.createFile({ fileBody, fileName, }, overwrite); } }