@40q/40q-cli 1.0.1 → 1.0.3

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/Readme.md CHANGED
@@ -19,4 +19,18 @@ Setup is intended to scaffold tools configurations.
19
19
  ```
20
20
 
21
21
  Supported Tools:
22
- * eslint
22
+ * eslint
23
+
24
+ ### Codegen
25
+ Codegen generates code for you.
26
+
27
+ ```
28
+ 40q codegen [type] [template]
29
+ ```
30
+
31
+ Supported Types:
32
+ * block: generates code for Gutenberg blocks
33
+
34
+ Templates are optional, if empty, it creates an example boilerplate for a Gutenberg block.
35
+
36
+ For supported templates, run: `40q codegen block --help`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@40q/40q-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "40q CLI tool",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  import { ArgumentsCamelCase, Argv } from 'yargs';
2
2
  import { Command } from '../Command';
3
- import inquirer, { QuestionCollection } from 'inquirer';
3
+ import inquirer from 'inquirer';
4
4
  import { GenerateBlock } from './Generators/GenerateBlock';
5
5
  import { Templates, Types, templateChoices, typeChoices } from './Codegen.types';
6
6
 
@@ -26,27 +26,21 @@ export class CodegenCommand implements Command {
26
26
  const template = (argv.template ?? 'default') as Templates;
27
27
 
28
28
  if (type === 'block') {
29
- const answers = await CodegenCommand.prompt(
29
+ const answers = await inquirer.prompt(
30
30
  [
31
31
  {
32
32
  type: 'input',
33
33
  name: 'name',
34
34
  message: 'Please enter a name for the block:',
35
- default: 'section-header',
35
+ default: template || 'section-header',
36
36
  },
37
37
  ],
38
- template === 'default'
39
38
  );
40
39
 
41
40
  const name = (answers?.name as string) || null;
42
41
 
43
- return GenerateBlock.run(template, name);
42
+ const blockGenerator = new GenerateBlock(template, name);
43
+ return blockGenerator.run();
44
44
  }
45
45
  }
46
-
47
- static async prompt(prompts: QuestionCollection, condition: boolean) {
48
- if (!condition) return null;
49
-
50
- return await inquirer.prompt(prompts);
51
- }
52
46
  }
@@ -1,36 +1,81 @@
1
- import { execSync } from 'child_process';
2
1
  import * as fs from 'fs';
3
2
  import path from 'path';
3
+ import { execSync } from 'child_process';
4
4
  import { Templates } from '../Codegen.types';
5
5
  import { findCliRoot } from '../../../lib/cliRoot';
6
6
 
7
7
  export class GenerateBlock {
8
- static run(template: Templates, name: string | null) {
9
- const title =
10
- name
11
- ?.split('-')
12
- .map((word) => {
13
- return word.charAt(0).toUpperCase() + word.slice(1);
14
- })
15
- .join(' ') ?? '';
16
- const dirAndFileName = name || template;
17
-
18
- execSync(`mkdir -p resources/scripts/editor/blocks/${dirAndFileName}`);
8
+ private template: Templates = 'default';
9
+ private name: string = '';
10
+ private title: string = '';
11
+ private camelCaseName: string = '';
19
12
 
20
- const cliRoot = findCliRoot(__dirname);
21
- const templateContent = fs.readFileSync(
22
- path.join(cliRoot, 'templates/blocks/', `${template}.txt`),
23
- 'utf8'
13
+ constructor(template: Templates, name: string | null) {
14
+ this.template = template;
15
+ this.name = name ?? '';
16
+ this.camelCaseName = this.toCamelCase(this.name);
17
+ this.title = this.parseName(this.name);
18
+ }
19
+
20
+ public run() {
21
+ this.createBlockFolder();
22
+ this.createBlockFiles();
23
+ }
24
+
25
+ private createBlockFolder() {
26
+ execSync(`mkdir -p resources/scripts/editor/blocks/${this.name}`);
27
+ }
28
+
29
+ private createBlockFiles() {
30
+ fs.writeFileSync(
31
+ path.join(
32
+ process.cwd(),
33
+ `resources/scripts/editor/blocks/${this.name}/${this.name}.tsx`
34
+ ),
35
+ this.getTemplate('tsx')
36
+ .replace(/{{name}}/g, this.name ?? '')
37
+ .replace(/{{title}}/g, this.title)
24
38
  );
25
39
 
26
40
  fs.writeFileSync(
27
41
  path.join(
28
42
  process.cwd(),
29
- `resources/scripts/editor/blocks/${dirAndFileName}/${dirAndFileName}.tsx`
43
+ `resources/views/blocks/${this.name}.blade.php`
30
44
  ),
31
- templateContent
32
- .replace(/{{name}}/g, name ?? '')
33
- .replace(/{{title}}/g, title)
45
+ ''
46
+ );
47
+
48
+ fs.writeFileSync(
49
+ path.join(process.cwd(), `app/Blocks/${this.camelCaseName}.php`),
50
+ this.getTemplate('php')
51
+ .replace(/{{name}}/g, this.name ?? '')
52
+ .replace(/{{camelCaseName}}/g, this.camelCaseName)
53
+ );
54
+ }
55
+
56
+ private parseName(name: string) {
57
+ return name
58
+ .split('-')
59
+ .map((word) => {
60
+ return word.charAt(0).toUpperCase() + word.slice(1);
61
+ })
62
+ .join(' ');
63
+ }
64
+
65
+ private toCamelCase(name: string) {
66
+ return (
67
+ name.split('-').reduce((acc, word) => {
68
+ return acc + word.charAt(0).toUpperCase() + word.slice(1);
69
+ }, '') ?? ''
70
+ );
71
+ }
72
+
73
+ private getTemplate(name: string) {
74
+ const cliRoot = findCliRoot(__dirname);
75
+ const templateFolder = `templates/blocks/${this.template}`;
76
+ return fs.readFileSync(
77
+ path.join(cliRoot, `${templateFolder}/${name}.txt`),
78
+ 'utf8'
34
79
  );
35
80
  }
36
81
  }
@@ -0,0 +1,13 @@
1
+ <?php
2
+
3
+ namespace App\Blocks;
4
+
5
+ class {{camelCaseName}} extends BlockHandler
6
+ {
7
+ public function __invoke($block_content, $block)
8
+ {
9
+ return view('blocks.{{name}}', [
10
+ 'title' => $block['attrs']['title'] ?? null,
11
+ ]);
12
+ }
13
+ }
@@ -7,10 +7,10 @@ import {
7
7
  } from "@wordpress/block-editor";
8
8
 
9
9
  /* Block name */
10
- export const name = "by40q/section-header";
10
+ export const name = "by40q/{{name}}";
11
11
 
12
12
  /* Block title */
13
- export const title = __("Section Header", "40q");
13
+ export const title = __("{{title}}", "40q");
14
14
 
15
15
  /* Block category */
16
16
  export const category = "text";
@@ -32,7 +32,7 @@ export const edit = ({ attributes, setAttributes }) => {
32
32
  return (
33
33
  <>
34
34
  <InspectorControls>
35
- <PanelBody title={__("Section Header Settings")} initialOpen></PanelBody>
35
+ <PanelBody title={__("{{title}} Settings")} initialOpen></PanelBody>
36
36
  </InspectorControls>
37
37
 
38
38
  <div {...blockProps}>