| 13 | * @returns a void promise |
| 14 | */ |
| 15 | export const taskGenerate = async (config: ValidatedConfig): Promise<void> => { |
| 16 | if (!config.configPath) { |
| 17 | config.logger.error('Please run this command in your root directory (i. e. the one containing stencil.config.ts).'); |
| 18 | return config.sys.exit(1); |
| 19 | } |
| 20 | |
| 21 | const absoluteSrcDir = config.srcDir; |
| 22 | |
| 23 | if (!absoluteSrcDir) { |
| 24 | config.logger.error(`Stencil's srcDir was not specified.`); |
| 25 | return config.sys.exit(1); |
| 26 | } |
| 27 | |
| 28 | const { prompt } = await import('prompts'); |
| 29 | |
| 30 | const input = |
| 31 | config.flags.unknownArgs.find((arg) => !arg.startsWith('-')) || |
| 32 | ((await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName as string); |
| 33 | |
| 34 | if (undefined === input) { |
| 35 | // in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console. |
| 36 | // explicitly return here to avoid printing the error message. |
| 37 | return; |
| 38 | } |
| 39 | const { dir, base: componentName } = parse(input); |
| 40 | |
| 41 | const tagError = validateComponentTag(componentName); |
| 42 | if (tagError) { |
| 43 | config.logger.error(tagError); |
| 44 | return config.sys.exit(1); |
| 45 | } |
| 46 | |
| 47 | let cssExtension: GeneratableStylingExtension = 'css'; |
| 48 | if (!!config.plugins.find((plugin) => plugin.name === 'sass')) { |
| 49 | cssExtension = await chooseSassExtension(); |
| 50 | } else if (!!config.plugins.find((plugin) => plugin.name === 'less')) { |
| 51 | cssExtension = 'less'; |
| 52 | } |
| 53 | const filesToGenerateExt = await chooseFilesToGenerate(cssExtension); |
| 54 | if (!filesToGenerateExt) { |
| 55 | // in some shells (e.g. Windows PowerShell), hitting Ctrl+C results in a TypeError printed to the console. |
| 56 | // explicitly return here to avoid printing the error message. |
| 57 | return; |
| 58 | } |
| 59 | const extensionsToGenerate: GeneratableExtension[] = ['tsx', ...filesToGenerateExt]; |
| 60 | const testFolder = extensionsToGenerate.some(isTest) ? 'test' : ''; |
| 61 | |
| 62 | const outDir = join(absoluteSrcDir, 'components', dir, componentName); |
| 63 | await config.sys.createDir(normalizePath(join(outDir, testFolder)), { recursive: true }); |
| 64 | |
| 65 | const filesToGenerate: readonly BoilerplateFile[] = extensionsToGenerate.map((extension) => ({ |
| 66 | extension, |
| 67 | path: getFilepathForFile(outDir, componentName, extension), |
| 68 | })); |
| 69 | await checkForOverwrite(filesToGenerate, config); |
| 70 | |
| 71 | const writtenFiles = await Promise.all( |
| 72 | filesToGenerate.map((file) => |