@40q/40q-cli 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/.cliroot +0 -0
- package/package.json +4 -2
- package/src/40qCli.ts +8 -1
- package/src/commands/Codegen/Codegen.command.ts +52 -0
- package/src/commands/Codegen/Codegen.types.ts +5 -0
- package/src/commands/Codegen/Generators/GenerateBlock.ts +36 -0
- package/src/commands/{Setup.command.ts → Setup/Setup.command.ts} +1 -1
- package/src/lib/cliRoot.ts +16 -0
- package/templates/blocks/default.txt +54 -0
- package/tsconfig.json +2 -1
package/.cliroot
ADDED
File without changes
|
package/package.json
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
{
|
2
2
|
"name": "@40q/40q-cli",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.1",
|
4
4
|
"description": "40q CLI tool",
|
5
5
|
"main": "index.js",
|
6
6
|
"bin": {
|
7
7
|
"40q": "./dist/index.js"
|
8
8
|
},
|
9
9
|
"dependencies": {
|
10
|
+
"inquirer": "^8.0.0",
|
10
11
|
"yargs": "^17.7.2"
|
11
12
|
},
|
12
13
|
"peerDependencies": {
|
@@ -14,7 +15,7 @@
|
|
14
15
|
},
|
15
16
|
"scripts": {
|
16
17
|
"build": "tsc",
|
17
|
-
"
|
18
|
+
"deploy": "yarn build && yarn publish --access public"
|
18
19
|
},
|
19
20
|
"author": "40q <info@40q.agency> (https://40q.agency/)",
|
20
21
|
"license": "ISC",
|
@@ -23,6 +24,7 @@
|
|
23
24
|
"url": "https://github.com/40Q/40q-cli.git"
|
24
25
|
},
|
25
26
|
"devDependencies": {
|
27
|
+
"@types/inquirer": "^8.0.0",
|
26
28
|
"@types/node": "^20.8.7",
|
27
29
|
"@types/yargs": "^17.0.29",
|
28
30
|
"ts-node": "^10.9.1",
|
package/src/40qCli.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import yargs from 'yargs';
|
2
2
|
import { hideBin } from 'yargs/helpers';
|
3
|
-
import { SetupCommand } from './commands/Setup.command';
|
3
|
+
import { SetupCommand } from './commands/Setup/Setup.command';
|
4
|
+
import { CodegenCommand } from './commands/Codegen/Codegen.command';
|
4
5
|
|
5
6
|
export class q40Cli {
|
6
7
|
static init() {
|
@@ -11,6 +12,12 @@ export class q40Cli {
|
|
11
12
|
SetupCommand.builder,
|
12
13
|
SetupCommand.handler
|
13
14
|
)
|
15
|
+
.command(
|
16
|
+
'codegen [type] [template]',
|
17
|
+
'Generate code from a template',
|
18
|
+
CodegenCommand.builder,
|
19
|
+
CodegenCommand.handler
|
20
|
+
)
|
14
21
|
.help().argv;
|
15
22
|
}
|
16
23
|
}
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import { ArgumentsCamelCase, Argv } from 'yargs';
|
2
|
+
import { Command } from '../Command';
|
3
|
+
import inquirer, { QuestionCollection } from 'inquirer';
|
4
|
+
import { GenerateBlock } from './Generators/GenerateBlock';
|
5
|
+
import { Templates, Types, templateChoices, typeChoices } from './Codegen.types';
|
6
|
+
|
7
|
+
export class CodegenCommand implements Command {
|
8
|
+
static builder(yargs: Argv<{}>) {
|
9
|
+
yargs.positional('type', {
|
10
|
+
describe: 'Type of code piece to generate',
|
11
|
+
choices: typeChoices,
|
12
|
+
demandOption: true,
|
13
|
+
type: 'string',
|
14
|
+
});
|
15
|
+
|
16
|
+
yargs.positional('template', {
|
17
|
+
describe: 'Template to use for code generation',
|
18
|
+
choices: templateChoices,
|
19
|
+
demandOption: false,
|
20
|
+
type: 'string',
|
21
|
+
});
|
22
|
+
}
|
23
|
+
|
24
|
+
static async handler(argv: ArgumentsCamelCase<{}>) {
|
25
|
+
const type = argv.type as Types;
|
26
|
+
const template = (argv.template ?? 'default') as Templates;
|
27
|
+
|
28
|
+
if (type === 'block') {
|
29
|
+
const answers = await CodegenCommand.prompt(
|
30
|
+
[
|
31
|
+
{
|
32
|
+
type: 'input',
|
33
|
+
name: 'name',
|
34
|
+
message: 'Please enter a name for the block:',
|
35
|
+
default: 'section-header',
|
36
|
+
},
|
37
|
+
],
|
38
|
+
template === 'default'
|
39
|
+
);
|
40
|
+
|
41
|
+
const name = (answers?.name as string) || null;
|
42
|
+
|
43
|
+
return GenerateBlock.run(template, name);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
static async prompt(prompts: QuestionCollection, condition: boolean) {
|
48
|
+
if (!condition) return null;
|
49
|
+
|
50
|
+
return await inquirer.prompt(prompts);
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { execSync } from 'child_process';
|
2
|
+
import * as fs from 'fs';
|
3
|
+
import path from 'path';
|
4
|
+
import { Templates } from '../Codegen.types';
|
5
|
+
import { findCliRoot } from '../../../lib/cliRoot';
|
6
|
+
|
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}`);
|
19
|
+
|
20
|
+
const cliRoot = findCliRoot(__dirname);
|
21
|
+
const templateContent = fs.readFileSync(
|
22
|
+
path.join(cliRoot, 'templates/blocks/', `${template}.txt`),
|
23
|
+
'utf8'
|
24
|
+
);
|
25
|
+
|
26
|
+
fs.writeFileSync(
|
27
|
+
path.join(
|
28
|
+
process.cwd(),
|
29
|
+
`resources/scripts/editor/blocks/${dirAndFileName}/${dirAndFileName}.tsx`
|
30
|
+
),
|
31
|
+
templateContent
|
32
|
+
.replace(/{{name}}/g, name ?? '')
|
33
|
+
.replace(/{{title}}/g, title)
|
34
|
+
);
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import * as fs from 'fs';
|
2
|
+
import * as path from 'path';
|
3
|
+
|
4
|
+
export function findCliRoot(startDir: string): string {
|
5
|
+
let currentDir = startDir;
|
6
|
+
|
7
|
+
while (currentDir !== path.parse(currentDir).root) {
|
8
|
+
if (fs.existsSync(path.join(currentDir, '.cliroot'))) {
|
9
|
+
return currentDir;
|
10
|
+
}
|
11
|
+
|
12
|
+
currentDir = path.dirname(currentDir);
|
13
|
+
}
|
14
|
+
|
15
|
+
throw new Error('CLI root directory with .cliroot marker not found.');
|
16
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { __ } from "@wordpress/i18n";
|
2
|
+
import { PanelBody } from "@wordpress/components";
|
3
|
+
import {
|
4
|
+
InspectorControls,
|
5
|
+
RichText,
|
6
|
+
useBlockProps,
|
7
|
+
} from "@wordpress/block-editor";
|
8
|
+
|
9
|
+
/* Block name */
|
10
|
+
export const name = "by40q/section-header";
|
11
|
+
|
12
|
+
/* Block title */
|
13
|
+
export const title = __("Section Header", "40q");
|
14
|
+
|
15
|
+
/* Block category */
|
16
|
+
export const category = "text";
|
17
|
+
|
18
|
+
/* Block attributes */
|
19
|
+
export const attributes = {
|
20
|
+
title: {
|
21
|
+
type: "string",
|
22
|
+
default: "40Q",
|
23
|
+
},
|
24
|
+
};
|
25
|
+
|
26
|
+
/* Block edit */
|
27
|
+
export const edit = ({ attributes, setAttributes }) => {
|
28
|
+
const { title } = attributes;
|
29
|
+
|
30
|
+
const blockProps = useBlockProps();
|
31
|
+
|
32
|
+
return (
|
33
|
+
<>
|
34
|
+
<InspectorControls>
|
35
|
+
<PanelBody title={__("Section Header Settings")} initialOpen></PanelBody>
|
36
|
+
</InspectorControls>
|
37
|
+
|
38
|
+
<div {...blockProps}>
|
39
|
+
<RichText
|
40
|
+
tagName="h2"
|
41
|
+
placeholder={__("40Q")}
|
42
|
+
value={title}
|
43
|
+
onChange={(title) => setAttributes({ title })}
|
44
|
+
/>
|
45
|
+
</div>
|
46
|
+
</>
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
/* Block save */
|
51
|
+
export const save = () => <></>;
|
52
|
+
|
53
|
+
/* Block styles */
|
54
|
+
export const styles = [];
|