From f8d71dc20ba12155c5f50c8bc07cf57db719e5e8 Mon Sep 17 00:00:00 2001 From: Edu Wass Date: Tue, 10 Dec 2024 16:47:45 +0100 Subject: [PATCH 1/3] WIP: Add support for custom prompts in block creation Enhance the create-block functionality allowing the inclusion of custom prompts. This change enables template configurations to specify additional prompts beyond the built-in ones, facilitating more flexible block creation. - Validate custom prompts for required properties: type, name, and message. - Merge custom prompts with built-in prompts to offer a comprehensive query set. - Ensure compatibility with existing template definitions by handling cases with null or non-object customPrompts gracefully. --- packages/create-block/lib/index.js | 30 ++++++++++++++---------- packages/create-block/lib/templates.js | 32 ++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/packages/create-block/lib/index.js b/packages/create-block/lib/index.js index da08bcd4ab1dc7..ee20f31a7b3163 100644 --- a/packages/create-block/lib/index.js +++ b/packages/create-block/lib/index.js @@ -150,18 +150,24 @@ program const filterOptionsProvided = ( { name } ) => ! Object.keys( optionsValues ).includes( name ); - const blockPrompts = getPrompts( - pluginTemplate, - [ - 'slug', - 'namespace', - 'title', - 'description', - 'dashicon', - 'category', - ], - variant - ).filter( filterOptionsProvided ); + const blockPrompts = [ + // Get built-in block prompts + ...getPrompts( + pluginTemplate, + [ + 'slug', + 'namespace', + 'title', + 'description', + 'dashicon', + 'category', + ], + variant + ), + // Get custom prompts + ...getPrompts(pluginTemplate, null, variant) + ].filter( filterOptionsProvided ); + const blockAnswers = await inquirer.prompt( blockPrompts ); const pluginAnswers = plugin diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js index 4e70ee66fd3a40..fc29ffde6213cf 100644 --- a/packages/create-block/lib/templates.js +++ b/packages/create-block/lib/templates.js @@ -124,12 +124,24 @@ const configToTemplate = async ( { assetsPath, defaultValues = {}, variants = {}, + customPrompts = {}, ...deprecated } ) => { if ( defaultValues === null || typeof defaultValues !== 'object' ) { throw new CLIError( 'Template found but invalid definition provided.' ); } + if (customPrompts !== null && typeof customPrompts !== 'object') { + throw new CLIError( 'Invalid custom prompts definition provided.' ); + } + + // Validate custom prompts format + for (const [name, prompt] of Object.entries(customPrompts)) { + if (!prompt.type || !prompt.name || !prompt.message) { + throw new CLIError(`Invalid custom prompt "${name}". Each prompt must have type, name, and message properties.`); + } + } + if ( deprecated.templatesPath ) { pluginTemplatesPath = deprecated.templatesPath; defaultValues = { @@ -154,6 +166,7 @@ const configToTemplate = async ( { outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {}, defaultValues, variants, + customPrompts, }; }; @@ -251,12 +264,27 @@ const getDefaultValues = ( pluginTemplate, variant ) => { const getPrompts = ( pluginTemplate, keys, variant ) => { const defaultValues = getDefaultValues( pluginTemplate, variant ); - return keys.map( ( promptName ) => { + + // Get built-in prompts if keys are provided + const builtInPrompts = keys ? keys.map( ( promptName ) => { return { ...prompts[ promptName ], default: defaultValues[ promptName ], }; - } ); + }) : []; + + // Add custom prompts if they exist + const customPromptsList = []; + if (pluginTemplate.customPrompts) { + for (const [name, prompt] of Object.entries(pluginTemplate.customPrompts)) { + customPromptsList.push({ + ...prompt, + default: defaultValues[name], + }); + } + } + + return [...builtInPrompts, ...customPromptsList]; }; const getVariantVars = ( variants, variant ) => { From efe3c1267674f7622ce4139e5fd05a56bc3c1d12 Mon Sep 17 00:00:00 2001 From: Edu Wass Date: Tue, 10 Dec 2024 17:36:25 +0100 Subject: [PATCH 2/3] Improve the handling of custom prompts to streamline their integration into the block creation process. - Merge built-in and custom prompts into a single array. - Allow custom prompts to be included wherever keys are specified. - Ensure default values for custom prompts are correctly retrieved and utilized. - Simplify the logic for aggregating both built-in and custom prompts into a single comprehensive list. This change enhances flexibility for developers using custom prompts with create-block. --- packages/create-block/lib/index.js | 33 +++++++++---------- packages/create-block/lib/scaffold.js | 2 ++ packages/create-block/lib/templates.js | 45 ++++++++++++++++---------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/packages/create-block/lib/index.js b/packages/create-block/lib/index.js index ee20f31a7b3163..fb3f3110459f90 100644 --- a/packages/create-block/lib/index.js +++ b/packages/create-block/lib/index.js @@ -150,23 +150,21 @@ program const filterOptionsProvided = ( { name } ) => ! Object.keys( optionsValues ).includes( name ); - const blockPrompts = [ - // Get built-in block prompts - ...getPrompts( - pluginTemplate, - [ - 'slug', - 'namespace', - 'title', - 'description', - 'dashicon', - 'category', - ], - variant - ), - // Get custom prompts - ...getPrompts(pluginTemplate, null, variant) - ].filter( filterOptionsProvided ); + + // Get all prompts in one call + const blockPrompts = getPrompts( + pluginTemplate, + [ + 'slug', + 'namespace', + 'title', + 'description', + 'dashicon', + 'category', + ...(pluginTemplate.customPrompts ? Object.keys(pluginTemplate.customPrompts) : []) + ], + variant + ).filter( filterOptionsProvided ); const blockAnswers = await inquirer.prompt( blockPrompts ); @@ -195,6 +193,7 @@ program 'domainPath', 'updateURI', ], + ...(pluginTemplate.customPrompts ? Object.keys(pluginTemplate.customPrompts) : []), variant ).filter( filterOptionsProvided ); const result = diff --git a/packages/create-block/lib/scaffold.js b/packages/create-block/lib/scaffold.js index 73b9f549908867..71471036e44bcf 100644 --- a/packages/create-block/lib/scaffold.js +++ b/packages/create-block/lib/scaffold.js @@ -54,6 +54,7 @@ module.exports = async ( customBlockJSON, example, transformer, + ...customPromptValues } ) => { slug = slug.toLowerCase(); @@ -97,6 +98,7 @@ module.exports = async ( example, textdomain: slug, rootDirectory, + ...customPromptValues } ); const view = { diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js index fc29ffde6213cf..c03d10b7770f60 100644 --- a/packages/create-block/lib/templates.js +++ b/packages/create-block/lib/templates.js @@ -238,6 +238,14 @@ const getPluginTemplate = async ( templateName ) => { }; const getDefaultValues = ( pluginTemplate, variant ) => { + // Get custom prompt default values + const customPromptDefaults = {}; + if (pluginTemplate.customPrompts) { + for (const [name, prompt] of Object.entries(pluginTemplate.customPrompts)) { + customPromptDefaults[name] = prompt.default || ''; + } + } + return { $schema: 'https://schemas.wp.org/trunk/block.json', apiVersion: 3, @@ -256,6 +264,7 @@ const getDefaultValues = ( pluginTemplate, variant ) => { editorStyle: 'file:./index.css', style: 'file:./style-index.css', transformer: ( view ) => view, + ...customPromptDefaults, ...pluginTemplate.defaultValues, ...pluginTemplate.variants?.[ variant ], variantVars: getVariantVars( pluginTemplate.variants, variant ), @@ -264,27 +273,29 @@ const getDefaultValues = ( pluginTemplate, variant ) => { const getPrompts = ( pluginTemplate, keys, variant ) => { const defaultValues = getDefaultValues( pluginTemplate, variant ); - - // Get built-in prompts if keys are provided - const builtInPrompts = keys ? keys.map( ( promptName ) => { - return { - ...prompts[ promptName ], - default: defaultValues[ promptName ], - }; - }) : []; + let allPrompts = []; - // Add custom prompts if they exist - const customPromptsList = []; - if (pluginTemplate.customPrompts) { - for (const [name, prompt] of Object.entries(pluginTemplate.customPrompts)) { - customPromptsList.push({ - ...prompt, - default: defaultValues[name], - }); + // Add built-in prompts if keys are provided + if (keys && keys.length > 0) { + for (const key of keys) { + // If it's a built-in prompt + if (prompts[key]) { + allPrompts.push({ + ...prompts[key], + default: defaultValues[key], + }); + } + // If it's a custom prompt + else if (pluginTemplate.customPrompts?.[key]) { + allPrompts.push({ + ...pluginTemplate.customPrompts[key], + default: defaultValues[key] || pluginTemplate.customPrompts[key].default || '', + }); + } } } - return [...builtInPrompts, ...customPromptsList]; + return allPrompts; }; const getVariantVars = ( variants, variant ) => { From 652bc2c49c934d15da65956633abadc9ee08ba36 Mon Sep 17 00:00:00 2001 From: Edu Wass Date: Sat, 21 Dec 2024 16:49:22 +0100 Subject: [PATCH 3/3] Apply whitespace fixing suggestions from code review Co-authored-by: Ryan Welcher --- packages/create-block/lib/index.js | 4 +-- packages/create-block/lib/templates.js | 34 +++++++++++++------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/create-block/lib/index.js b/packages/create-block/lib/index.js index fb3f3110459f90..200f08dc8fc903 100644 --- a/packages/create-block/lib/index.js +++ b/packages/create-block/lib/index.js @@ -161,7 +161,7 @@ program 'description', 'dashicon', 'category', - ...(pluginTemplate.customPrompts ? Object.keys(pluginTemplate.customPrompts) : []) + ...( pluginTemplate.customPrompts ? Object.keys( pluginTemplate.customPrompts ) : [] ) ], variant ).filter( filterOptionsProvided ); @@ -193,7 +193,7 @@ program 'domainPath', 'updateURI', ], - ...(pluginTemplate.customPrompts ? Object.keys(pluginTemplate.customPrompts) : []), + ...( pluginTemplate.customPrompts ? Object.keys( pluginTemplate.customPrompts ) : [] ), variant ).filter( filterOptionsProvided ); const result = diff --git a/packages/create-block/lib/templates.js b/packages/create-block/lib/templates.js index c03d10b7770f60..32bcf0f52963bd 100644 --- a/packages/create-block/lib/templates.js +++ b/packages/create-block/lib/templates.js @@ -131,14 +131,14 @@ const configToTemplate = async ( { throw new CLIError( 'Template found but invalid definition provided.' ); } - if (customPrompts !== null && typeof customPrompts !== 'object') { + if ( customPrompts !== null && typeof customPrompts !== 'object' ) { throw new CLIError( 'Invalid custom prompts definition provided.' ); } // Validate custom prompts format - for (const [name, prompt] of Object.entries(customPrompts)) { - if (!prompt.type || !prompt.name || !prompt.message) { - throw new CLIError(`Invalid custom prompt "${name}". Each prompt must have type, name, and message properties.`); + for ( const [name, prompt] of Object.entries( customPrompts ) ) { + if ( ! prompt.type || ! prompt.name || ! prompt.message ) { + throw new CLIError( `Invalid custom prompt "${name}". Each prompt must have type, name, and message properties.` ); } } @@ -240,9 +240,9 @@ const getPluginTemplate = async ( templateName ) => { const getDefaultValues = ( pluginTemplate, variant ) => { // Get custom prompt default values const customPromptDefaults = {}; - if (pluginTemplate.customPrompts) { - for (const [name, prompt] of Object.entries(pluginTemplate.customPrompts)) { - customPromptDefaults[name] = prompt.default || ''; + if ( pluginTemplate.customPrompts ) { + for ( const [ name, prompt ] of Object.entries( pluginTemplate.customPrompts ) ) { + customPromptDefaults[ name ] = prompt.default || ''; } } @@ -276,20 +276,20 @@ const getPrompts = ( pluginTemplate, keys, variant ) => { let allPrompts = []; // Add built-in prompts if keys are provided - if (keys && keys.length > 0) { - for (const key of keys) { + if ( keys && keys.length > 0 ) { + for ( const key of keys ) { // If it's a built-in prompt - if (prompts[key]) { - allPrompts.push({ - ...prompts[key], - default: defaultValues[key], + if ( prompts[ key ] ) { + allPrompts.push( { + ...prompts[ key ], + default: defaultValues[ key ], }); } // If it's a custom prompt - else if (pluginTemplate.customPrompts?.[key]) { - allPrompts.push({ - ...pluginTemplate.customPrompts[key], - default: defaultValues[key] || pluginTemplate.customPrompts[key].default || '', + else if ( pluginTemplate.customPrompts?.[ key ] ) { + allPrompts.push( { + ...pluginTemplate.customPrompts[ key ], + default: defaultValues[ key ] || pluginTemplate.customPrompts[ key ].default || '', }); } }