@wordpress/create-block 4.57.0 → 4.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ## Gutenberg
2
2
 
3
- Copyright 2016-2024 by the contributors
3
+ Copyright 2016-2025 by the contributors
4
4
 
5
5
  **License for Contributions (on and after April 15, 2021)**
6
6
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- const inquirer = require( 'inquirer' );
4
+ const { confirm } = require( '@inquirer/prompts' );
5
5
  const checkSync = require( 'check-node-version' );
6
6
  const tools = require( 'check-node-version/tools' );
7
7
  const { promisify } = require( 'util' );
@@ -34,14 +34,10 @@ async function checkSystemRequirements( engines ) {
34
34
  log.error( 'The program may not complete correctly if you continue.' );
35
35
  log.info( '' );
36
36
 
37
- const { yesContinue } = await inquirer.prompt( [
38
- {
39
- type: 'confirm',
40
- name: 'yesContinue',
41
- message: 'Are you sure you want to continue anyway?',
42
- default: false,
43
- },
44
- ] );
37
+ const yesContinue = await confirm( {
38
+ message: 'Are you sure you want to continue anyway?',
39
+ default: false,
40
+ } );
45
41
 
46
42
  if ( ! yesContinue ) {
47
43
  log.error( 'Cancelled.' );
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- const inquirer = require( 'inquirer' );
4
+ const { confirm, select } = require( '@inquirer/prompts' );
5
5
  const { capitalCase } = require( 'change-case' );
6
6
  const program = require( 'commander' );
7
7
 
@@ -14,9 +14,9 @@ const log = require( './log' );
14
14
  const { engines, version } = require( '../package.json' );
15
15
  const scaffold = require( './scaffold' );
16
16
  const {
17
- getPluginTemplate,
18
17
  getDefaultValues,
19
- getPrompts,
18
+ getProjectTemplate,
19
+ runPrompts,
20
20
  } = require( './templates' );
21
21
 
22
22
  const commandName = `wp-create-block`;
@@ -79,11 +79,13 @@ program
79
79
  targetDir,
80
80
  }
81
81
  ) => {
82
- await checkSystemRequirements( engines );
83
82
  try {
84
- const pluginTemplate = await getPluginTemplate( templateName );
83
+ await checkSystemRequirements( engines );
84
+
85
+ const projectTemplate =
86
+ await getProjectTemplate( templateName );
85
87
  const availableVariants = Object.keys(
86
- pluginTemplate.variants
88
+ projectTemplate.variants
87
89
  );
88
90
  if ( variant && ! availableVariants.includes( variant ) ) {
89
91
  if ( ! availableVariants.length ) {
@@ -113,7 +115,7 @@ program
113
115
 
114
116
  if ( slug ) {
115
117
  const defaultValues = getDefaultValues(
116
- pluginTemplate,
118
+ projectTemplate,
117
119
  variant
118
120
  );
119
121
  const answers = {
@@ -123,7 +125,7 @@ program
123
125
  title: capitalCase( slug ),
124
126
  ...optionsValues,
125
127
  };
126
- await scaffold( pluginTemplate, answers );
128
+ await scaffold( projectTemplate, answers );
127
129
  } else {
128
130
  log.info( '' );
129
131
  log.info(
@@ -133,25 +135,22 @@ program
133
135
  );
134
136
 
135
137
  if ( ! variant && availableVariants.length > 1 ) {
136
- const result = await inquirer.prompt( {
137
- type: 'list',
138
- name: 'variant',
138
+ variant = await select( {
139
139
  message:
140
140
  'The template variant to use for this block:',
141
- choices: availableVariants,
141
+ choices: availableVariants.map( ( value ) => ( {
142
+ value,
143
+ } ) ),
142
144
  } );
143
- variant = result.variant;
144
145
  }
145
146
 
146
147
  const defaultValues = getDefaultValues(
147
- pluginTemplate,
148
+ projectTemplate,
148
149
  variant
149
150
  );
150
151
 
151
- const filterOptionsProvided = ( { name } ) =>
152
- ! Object.keys( optionsValues ).includes( name );
153
- const blockPrompts = getPrompts(
154
- pluginTemplate,
152
+ const blockAnswers = await runPrompts(
153
+ projectTemplate,
155
154
  [
156
155
  'slug',
157
156
  'namespace',
@@ -159,45 +158,36 @@ program
159
158
  'description',
160
159
  'dashicon',
161
160
  'category',
162
- ],
163
- variant
164
- ).filter( filterOptionsProvided );
165
- const blockAnswers = await inquirer.prompt( blockPrompts );
166
-
167
- const pluginAnswers = plugin
168
- ? await inquirer
169
- .prompt( {
170
- type: 'confirm',
171
- name: 'configurePlugin',
172
- message:
173
- 'Do you want to customize the WordPress plugin?',
174
- default: false,
175
- } )
176
- .then( async ( { configurePlugin } ) => {
177
- if ( ! configurePlugin ) {
178
- return {};
179
- }
161
+ ! plugin && 'textdomain',
162
+ ].filter( Boolean ),
163
+ variant,
164
+ optionsValues
165
+ );
180
166
 
181
- const pluginPrompts = getPrompts(
182
- pluginTemplate,
183
- [
184
- 'pluginURI',
185
- 'version',
186
- 'author',
187
- 'license',
188
- 'licenseURI',
189
- 'domainPath',
190
- 'updateURI',
191
- ],
192
- variant
193
- ).filter( filterOptionsProvided );
194
- const result =
195
- await inquirer.prompt( pluginPrompts );
196
- return result;
197
- } )
198
- : {};
167
+ const pluginAnswers =
168
+ plugin &&
169
+ ( await confirm( {
170
+ message:
171
+ 'Do you want to customize the WordPress plugin?',
172
+ default: false,
173
+ } ) )
174
+ ? await runPrompts(
175
+ projectTemplate,
176
+ [
177
+ 'pluginURI',
178
+ 'version',
179
+ 'author',
180
+ 'license',
181
+ 'licenseURI',
182
+ 'domainPath',
183
+ 'updateURI',
184
+ ],
185
+ variant,
186
+ optionsValues
187
+ )
188
+ : {};
199
189
 
200
- await scaffold( pluginTemplate, {
190
+ await scaffold( projectTemplate, {
201
191
  ...defaultValues,
202
192
  ...optionsValues,
203
193
  variant,
@@ -209,6 +199,9 @@ program
209
199
  if ( error instanceof CLIError ) {
210
200
  log.error( error.message );
211
201
  process.exit( 1 );
202
+ } else if ( error.name === 'ExitPromptError' ) {
203
+ log.info( 'Cancelled.' );
204
+ process.exit( 1 );
212
205
  } else {
213
206
  throw error;
214
207
  }
package/lib/prompts.js CHANGED
@@ -11,7 +11,6 @@ const upperFirst = ( [ firstLetter, ...rest ] ) =>
11
11
  // Block metadata.
12
12
  const slug = {
13
13
  type: 'input',
14
- name: 'slug',
15
14
  message:
16
15
  'The block slug used for identification (also the output folder name):',
17
16
  validate( input ) {
@@ -25,7 +24,6 @@ const slug = {
25
24
 
26
25
  const namespace = {
27
26
  type: 'input',
28
- name: 'namespace',
29
27
  message:
30
28
  'The internal namespace for the block name (something unique for your products):',
31
29
  validate( input ) {
@@ -39,25 +37,22 @@ const namespace = {
39
37
 
40
38
  const title = {
41
39
  type: 'input',
42
- name: 'title',
43
40
  message: 'The display title for your block:',
44
- filter( input ) {
41
+ transformer( input ) {
45
42
  return input && upperFirst( input );
46
43
  },
47
44
  };
48
45
 
49
46
  const description = {
50
47
  type: 'input',
51
- name: 'description',
52
48
  message: 'The short description for your block (optional):',
53
- filter( input ) {
49
+ transformer( input ) {
54
50
  return input && upperFirst( input );
55
51
  },
56
52
  };
57
53
 
58
54
  const dashicon = {
59
55
  type: 'input',
60
- name: 'dashicon',
61
56
  message:
62
57
  'The dashicon to make it easier to identify your block (optional):',
63
58
  validate( input ) {
@@ -67,29 +62,41 @@ const dashicon = {
67
62
 
68
63
  return true;
69
64
  },
70
- filter( input ) {
65
+ transformer( input ) {
71
66
  return input && input.replace( /dashicon(s)?-/, '' );
72
67
  },
73
68
  };
74
69
 
75
70
  const category = {
76
- type: 'list',
77
- name: 'category',
71
+ type: 'select',
78
72
  message: 'The category name to help users browse and discover your block:',
79
- choices: [ 'text', 'media', 'design', 'widgets', 'theme', 'embed' ],
73
+ choices: [ 'text', 'media', 'design', 'widgets', 'theme', 'embed' ].map(
74
+ ( value ) => ( { value } )
75
+ ),
76
+ };
77
+
78
+ const textdomain = {
79
+ type: 'input',
80
+ message:
81
+ 'The text domain used to make strings translatable in the block (optional):',
82
+ validate( input ) {
83
+ if ( input.length && ! /^[a-z][a-z0-9\-]*$/.test( input ) ) {
84
+ return 'Invalid text domain specified. Text domain can contain only lowercase alphanumeric characters or dashes, and start with a letter.';
85
+ }
86
+
87
+ return true;
88
+ },
80
89
  };
81
90
 
82
91
  // Plugin header fields.
83
92
  const pluginURI = {
84
93
  type: 'input',
85
- name: 'pluginURI',
86
94
  message:
87
95
  'The home page of the plugin (optional). Unique URL outside of WordPress.org:',
88
96
  };
89
97
 
90
98
  const version = {
91
99
  type: 'input',
92
- name: 'version',
93
100
  message: 'The current version number of the plugin:',
94
101
  validate( input ) {
95
102
  // Regular expression was copied from https://semver.org.
@@ -105,32 +112,27 @@ const version = {
105
112
 
106
113
  const author = {
107
114
  type: 'input',
108
- name: 'author',
109
115
  message:
110
116
  'The name of the plugin author (optional). Multiple authors may be listed using commas:',
111
117
  };
112
118
 
113
119
  const license = {
114
120
  type: 'input',
115
- name: 'license',
116
121
  message: 'The short name of the plugin’s license (optional):',
117
122
  };
118
123
 
119
124
  const licenseURI = {
120
125
  type: 'input',
121
- name: 'licenseURI',
122
126
  message: 'A link to the full text of the license (optional):',
123
127
  };
124
128
 
125
129
  const domainPath = {
126
130
  type: 'input',
127
- name: 'domainPath',
128
131
  message: 'A custom domain path for the translations (optional):',
129
132
  };
130
133
 
131
134
  const updateURI = {
132
135
  type: 'input',
133
- name: 'updateURI',
134
136
  message: 'A custom update URI for the plugin (optional):',
135
137
  };
136
138
 
@@ -141,6 +143,7 @@ module.exports = {
141
143
  description,
142
144
  dashicon,
143
145
  category,
146
+ textdomain,
144
147
  pluginURI,
145
148
  version,
146
149
  author,
package/lib/scaffold.js CHANGED
@@ -26,6 +26,7 @@ module.exports = async (
26
26
  description,
27
27
  dashicon,
28
28
  category,
29
+ textdomain,
29
30
  attributes,
30
31
  supports,
31
32
  author,
@@ -35,6 +36,9 @@ module.exports = async (
35
36
  domainPath,
36
37
  updateURI,
37
38
  version,
39
+ requiresAtLeast,
40
+ requiresPHP,
41
+ testedUpTo,
38
42
  wpScripts,
39
43
  wpEnv,
40
44
  npmDependencies,
@@ -57,13 +61,12 @@ module.exports = async (
57
61
  }
58
62
  ) => {
59
63
  slug = slug.toLowerCase();
60
- namespace = namespace.toLowerCase();
61
64
  const rootDirectory = join( process.cwd(), targetDir || slug );
62
65
  const transformedValues = transformer( {
63
66
  $schema,
64
67
  apiVersion,
65
68
  plugin,
66
- namespace,
69
+ namespace: namespace.toLowerCase(),
67
70
  slug,
68
71
  title,
69
72
  description,
@@ -78,12 +81,15 @@ module.exports = async (
78
81
  domainPath,
79
82
  updateURI,
80
83
  version,
84
+ requiresAtLeast,
85
+ requiresPHP,
86
+ testedUpTo,
81
87
  wpScripts,
82
88
  wpEnv,
83
89
  npmDependencies,
84
90
  npmDevDependencies,
85
91
  customScripts,
86
- folderName,
92
+ folderName: folderName.replace( /\$slug/g, slug ),
87
93
  editorScript,
88
94
  editorStyle,
89
95
  style,
@@ -95,7 +101,7 @@ module.exports = async (
95
101
  customPackageJSON,
96
102
  customBlockJSON,
97
103
  example,
98
- textdomain: slug,
104
+ textdomain: textdomain || slug,
99
105
  rootDirectory,
100
106
  } );
101
107
 
@@ -7,9 +7,13 @@
7
7
  {{#description}}
8
8
  * Description: {{description}}
9
9
  {{/description}}
10
- * Requires at least: 6.6
11
- * Requires PHP: 7.2
12
10
  * Version: {{version}}
11
+ {{#requiresAtLeast}}
12
+ * Requires at least: {{requiresAtLeast}}
13
+ {{/requiresAtLeast}}
14
+ {{#requiresPHP}}
15
+ * Requires PHP: {{requiresPHP}}
16
+ {{/requiresPHP}}
13
17
  {{#author}}
14
18
  * Author: {{author}}
15
19
  {{/author}}
@@ -3,7 +3,9 @@
3
3
  Contributors: {{author}}
4
4
  {{/author}}
5
5
  Tags: block
6
- Tested up to: 6.6
6
+ {{#testedUpTo}}
7
+ Tested up to: {{testedUpTo}}
8
+ {{/testedUpTo}}
7
9
  Stable tag: {{version}}
8
10
  {{#license}}
9
11
  License: {{license}}
@@ -7,9 +7,13 @@
7
7
  {{#description}}
8
8
  * Description: {{description}}
9
9
  {{/description}}
10
- * Requires at least: 6.6
11
- * Requires PHP: 7.2
12
10
  * Version: {{version}}
11
+ {{#requiresAtLeast}}
12
+ * Requires at least: {{requiresAtLeast}}
13
+ {{/requiresAtLeast}}
14
+ {{#requiresPHP}}
15
+ * Requires PHP: {{requiresPHP}}
16
+ {{/requiresPHP}}
13
17
  {{#author}}
14
18
  * Author: {{author}}
15
19
  {{/author}}
@@ -42,6 +46,6 @@ if ( ! defined( 'ABSPATH' ) ) {
42
46
  * @see https://developer.wordpress.org/reference/functions/register_block_type/
43
47
  */
44
48
  function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() {
45
- register_block_type( __DIR__ . '/build' );
49
+ register_block_type( __DIR__ . '/build/{{slug}}' );
46
50
  }
47
51
  add_action( 'init', '{{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init' );
@@ -3,7 +3,9 @@
3
3
  Contributors: {{author}}
4
4
  {{/author}}
5
5
  Tags: block
6
- Tested up to: 6.6
6
+ {{#testedUpTo}}
7
+ Tested up to: {{testedUpTo}}
8
+ {{/testedUpTo}}
7
9
  Stable tag: {{version}}
8
10
  {{#license}}
9
11
  License: {{license}}
package/lib/templates.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
+ const inquirer = require( '@inquirer/prompts' );
4
5
  const { command } = require( 'execa' );
5
6
  const glob = require( 'fast-glob' );
6
7
  const { resolve } = require( 'path' );
@@ -58,6 +59,7 @@ const predefinedPluginTemplates = {
58
59
  },
59
60
  viewScript: 'file:./view.js',
60
61
  example: {},
62
+ folderName: './src/$slug',
61
63
  },
62
64
  variants: {
63
65
  static: {},
@@ -157,7 +159,7 @@ const configToTemplate = async ( {
157
159
  };
158
160
  };
159
161
 
160
- const getPluginTemplate = async ( templateName ) => {
162
+ const getProjectTemplate = async ( templateName ) => {
161
163
  if ( predefinedPluginTemplates[ templateName ] ) {
162
164
  return await configToTemplate(
163
165
  predefinedPluginTemplates[ templateName ]
@@ -224,16 +226,20 @@ const getPluginTemplate = async ( templateName ) => {
224
226
  }
225
227
  };
226
228
 
227
- const getDefaultValues = ( pluginTemplate, variant ) => {
229
+ const getDefaultValues = ( projectTemplate, variant ) => {
228
230
  return {
229
231
  $schema: 'https://schemas.wp.org/trunk/block.json',
230
232
  apiVersion: 3,
231
233
  namespace: 'create-block',
232
234
  category: 'widgets',
235
+ textdomain: '',
233
236
  author: 'The WordPress Contributors',
234
237
  license: 'GPL-2.0-or-later',
235
238
  licenseURI: 'https://www.gnu.org/licenses/gpl-2.0.html',
236
239
  version: '0.1.0',
240
+ requiresAtLeast: '6.7',
241
+ requiresPHP: '7.4',
242
+ testedUpTo: '6.7',
237
243
  wpScripts: true,
238
244
  customScripts: {},
239
245
  wpEnv: false,
@@ -243,20 +249,33 @@ const getDefaultValues = ( pluginTemplate, variant ) => {
243
249
  editorStyle: 'file:./index.css',
244
250
  style: 'file:./style-index.css',
245
251
  transformer: ( view ) => view,
246
- ...pluginTemplate.defaultValues,
247
- ...pluginTemplate.variants?.[ variant ],
248
- variantVars: getVariantVars( pluginTemplate.variants, variant ),
252
+ ...projectTemplate.defaultValues,
253
+ ...projectTemplate.variants?.[ variant ],
254
+ variantVars: getVariantVars( projectTemplate.variants, variant ),
249
255
  };
250
256
  };
251
257
 
252
- const getPrompts = ( pluginTemplate, keys, variant ) => {
253
- const defaultValues = getDefaultValues( pluginTemplate, variant );
254
- return keys.map( ( promptName ) => {
255
- return {
256
- ...prompts[ promptName ],
258
+ const runPrompts = async (
259
+ projectTemplate,
260
+ promptNames,
261
+ variant,
262
+ optionsValues
263
+ ) => {
264
+ const defaultValues = getDefaultValues( projectTemplate, variant );
265
+ const result = {};
266
+ for ( const promptName of promptNames ) {
267
+ if ( Object.keys( optionsValues ).includes( promptName ) ) {
268
+ continue;
269
+ }
270
+
271
+ const { type, ...config } = prompts[ promptName ];
272
+ result[ promptName ] = await inquirer[ type ]( {
273
+ ...config,
257
274
  default: defaultValues[ promptName ],
258
- };
259
- } );
275
+ } );
276
+ }
277
+
278
+ return result;
260
279
  };
261
280
 
262
281
  const getVariantVars = ( variants, variant ) => {
@@ -277,7 +296,7 @@ const getVariantVars = ( variants, variant ) => {
277
296
  };
278
297
 
279
298
  module.exports = {
280
- getPluginTemplate,
281
299
  getDefaultValues,
282
- getPrompts,
300
+ getProjectTemplate,
301
+ runPrompts,
283
302
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/create-block",
3
- "version": "4.57.0",
3
+ "version": "4.58.1",
4
4
  "description": "Generates PHP, JS and CSS code for registering a block for a WordPress plugin.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -31,14 +31,14 @@
31
31
  "wp-create-block": "./index.js"
32
32
  },
33
33
  "dependencies": {
34
- "@wordpress/lazy-import": "*",
34
+ "@inquirer/prompts": "^7.2.0",
35
+ "@wordpress/lazy-import": "^2.15.0",
35
36
  "chalk": "^4.0.0",
36
37
  "change-case": "^4.1.2",
37
38
  "check-node-version": "^4.1.0",
38
39
  "commander": "^9.2.0",
39
40
  "execa": "^4.0.2",
40
41
  "fast-glob": "^3.2.7",
41
- "inquirer": "^7.1.0",
42
42
  "make-dir": "^3.0.0",
43
43
  "mustache": "^4.0.0",
44
44
  "npm-package-arg": "^8.1.5",
@@ -48,5 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "b432c18934c9db866b6dba7d37517a4e97d642e3"
51
+ "gitHead": "0d4503ecc364cf4ca16024673baf5a84dacf212f"
52
52
  }