@pavlos-samaras/react-cli 1.0.0 → 1.1.0

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.
Files changed (40) hide show
  1. package/README.md +75 -0
  2. package/dist/bin/ct.js +46 -10
  3. package/dist/bin/ct.js.map +1 -1
  4. package/dist/constants/generator.d.ts +3 -0
  5. package/dist/constants/generator.d.ts.map +1 -0
  6. package/dist/constants/generator.js +6 -0
  7. package/dist/constants/generator.js.map +1 -0
  8. package/dist/templates/component.d.ts +1 -1
  9. package/dist/templates/component.d.ts.map +1 -1
  10. package/dist/templates/component.js +7 -3
  11. package/dist/templates/component.js.map +1 -1
  12. package/dist/templates/hook.d.ts +3 -0
  13. package/dist/templates/hook.d.ts.map +1 -0
  14. package/dist/templates/hook.js +5 -0
  15. package/dist/templates/hook.js.map +1 -0
  16. package/dist/templates/stylesheet.d.ts +3 -0
  17. package/dist/templates/stylesheet.d.ts.map +1 -0
  18. package/dist/templates/stylesheet.js +7 -0
  19. package/dist/templates/stylesheet.js.map +1 -0
  20. package/dist/types/generator.d.ts +7 -0
  21. package/dist/types/generator.d.ts.map +1 -0
  22. package/dist/types/generator.js +2 -0
  23. package/dist/types/generator.js.map +1 -0
  24. package/dist/utils/applySpinner.d.ts +5 -0
  25. package/dist/utils/applySpinner.d.ts.map +1 -0
  26. package/dist/utils/applySpinner.js +16 -0
  27. package/dist/utils/applySpinner.js.map +1 -0
  28. package/dist/utils/generateComponent.d.ts +18 -4
  29. package/dist/utils/generateComponent.d.ts.map +1 -1
  30. package/dist/utils/generateComponent.js +47 -9
  31. package/dist/utils/generateComponent.js.map +1 -1
  32. package/dist/utils/generateHook.d.ts +6 -0
  33. package/dist/utils/generateHook.d.ts.map +1 -0
  34. package/dist/utils/generateHook.js +32 -0
  35. package/dist/utils/generateHook.js.map +1 -0
  36. package/package.json +37 -30
  37. package/dist/types/component.d.ts +0 -5
  38. package/dist/types/component.d.ts.map +0 -1
  39. package/dist/types/component.js +0 -2
  40. package/dist/types/component.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # React CLI
2
+
3
+ A simple command-line tool for generating React components and hooks.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @pavlos-samaras/react-cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ ct generate <type> <name> [options]
15
+ ```
16
+
17
+ `g` is a shorthand for `generate`.
18
+
19
+ ### Types
20
+
21
+ | Type | Output |
22
+ | ----------- | --------------------------------------------------------------------------------------- |
23
+ | `component` | A folder with the component, a CSS/SCSS module, a hook and a test file |
24
+ | `hook` | A single hook file. The name must start with `use` followed by a capital (e.g. `useAuth`) |
25
+
26
+ ### Options
27
+
28
+ | Option | Description |
29
+ | ------------------------- | ------------------------------------------------------------------------ |
30
+ | `-d, --dir <dir>` | Target folder inside `src/` (or inside the feature). Default depends on the type: `components` or `hooks` |
31
+ | `-f, --feature <feature>` | Put the output under `src/features/<feature>/` |
32
+ | `--ts` | Use TypeScript without prompting |
33
+ | `-y, --yes` | Use the defaults (TypeScript, SCSS) and skip all prompts |
34
+
35
+ Without `--ts` or `-y`, the CLI asks whether to use TypeScript and (for
36
+ components) which stylesheet to use.
37
+
38
+ ### Output locations
39
+
40
+ | Command | Output |
41
+ | ---------------------------------------- | -------------------------------------------- |
42
+ | `ct g component Button` | `src/components/Button/` |
43
+ | `ct g component Button -f auth` | `src/features/auth/components/Button/` |
44
+ | `ct g component Button -d ui` | `src/ui/Button/` |
45
+ | `ct g hook useAuth` | `src/shared/hooks/useAuth.ts` |
46
+ | `ct g hook useAuth -f auth` | `src/features/auth/hooks/useAuth.ts` |
47
+
48
+ ### Examples
49
+
50
+ ```bash
51
+ # Component with all defaults, no prompts
52
+ ct g component Button -y
53
+
54
+ # TypeScript component under a feature
55
+ ct g component LoginForm --feature auth --ts
56
+
57
+ # Hook under a feature
58
+ ct g hook useSession -f auth -y
59
+ ```
60
+
61
+ ## Development
62
+
63
+ Run the CLI directly from the TypeScript source:
64
+
65
+ ```bash
66
+ npm run dev -- generate component Button
67
+ ```
68
+
69
+ To link the local build globally instead:
70
+
71
+ ```bash
72
+ npm install
73
+ npm run build
74
+ npm link
75
+ ```
package/dist/bin/ct.js CHANGED
@@ -1,25 +1,61 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import chalk from "chalk";
5
+ import { createRequire } from "module";
4
6
  import { Command } from "commander";
5
7
  import { generateComponent } from "../utils/generateComponent.js";
8
+ import { applySpinner } from "../utils/applySpinner.js";
9
+ import { DEFAULT_DIRS, TYPES } from "../constants/generator.js";
10
+ import { generateHook } from "../utils/generateHook.js";
11
+ const require = createRequire(import.meta.url);
12
+ const { version } = require("../../package.json");
6
13
  const program = new Command();
7
- const TYPES = ["component"];
8
- program.name("ct").description("My React CLI").version("1.0.0");
14
+ program.name("ct").description("My React CLI").version(version);
9
15
  program
10
16
  .command("generate <type> <name>")
11
17
  .alias("g")
12
18
  .description("Generate a component, e.g. ct g component Button")
13
- .option("-d, --dir <div>", "target folder", "src/components")
19
+ .option("-d, --dir <dir>", "target folder (default depends on type)")
20
+ .option("-f, --feature <feature>", "put component under a feature")
14
21
  .option("--ts", "create a .tsx file")
15
- .action(async (type, name, options) => {
16
- if (!TYPES.includes(type))
17
- return console.log(`Unknown type: ${type}`);
22
+ .option("-y, --yes", "use default options and skip prompts")
23
+ .action((type, name, options) => {
24
+ if (!TYPES.includes(type)) {
25
+ console.log(chalk.red(`Unknown type: ${type}`));
26
+ process.exitCode = 1;
27
+ return;
28
+ }
29
+ const dir = options.dir ?? DEFAULT_DIRS[type];
18
30
  if (type === "component") {
19
- const folder = path.join(process.cwd(), options.dir, name);
20
- fs.mkdirSync(folder, { recursive: true });
21
- const { file, content } = await generateComponent(name, options);
22
- fs.writeFileSync(path.join(folder, file), content);
31
+ const pathToComponent = options.feature
32
+ ? `src/features/${options.feature}/${dir}`
33
+ : `src/${dir}`;
34
+ const folder = path.join(process.cwd(), pathToComponent, name);
35
+ applySpinner({ name, folder }, async () => {
36
+ fs.mkdirSync(folder, { recursive: true });
37
+ const { JSX, stylesheet, hook, test } = await generateComponent(folder, name, options);
38
+ fs.writeFileSync(JSX.pathToFile, JSX.content);
39
+ fs.writeFileSync(stylesheet.pathToFile, stylesheet.content);
40
+ fs.writeFileSync(hook.pathToFile, hook.content);
41
+ fs.writeFileSync(test.pathToFile, test.content);
42
+ });
43
+ }
44
+ if (type === "hook") {
45
+ if (!/^use[A-Z]\w+$/.test(name)) {
46
+ console.log(chalk.red("Hook must start with 'use' followed by a capital letter"));
47
+ process.exitCode = 1;
48
+ return;
49
+ }
50
+ const pathToHook = options.feature
51
+ ? `src/features/${options.feature}/${dir}`
52
+ : `src/shared/${dir}`;
53
+ const folder = path.join(process.cwd(), pathToHook);
54
+ applySpinner({ name, folder }, async () => {
55
+ fs.mkdirSync(folder, { recursive: true });
56
+ const hook = await generateHook(folder, name, options);
57
+ fs.writeFileSync(hook.pathToFile, hook.content);
58
+ });
23
59
  }
24
60
  });
25
61
  program.parse();
@@ -1 +1 @@
1
- {"version":3,"file":"ct.js","sourceRoot":"","sources":["../../src/bin/ct.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGlE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,MAAM,KAAK,GAAG,CAAC,WAAW,CAAC,CAAC;AAE5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhE,OAAO;KACJ,OAAO,CAAC,wBAAwB,CAAC;KACjC,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,CAAC;KAC5D,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC;KACpC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,IAAY,EAAE,OAAyB,EAAE,EAAE;IACtE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAEvE,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3D,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACjE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"ct.js","sourceRoot":"","sources":["../../src/bin/ct.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare const TYPES: string[];
2
+ export declare const DEFAULT_DIRS: Record<string, string>;
3
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/constants/generator.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,UAAwB,CAAC;AAE3C,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG/C,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const TYPES = ["component", "hook"];
2
+ export const DEFAULT_DIRS = {
3
+ component: "components",
4
+ hook: "hooks",
5
+ };
6
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/constants/generator.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,SAAS,EAAE,YAAY;IACvB,IAAI,EAAE,OAAO;CACd,CAAC"}
@@ -1,3 +1,3 @@
1
- declare const buildComponentTemplate: (name: string) => string;
1
+ declare const buildComponentTemplate: (name: string, stylesheetExt: string, componentExt: string) => string;
2
2
  export default buildComponentTemplate;
3
3
  //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/templates/component.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,sBAAsB,SAAU,MAAM,WAI3C,CAAC;eAEa,sBAAsB"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/templates/component.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,sBAAsB,SACpB,MAAM,iBACG,MAAM,gBACP,MAAM,WASrB,CAAC;eAEa,sBAAsB"}
@@ -1,6 +1,10 @@
1
- const buildComponentTemplate = (name) => {
2
- return `export const ${name} = () => {
3
- return <div></div>
1
+ const buildComponentTemplate = (name, stylesheetExt, componentExt) => {
2
+ return `import styles from "./${name}.module.${stylesheetExt}"
3
+ import { use${name} } from "./use${name}.${componentExt}"
4
+
5
+ export const ${name} = () => {
6
+ const hook = use${name}();
7
+ return <div className={styles.${name.toLowerCase()}></div>
4
8
  }`;
5
9
  };
6
10
  export default buildComponentTemplate;
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/templates/component.ts"],"names":[],"mappings":"AAAA,MAAM,sBAAsB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC9C,OAAO,gBAAgB,IAAI;;EAE3B,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/templates/component.ts"],"names":[],"mappings":"AAAA,MAAM,sBAAsB,GAAG,CAC7B,IAAY,EACZ,aAAqB,EACrB,YAAoB,EACpB,EAAE;IACF,OAAO,yBAAyB,IAAI,WAAW,aAAa;cAChD,IAAI,iBAAiB,IAAI,IAAI,YAAY;;eAExC,IAAI;oBACC,IAAI;kCACU,IAAI,CAAC,WAAW,EAAE;EAClD,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const buildHookTemplate: (name: string) => string;
2
+ export default buildHookTemplate;
3
+ //# sourceMappingURL=hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/templates/hook.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,iBAAiB,SAAU,MAAM,WAEtC,CAAC;eAEa,iBAAiB"}
@@ -0,0 +1,5 @@
1
+ const buildHookTemplate = (name) => {
2
+ return `export const use${name} = () => {}`;
3
+ };
4
+ export default buildHookTemplate;
5
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/templates/hook.ts"],"names":[],"mappings":"AAAA,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,EAAE;IACzC,OAAO,mBAAmB,IAAI,aAAa,CAAC;AAC9C,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const buildStylesheetTemplate: (name: string) => string;
2
+ export default buildStylesheetTemplate;
3
+ //# sourceMappingURL=stylesheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylesheet.d.ts","sourceRoot":"","sources":["../../src/templates/stylesheet.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,uBAAuB,SAAU,MAAM,WAI5C,CAAC;eAEa,uBAAuB"}
@@ -0,0 +1,7 @@
1
+ const buildStylesheetTemplate = (name) => {
2
+ return `.${name.toLowerCase()} {
3
+ // Styles go here
4
+ }`;
5
+ };
6
+ export default buildStylesheetTemplate;
7
+ //# sourceMappingURL=stylesheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stylesheet.js","sourceRoot":"","sources":["../../src/templates/stylesheet.ts"],"names":[],"mappings":"AAAA,MAAM,uBAAuB,GAAG,CAAC,IAAY,EAAE,EAAE;IAC/C,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE;;EAE7B,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type GeneratorOptions = {
2
+ dir?: string;
3
+ feature?: string;
4
+ ts?: boolean;
5
+ yes?: boolean;
6
+ };
7
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/types/generator.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/types/generator.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ export declare const applySpinner: (options: {
2
+ name: string;
3
+ folder: string;
4
+ }, callback: () => void) => void;
5
+ //# sourceMappingURL=applySpinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applySpinner.d.ts","sourceRoot":"","sources":["../../src/utils/applySpinner.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,YAAY,YACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,YAC/B,MAAM,IAAI,SAarB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import chalk from "chalk";
2
+ import ora from "ora";
3
+ export const applySpinner = (options, callback) => {
4
+ const { name, folder } = options;
5
+ const spinner = ora(`Creating ${name}...`).start();
6
+ try {
7
+ callback();
8
+ spinner.succeed(`Created ${chalk.cyan(name)} in ${chalk.gray(folder)}`);
9
+ }
10
+ catch (error) {
11
+ spinner.fail(chalk.red(`Could not create ${name}`));
12
+ console.error(error);
13
+ process.exitCode = 1;
14
+ }
15
+ };
16
+ //# sourceMappingURL=applySpinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applySpinner.js","sourceRoot":"","sources":["../../src/utils/applySpinner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAAyC,EACzC,QAAoB,EACpB,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAEnD,IAAI,CAAC;QACH,QAAQ,EAAE,CAAC;QACX,OAAO,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC,CAAC"}
@@ -1,6 +1,20 @@
1
- import type { ComponentOptions } from "../types/component.js";
2
- export declare const generateComponent: (name: string, options: ComponentOptions) => Promise<{
3
- file: string;
4
- content: string;
1
+ import type { GeneratorOptions } from "../types/generator.js";
2
+ export declare const generateComponent: (folder: string, name: string, options: GeneratorOptions) => Promise<{
3
+ JSX: {
4
+ pathToFile: string;
5
+ content: string;
6
+ };
7
+ stylesheet: {
8
+ pathToFile: string;
9
+ content: string;
10
+ };
11
+ hook: {
12
+ pathToFile: string;
13
+ content: string;
14
+ };
15
+ test: {
16
+ pathToFile: string;
17
+ content: string;
18
+ };
5
19
  }>;
6
20
  //# sourceMappingURL=generateComponent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateComponent.d.ts","sourceRoot":"","sources":["../../src/utils/generateComponent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,eAAO,MAAM,iBAAiB,SACtB,MAAM,WACH,gBAAgB;;;EAuB1B,CAAC"}
1
+ {"version":3,"file":"generateComponent.d.ts","sourceRoot":"","sources":["../../src/utils/generateComponent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAM9D,eAAO,MAAM,iBAAiB,WACpB,MAAM,QACR,MAAM,WACH,gBAAgB;;QAuCrB,UAAU;QACV,OAAO;;;QAOP,UAAU;QACV,OAAO;;;QAGP,UAAU;QACV,OAAO;;;QAGP,UAAU;QACV,OAAO;;EAGZ,CAAC"}
@@ -1,22 +1,60 @@
1
+ import path from "path";
1
2
  import prompts from "prompts";
2
3
  import buildComponentTemplate from "../templates/component.js";
3
- export const generateComponent = async (name, options) => {
4
- let useTs = options.ts;
5
- if (useTs === undefined) {
4
+ import buildStylesheetTemplate from "../templates/stylesheet.js";
5
+ import buildHookTemplate from "../templates/hook.js";
6
+ const DEFAULTS = { componentExt: "tsx", style: "scss" };
7
+ export const generateComponent = async (folder, name, options) => {
8
+ let componentExt;
9
+ if (options.ts !== undefined) {
10
+ componentExt = options.ts ? "tsx" : "jsx";
11
+ }
12
+ else if (options.yes) {
13
+ componentExt = DEFAULTS.componentExt;
14
+ }
15
+ else {
6
16
  const answer = await prompts({
7
17
  type: "select",
8
18
  name: "ts",
9
19
  message: "Use TypeScript?",
10
20
  choices: [
11
- { title: "Yes", value: true },
12
- { title: "No", value: false },
21
+ { title: "Yes", value: "tsx" },
22
+ { title: "No", value: "jsx" },
13
23
  ],
14
24
  initial: 0,
15
25
  });
16
- useTs = answer.ts ?? false;
26
+ componentExt = answer.ts;
17
27
  }
18
- const ext = useTs ? "tsx" : "jsx";
19
- const content = buildComponentTemplate(name);
20
- return { file: `${name}.${ext}`, content };
28
+ const stylesheetExt = options.yes
29
+ ? { style: DEFAULTS.style }
30
+ : await prompts({
31
+ type: "select",
32
+ name: "style",
33
+ message: "What stylesheet to use",
34
+ choices: [
35
+ { title: "CSS", value: "css" },
36
+ { title: "SCSS", value: "scss" },
37
+ ],
38
+ initial: 1,
39
+ });
40
+ const componentLanguage = componentExt?.replace("x", "");
41
+ return {
42
+ JSX: {
43
+ pathToFile: path.join(folder, `${name}.${componentExt}`),
44
+ content: buildComponentTemplate(name, stylesheetExt.style, componentLanguage),
45
+ },
46
+ stylesheet: {
47
+ pathToFile: path.join(folder, `${name}.module.${stylesheetExt.style}`),
48
+ content: buildStylesheetTemplate(name),
49
+ },
50
+ hook: {
51
+ pathToFile: path.join(folder, `use${name}.${componentLanguage}`),
52
+ content: buildHookTemplate(name),
53
+ },
54
+ test: {
55
+ pathToFile: path.join(folder, `${name}.test.${componentLanguage}`),
56
+ content: "",
57
+ },
58
+ };
21
59
  };
22
60
  //# sourceMappingURL=generateComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generateComponent.js","sourceRoot":"","sources":["../../src/utils/generateComponent.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,sBAAsB,MAAM,2BAA2B,CAAC;AAG/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,IAAY,EACZ,OAAyB,EACzB,EAAE;IACF,IAAI,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC;IAEvB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;gBAC7B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;aAC9B;YACD,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,KAAK,GAAG,MAAM,CAAC,EAAE,IAAI,KAAK,CAAC;IAC7B,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAElC,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE7C,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC,CAAC"}
1
+ {"version":3,"file":"generateComponent.js","sourceRoot":"","sources":["../../src/utils/generateComponent.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,sBAAsB,MAAM,2BAA2B,CAAC;AAE/D,OAAO,uBAAuB,MAAM,4BAA4B,CAAC;AACjE,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AAErD,MAAM,QAAQ,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAExD,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,MAAc,EACd,IAAY,EACZ,OAAyB,EACzB,EAAE;IACF,IAAI,YAAgC,CAAC;IAErC,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,CAAC;SAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvB,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;gBAC9B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;aAC9B;YACD,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,YAAY,GAAG,MAAM,CAAC,EAAY,CAAC;IACrC,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG;QAC/B,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE;QAC3B,CAAC,CAAC,MAAM,OAAO,CAAC;YACZ,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;gBAC9B,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;aACjC;YACD,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAE,CAAC;IAE1D,OAAO;QACL,GAAG,EAAE;YACH,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,YAAY,EAAE,CAAC;YACxD,OAAO,EAAE,sBAAsB,CAC7B,IAAI,EACJ,aAAa,CAAC,KAAK,EACnB,iBAAiB,CAClB;SACF;QACD,UAAU,EAAE;YACV,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,WAAW,aAAa,CAAC,KAAK,EAAE,CAAC;YACtE,OAAO,EAAE,uBAAuB,CAAC,IAAI,CAAC;SACvC;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;YAChE,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC;SACjC;QACD,IAAI,EAAE;YACJ,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,SAAS,iBAAiB,EAAE,CAAC;YAClE,OAAO,EAAE,EAAE;SACZ;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { GeneratorOptions } from "../types/generator.js";
2
+ export declare const generateHook: (folder: string, name: string, options: GeneratorOptions) => Promise<{
3
+ pathToFile: string;
4
+ content: string;
5
+ }>;
6
+ //# sourceMappingURL=generateHook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateHook.d.ts","sourceRoot":"","sources":["../../src/utils/generateHook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAM9D,eAAO,MAAM,YAAY,WACf,MAAM,QACR,MAAM,WACH,gBAAgB;;;EA2B1B,CAAC"}
@@ -0,0 +1,32 @@
1
+ import path from "path";
2
+ import prompts from "prompts";
3
+ import buildHookTemplate from "../templates/hook.js";
4
+ const DEFAULTS = { componentExt: "tsx", style: "scss" };
5
+ export const generateHook = async (folder, name, options) => {
6
+ let componentExt;
7
+ if (options.ts !== undefined) {
8
+ componentExt = options.ts ? "tsx" : "jsx";
9
+ }
10
+ else if (options.yes) {
11
+ componentExt = DEFAULTS.componentExt;
12
+ }
13
+ else {
14
+ const answer = await prompts({
15
+ type: "select",
16
+ name: "ts",
17
+ message: "Use TypeScript?",
18
+ choices: [
19
+ { title: "Yes", value: "tsx" },
20
+ { title: "No", value: "jsx" },
21
+ ],
22
+ initial: 0,
23
+ });
24
+ componentExt = answer.ts;
25
+ }
26
+ const componentLanguage = componentExt?.replace("x", "");
27
+ return {
28
+ pathToFile: path.join(folder, `${name}.${componentLanguage}`),
29
+ content: buildHookTemplate(name),
30
+ };
31
+ };
32
+ //# sourceMappingURL=generateHook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateHook.js","sourceRoot":"","sources":["../../src/utils/generateHook.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,iBAAiB,MAAM,sBAAsB,CAAC;AAErD,MAAM,QAAQ,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAExD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC/B,MAAc,EACd,IAAY,EACZ,OAAyB,EACzB,EAAE;IACF,IAAI,YAAgC,CAAC;IAErC,IAAI,OAAO,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC7B,YAAY,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,CAAC;SAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvB,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;gBAC9B,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;aAC9B;YACD,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,YAAY,GAAG,MAAM,CAAC,EAAY,CAAC;IACrC,CAAC;IACD,MAAM,iBAAiB,GAAG,YAAY,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAE,CAAC;IAE1D,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;QAC7D,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,30 +1,37 @@
1
- {
2
- "name": "@pavlos-samaras/react-cli",
3
- "version": "1.0.0",
4
- "author": "sammern-stack",
5
- "description": "A CLI to generate React code",
6
- "keywords": ["react", "cli", "generator"],
7
- "license": "MIT",
8
- "type": "module",
9
- "bin": {
10
- "ct": "./dist/bin/ct.js"
11
- },
12
- "scripts": {
13
- "build": "tsc",
14
- "dev": "tsx src/bin/ct.ts",
15
- "build:link": "npm run build && npm link"
16
- },
17
- "dependencies": {
18
- "commander": "^15.0.0",
19
- "prompts": "^2.4.2"
20
- },
21
- "devDependencies": {
22
- "@types/node": "^26.6.6",
23
- "@types/prompts": "^2.4.9",
24
- "tsx": "^4.23.15",
25
- "typescript": "^7.0.2"
26
- },
27
- "files": [
28
- "dist"
29
- ]
30
- }
1
+ {
2
+ "name": "@pavlos-samaras/react-cli",
3
+ "version": "1.1.0",
4
+ "author": "sammern-stack",
5
+ "description": "A CLI to generate React code",
6
+ "keywords": [
7
+ "react",
8
+ "cli",
9
+ "generator"
10
+ ],
11
+ "license": "MIT",
12
+ "type": "module",
13
+ "bin": {
14
+ "ct": "./dist/bin/ct.js"
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "prepublishOnly": "npm run build",
19
+ "dev": "tsx src/bin/ct.ts",
20
+ "build:link": "npm run build && npm link"
21
+ },
22
+ "dependencies": {
23
+ "chalk": "^6.0.1",
24
+ "commander": "^15.0.0",
25
+ "ora": "^10.0.0",
26
+ "prompts": "^2.4.2"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^26.6.6",
30
+ "@types/prompts": "^2.4.9",
31
+ "tsx": "^4.23.15",
32
+ "typescript": "^7.0.2"
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ]
37
+ }
@@ -1,5 +0,0 @@
1
- export type ComponentOptions = {
2
- dir: string;
3
- ts?: boolean;
4
- };
5
- //# sourceMappingURL=component.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/types/component.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,CAAA"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=component.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["../../src/types/component.ts"],"names":[],"mappings":""}