@40q/40q-cli 1.0.0 → 1.0.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/.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 = [];
|