vite-code-generator 0.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 (47) hide show
  1. package/README.md +95 -0
  2. package/bin/vite-gen.js +4 -0
  3. package/dist/cli/index.d.ts +4 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +124 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/generator/crud.d.ts +8 -0
  8. package/dist/generator/crud.d.ts.map +1 -0
  9. package/dist/generator/crud.js +33 -0
  10. package/dist/generator/crud.js.map +1 -0
  11. package/dist/generator/hello-world.d.ts +3 -0
  12. package/dist/generator/hello-world.d.ts.map +1 -0
  13. package/dist/generator/hello-world.js +162 -0
  14. package/dist/generator/hello-world.js.map +1 -0
  15. package/dist/generator/index.d.ts +9 -0
  16. package/dist/generator/index.d.ts.map +1 -0
  17. package/dist/generator/index.js +26 -0
  18. package/dist/generator/index.js.map +1 -0
  19. package/dist/generator/naming.d.ts +20 -0
  20. package/dist/generator/naming.d.ts.map +1 -0
  21. package/dist/generator/naming.js +42 -0
  22. package/dist/generator/naming.js.map +1 -0
  23. package/dist/generator/registry.d.ts +5 -0
  24. package/dist/generator/registry.d.ts.map +1 -0
  25. package/dist/generator/registry.js +20 -0
  26. package/dist/generator/registry.js.map +1 -0
  27. package/dist/generator/resource-api.d.ts +3 -0
  28. package/dist/generator/resource-api.d.ts.map +1 -0
  29. package/dist/generator/resource-api.js +143 -0
  30. package/dist/generator/resource-api.js.map +1 -0
  31. package/dist/generator/resource-hooks.d.ts +7 -0
  32. package/dist/generator/resource-hooks.d.ts.map +1 -0
  33. package/dist/generator/resource-hooks.js +248 -0
  34. package/dist/generator/resource-hooks.js.map +1 -0
  35. package/dist/generator/resource-page.d.ts +3 -0
  36. package/dist/generator/resource-page.d.ts.map +1 -0
  37. package/dist/generator/resource-page.js +280 -0
  38. package/dist/generator/resource-page.js.map +1 -0
  39. package/dist/index.d.ts +11 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +6 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/types.d.ts +28 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +2 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # vite-code-generator
2
+
3
+ CLI that scaffolds Vite + TypeScript projects and generates code from named templates.
4
+
5
+ ## Install / run
6
+
7
+ ```bash
8
+ npm install
9
+ npm run build
10
+ npx vite-gen create my-app
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ # list templates and their flags
17
+ vite-gen list
18
+
19
+ # create with the default hello-world template
20
+ vite-gen create my-app
21
+
22
+ # pick a template and pass dynamic flags
23
+ vite-gen create my-app --template hello-world --greeting "Hi there" --title "My App"
24
+
25
+ # same flags via generic --flag (useful for future templates)
26
+ vite-gen create my-app -t hello-world -f greeting=Hi -f title=MyApp
27
+
28
+ # custom output directory
29
+ vite-gen create my-app --out-dir ./apps/my-app
30
+ ```
31
+
32
+ ### Resource hooks
33
+
34
+ Pass the **PascalCase singular** type name (e.g. `Resource`, not `resource`). Writes to `src/hooks/query-hooks/`.
35
+
36
+ ```bash
37
+ # all hooks, single-record mutations (default)
38
+ vite-gen create Resource -t resource-hooks
39
+
40
+ # bulk mutations (arrays)
41
+ vite-gen create Resource -t resource-hooks --variant bulk
42
+
43
+ # only some hooks
44
+ vite-gen create User -t resource-hooks --hooks list,show,create
45
+
46
+ # irregular plural
47
+ vite-gen create Person -t resource-hooks --plural People
48
+
49
+ # write into an existing app root
50
+ vite-gen create Resource -t resource-hooks --out-dir ../gyst-tracker-web
51
+ ```
52
+
53
+ `--hooks` accepts: `list`, `show`, `create`, `update`, `delete`, or `all` (default).
54
+
55
+ ### Resource API
56
+
57
+ Same naming rules. Writes to `src/api/<plural>.api.ts`.
58
+
59
+ ```bash
60
+ # all methods, single-record body (default)
61
+ vite-gen create Condition -t resource-api
62
+
63
+ # bulk create/update/delete (matches conditions-style APIs)
64
+ vite-gen create Condition -t resource-api --variant bulk
65
+
66
+ # only some methods
67
+ vite-gen create Condition -t resource-api --methods list,show,create
68
+
69
+ # custom route path
70
+ vite-gen create Condition -t resource-api --variant bulk --path conditions
71
+ ```
72
+
73
+ `--methods` accepts: `list`, `show`, `create`, `update`, `delete`, or `all` (default).
74
+
75
+ ### Resource page
76
+
77
+ Pass the **PascalCase singular** type name. Requires `--dir` for the parent folder. Creates a **plural** folder with page, CSS module, and form.
78
+
79
+ ```bash
80
+ vite-gen create Role -t resource-page --dir src/pages
81
+ # → src/pages/Roles/RolesPage.tsx
82
+ # → src/pages/Roles/RolesPage.module.css
83
+ # → src/pages/Roles/components/RoleForm.tsx
84
+
85
+ # irregular plural
86
+ vite-gen create Person -t resource-page --dir src/pages --plural People
87
+ ```
88
+
89
+ Form fields: `display_name` and `name` (name auto-filled via `toSnakeCase` from display_name on create).
90
+
91
+ ## Adding a template
92
+
93
+ 1. Create a `TemplateDefinition` in `src/generator/` (see `hello-world.ts` / `resource-hooks.ts`).
94
+ 2. Register it in `src/generator/registry.ts`.
95
+ 3. Rebuild. Template-specific flags declared on the definition are wired into the CLI automatically.
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from '../dist/cli/index.js';
3
+
4
+ runCli(process.argv);
@@ -0,0 +1,4 @@
1
+ import { Command } from 'commander';
2
+ export declare function createCli(): Command;
3
+ export declare function runCli(argv: string[]): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,wBAAgB,SAAS,IAAI,OAAO,CA4HnC;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1D"}
@@ -0,0 +1,124 @@
1
+ import { Command } from 'commander';
2
+ import path from 'node:path';
3
+ import { generateProject, getTemplate, listTemplates } from '../generator/index.js';
4
+ function collectFlag(value, previous) {
5
+ const eq = value.indexOf('=');
6
+ if (eq === -1) {
7
+ throw new Error(`Invalid --flag value "${value}". Use key=value (e.g. greeting=Hi).`);
8
+ }
9
+ const key = value.slice(0, eq).trim();
10
+ const val = value.slice(eq + 1);
11
+ if (!key) {
12
+ throw new Error(`Invalid --flag value "${value}". Key cannot be empty.`);
13
+ }
14
+ return { ...previous, [key]: val };
15
+ }
16
+ export function createCli() {
17
+ const program = new Command();
18
+ program
19
+ .name('vite-gen')
20
+ .description('Generate Vite TypeScript projects and code from templates')
21
+ .version('0.1.0');
22
+ program
23
+ .command('list')
24
+ .description('List available templates')
25
+ .action(() => {
26
+ const templates = listTemplates();
27
+ if (templates.length === 0) {
28
+ console.log('No templates registered.');
29
+ return;
30
+ }
31
+ for (const t of templates) {
32
+ const kind = t.kind ?? 'project';
33
+ console.log(`${t.name.padEnd(18)} [${kind}] ${t.description}`);
34
+ if (t.flags?.length) {
35
+ for (const flag of t.flags) {
36
+ const def = flag.defaultValue !== undefined && flag.defaultValue !== ''
37
+ ? ` (default: ${String(flag.defaultValue)})`
38
+ : '';
39
+ console.log(` --${flag.name}${def}: ${flag.description}`);
40
+ }
41
+ }
42
+ }
43
+ });
44
+ program
45
+ .command('create')
46
+ .description('Create from a template (project scaffold or generated files)')
47
+ .argument('<name>', 'project name, or PascalCase singular resource name for file templates')
48
+ .option('-t, --template <name>', 'template to use', 'hello-world')
49
+ .option('-o, --out-dir <path>', 'output directory (project: ./<name>; file templates: .)')
50
+ .option('-f, --flag <key=value>', 'template-specific flag (repeatable)', collectFlag, {})
51
+ .action(async (name, opts) => {
52
+ const template = getTemplate(opts.template);
53
+ if (!template) {
54
+ const available = listTemplates().map((t) => t.name).join(', ');
55
+ console.error(`Unknown template "${opts.template}". Available: ${available}`);
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+ const flags = {};
60
+ for (const def of template.flags ?? []) {
61
+ flags[def.name] = def.defaultValue;
62
+ }
63
+ Object.assign(flags, opts.flag);
64
+ const kind = template.kind ?? 'project';
65
+ const outDir = opts.outDir
66
+ ? path.resolve(opts.outDir)
67
+ : kind === 'file'
68
+ ? process.cwd()
69
+ : path.resolve(process.cwd(), name);
70
+ try {
71
+ const target = await generateProject({
72
+ projectName: name,
73
+ outDir,
74
+ template: opts.template,
75
+ flags,
76
+ });
77
+ if (kind === 'file') {
78
+ console.log(`Generated ${opts.template} for ${name} in ${target}`);
79
+ }
80
+ else {
81
+ console.log(`Created ${opts.template} project at ${target}`);
82
+ console.log(`\n cd ${path.relative(process.cwd(), target) || '.'}`);
83
+ console.log(' npm install');
84
+ console.log(' npm run dev\n');
85
+ }
86
+ }
87
+ catch (err) {
88
+ console.error(err instanceof Error ? err.message : err);
89
+ process.exitCode = 1;
90
+ }
91
+ });
92
+ // Register known template flags as first-class create options so
93
+ // `vite-gen create my-app --greeting "Hi"` works without --flag.
94
+ const createCmd = program.commands.find((c) => c.name() === 'create');
95
+ if (createCmd) {
96
+ for (const template of listTemplates()) {
97
+ for (const flag of template.flags ?? []) {
98
+ const optionName = `--${flag.name} <value>`;
99
+ if (!createCmd.options.some((o) => o.long === `--${flag.name}`)) {
100
+ createCmd.option(optionName, flag.description);
101
+ }
102
+ }
103
+ }
104
+ createCmd.hook('preAction', (_thisCommand, actionCommand) => {
105
+ const opts = actionCommand.opts();
106
+ const flagBag = opts.flag ?? {};
107
+ for (const template of listTemplates()) {
108
+ for (const flag of template.flags ?? []) {
109
+ const value = opts[flag.name];
110
+ if (typeof value === 'string') {
111
+ flagBag[flag.name] = value;
112
+ }
113
+ }
114
+ }
115
+ actionCommand.setOptionValue('flag', flagBag);
116
+ });
117
+ }
118
+ return program;
119
+ }
120
+ export async function runCli(argv) {
121
+ const program = createCli();
122
+ await program.parseAsync(argv);
123
+ }
124
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const CRUD_KINDS: readonly ["list", "show", "create", "update", "delete"];
2
+ export type CrudKind = (typeof CRUD_KINDS)[number];
3
+ export type ResourceVariant = 'single' | 'bulk';
4
+ export declare function parseCrudKinds(raw: string | boolean | undefined, label?: string): Set<CrudKind>;
5
+ export declare function parseVariant(raw: string | boolean | undefined): ResourceVariant;
6
+ /** PascalCase → snake_case path segment, e.g. PricingConfigs → pricing_configs */
7
+ export declare function toSnakeCase(pascal: string): string;
8
+ //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../src/generator/crud.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,yDAA0D,CAAC;AAClF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AACnD,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,EACjC,KAAK,SAAW,GACf,GAAG,CAAC,QAAQ,CAAC,CAqBf;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,eAAe,CAI/E;AAED,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKlD"}
@@ -0,0 +1,33 @@
1
+ export const CRUD_KINDS = ['list', 'show', 'create', 'update', 'delete'];
2
+ export function parseCrudKinds(raw, label = 'method') {
3
+ const value = typeof raw === 'string' ? raw.trim() : '';
4
+ if (!value || value === 'all') {
5
+ return new Set(CRUD_KINDS);
6
+ }
7
+ const parts = value.split(',').map((p) => p.trim().toLowerCase()).filter(Boolean);
8
+ if (parts.length === 0) {
9
+ return new Set(CRUD_KINDS);
10
+ }
11
+ const selected = new Set();
12
+ for (const part of parts) {
13
+ if (!CRUD_KINDS.includes(part)) {
14
+ throw new Error(`Unknown ${label} "${part}". Valid: ${CRUD_KINDS.join(', ')}, or all`);
15
+ }
16
+ selected.add(part);
17
+ }
18
+ return selected;
19
+ }
20
+ export function parseVariant(raw) {
21
+ const value = typeof raw === 'string' ? raw.trim().toLowerCase() : 'single';
22
+ if (value === 'single' || value === 'bulk')
23
+ return value;
24
+ throw new Error(`Unknown variant "${String(raw)}". Valid: single, bulk`);
25
+ }
26
+ /** PascalCase → snake_case path segment, e.g. PricingConfigs → pricing_configs */
27
+ export function toSnakeCase(pascal) {
28
+ return pascal
29
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
30
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
31
+ .toLowerCase();
32
+ }
33
+ //# sourceMappingURL=crud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.js","sourceRoot":"","sources":["../../src/generator/crud.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAIlF,MAAM,UAAU,cAAc,CAC5B,GAAiC,EACjC,KAAK,GAAG,QAAQ;IAEhB,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACxD,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAC9B,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAY,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAE,UAAgC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CACb,WAAW,KAAK,KAAK,IAAI,aAAa,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACtE,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,IAAgB,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAiC;IAC5D,MAAM,KAAK,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC5E,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzD,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAC3E,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,MAAM;SACV,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;SACxC,WAAW,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TemplateDefinition } from '../types.js';
2
+ export declare const helloWorldTemplate: TemplateDefinition;
3
+ //# sourceMappingURL=hello-world.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hello-world.d.ts","sourceRoot":"","sources":["../../src/generator/hello-world.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAgB,MAAM,aAAa,CAAC;AAgJrF,eAAO,MAAM,kBAAkB,EAAE,kBAqChC,CAAC"}
@@ -0,0 +1,162 @@
1
+ function packageJson(name) {
2
+ return `${JSON.stringify({
3
+ name,
4
+ private: true,
5
+ version: '0.0.0',
6
+ type: 'module',
7
+ scripts: {
8
+ dev: 'vite',
9
+ build: 'tsc && vite build',
10
+ preview: 'vite preview',
11
+ },
12
+ devDependencies: {
13
+ typescript: '~5.8.2',
14
+ vite: '^6.2.0',
15
+ },
16
+ }, null, 2)}\n`;
17
+ }
18
+ function tsconfig() {
19
+ return `${JSON.stringify({
20
+ compilerOptions: {
21
+ target: 'ES2022',
22
+ useDefineForClassFields: true,
23
+ module: 'ESNext',
24
+ lib: ['ES2022', 'DOM', 'DOM.Iterable'],
25
+ skipLibCheck: true,
26
+ moduleResolution: 'bundler',
27
+ allowImportingTsExtensions: true,
28
+ isolatedModules: true,
29
+ moduleDetection: 'force',
30
+ noEmit: true,
31
+ strict: true,
32
+ noUnusedLocals: true,
33
+ noUnusedParameters: true,
34
+ noFallthroughCasesInSwitch: true,
35
+ noUncheckedSideEffectImports: true,
36
+ },
37
+ include: ['src'],
38
+ }, null, 2)}\n`;
39
+ }
40
+ function viteConfig() {
41
+ return `import { defineConfig } from 'vite';
42
+
43
+ export default defineConfig({
44
+ // https://vite.dev/config/
45
+ });
46
+ `;
47
+ }
48
+ function indexHtml(projectName, title) {
49
+ return `<!doctype html>
50
+ <html lang="en">
51
+ <head>
52
+ <meta charset="UTF-8" />
53
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
54
+ <title>${title || projectName}</title>
55
+ </head>
56
+ <body>
57
+ <div id="app"></div>
58
+ <script type="module" src="/src/main.ts"></script>
59
+ </body>
60
+ </html>
61
+ `;
62
+ }
63
+ function mainTs(greeting) {
64
+ return `import './style.css';
65
+
66
+ const app = document.querySelector<HTMLDivElement>('#app');
67
+
68
+ if (app) {
69
+ app.innerHTML = \`
70
+ <h1>${greeting}</h1>
71
+ <p>Edit <code>src/main.ts</code> and save to reload.</p>
72
+ \`;
73
+ }
74
+ `;
75
+ }
76
+ function styleCss() {
77
+ return `:root {
78
+ font-family: system-ui, sans-serif;
79
+ line-height: 1.5;
80
+ color: #213547;
81
+ background-color: #ffffff;
82
+ }
83
+
84
+ body {
85
+ margin: 0;
86
+ min-height: 100vh;
87
+ display: flex;
88
+ place-items: center;
89
+ }
90
+
91
+ #app {
92
+ max-width: 40rem;
93
+ margin: 0 auto;
94
+ padding: 2rem;
95
+ text-align: center;
96
+ }
97
+
98
+ code {
99
+ font-family: ui-monospace, monospace;
100
+ background: #f4f4f5;
101
+ padding: 0.15em 0.4em;
102
+ border-radius: 4px;
103
+ }
104
+ `;
105
+ }
106
+ function gitignore() {
107
+ return `node_modules
108
+ dist
109
+ dist-ssr
110
+ *.local
111
+ .DS_Store
112
+ `;
113
+ }
114
+ function readme(projectName) {
115
+ return `# ${projectName}
116
+
117
+ Generated with \`vite-code-generator\` (hello-world template).
118
+
119
+ ## Scripts
120
+
121
+ \`\`\`bash
122
+ npm install
123
+ npm run dev
124
+ \`\`\`
125
+ `;
126
+ }
127
+ export const helloWorldTemplate = {
128
+ name: 'hello-world',
129
+ description: 'Minimal Vite + TypeScript hello world app',
130
+ kind: 'project',
131
+ flags: [
132
+ {
133
+ name: 'greeting',
134
+ description: 'Text shown in the page heading',
135
+ defaultValue: 'Hello World',
136
+ },
137
+ {
138
+ name: 'title',
139
+ description: 'HTML document title',
140
+ defaultValue: '',
141
+ },
142
+ ],
143
+ resolveFiles(context) {
144
+ const greeting = typeof context.flags.greeting === 'string' && context.flags.greeting.length > 0
145
+ ? context.flags.greeting
146
+ : 'Hello World';
147
+ const title = typeof context.flags.title === 'string' && context.flags.title.length > 0
148
+ ? context.flags.title
149
+ : context.projectName;
150
+ return [
151
+ { path: 'package.json', content: packageJson(context.projectName) },
152
+ { path: 'tsconfig.json', content: tsconfig() },
153
+ { path: 'vite.config.ts', content: viteConfig() },
154
+ { path: 'index.html', content: indexHtml(context.projectName, title) },
155
+ { path: 'src/main.ts', content: mainTs(greeting) },
156
+ { path: 'src/style.css', content: styleCss() },
157
+ { path: '.gitignore', content: gitignore() },
158
+ { path: 'README.md', content: readme(context.projectName) },
159
+ ];
160
+ },
161
+ };
162
+ //# sourceMappingURL=hello-world.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hello-world.js","sourceRoot":"","sources":["../../src/generator/hello-world.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type GenerateOptions = {
2
+ projectName: string;
3
+ outDir: string;
4
+ template: string;
5
+ flags?: Record<string, string | boolean | undefined>;
6
+ };
7
+ export { getTemplate, listTemplates, registerTemplate } from './registry.js';
8
+ export declare function generateProject(options: GenerateOptions): Promise<string>;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CACtD,CAAC;AAEF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE7E,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B/E"}
@@ -0,0 +1,26 @@
1
+ import { mkdir, writeFile } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { getTemplate, listTemplates } from './registry.js';
4
+ export { getTemplate, listTemplates, registerTemplate } from './registry.js';
5
+ export async function generateProject(options) {
6
+ const template = getTemplate(options.template);
7
+ if (!template) {
8
+ const available = listTemplates()
9
+ .map((t) => t.name)
10
+ .join(', ');
11
+ throw new Error(`Unknown template "${options.template}". Available: ${available || '(none)'}`);
12
+ }
13
+ const targetDir = path.resolve(options.outDir);
14
+ const context = {
15
+ projectName: options.projectName,
16
+ flags: options.flags ?? {},
17
+ };
18
+ const files = template.resolveFiles(context);
19
+ for (const file of files) {
20
+ const filePath = path.join(targetDir, file.path);
21
+ await mkdir(path.dirname(filePath), { recursive: true });
22
+ await writeFile(filePath, file.content, 'utf8');
23
+ }
24
+ return targetDir;
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU3D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE7E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAwB;IAC5D,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,aAAa,EAAE;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CACb,qBAAqB,OAAO,CAAC,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,EAAE,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAoB;QAC/B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;KAC3B,CAAC;IAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,20 @@
1
+ export type ResourceNames = {
2
+ /** PascalCase singular, e.g. Resource */
3
+ singular: string;
4
+ /** PascalCase plural, e.g. Resources */
5
+ plural: string;
6
+ /** camelCase singular, e.g. resource */
7
+ singularCamel: string;
8
+ /** camelCase plural, e.g. resources */
9
+ pluralCamel: string;
10
+ /** SCREAMING_SNAKE singular, e.g. RESOURCE */
11
+ singularConst: string;
12
+ /** SCREAMING_SNAKE plural, e.g. RESOURCES */
13
+ pluralConst: string;
14
+ };
15
+ /**
16
+ * Derive naming variants from a PascalCase singular resource name.
17
+ * Example: Resource → resource, Resources, resources, RESOURCE, RESOURCES
18
+ */
19
+ export declare function deriveResourceNames(singularPascal: string, pluralOverride?: string): ResourceNames;
20
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/generator/naming.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAsBF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,cAAc,CAAC,EAAE,MAAM,GACtB,aAAa,CAqBf"}
@@ -0,0 +1,42 @@
1
+ function toCamelCase(pascal) {
2
+ if (!pascal)
3
+ return pascal;
4
+ return pascal[0].toLowerCase() + pascal.slice(1);
5
+ }
6
+ function toScreamingSnake(pascal) {
7
+ return pascal
8
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
9
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
10
+ .toUpperCase();
11
+ }
12
+ function defaultPlural(singular) {
13
+ if (singular.endsWith('s'))
14
+ return singular;
15
+ if (singular.endsWith('y') && singular.length > 1 && !/[aeiou]y$/i.test(singular)) {
16
+ return `${singular.slice(0, -1)}ies`;
17
+ }
18
+ return `${singular}s`;
19
+ }
20
+ /**
21
+ * Derive naming variants from a PascalCase singular resource name.
22
+ * Example: Resource → resource, Resources, resources, RESOURCE, RESOURCES
23
+ */
24
+ export function deriveResourceNames(singularPascal, pluralOverride) {
25
+ const singular = singularPascal.trim();
26
+ if (!singular || singular !== singular[0].toUpperCase() + singular.slice(1) || !/^[A-Z][A-Za-z0-9]*$/.test(singular)) {
27
+ throw new Error(`Resource name must be PascalCase singular (e.g. Resource, User). Got "${singularPascal}".`);
28
+ }
29
+ const plural = (pluralOverride?.trim() || defaultPlural(singular));
30
+ if (!/^[A-Z][A-Za-z0-9]*$/.test(plural)) {
31
+ throw new Error(`Plural name must be PascalCase (e.g. Resources). Got "${plural}".`);
32
+ }
33
+ return {
34
+ singular,
35
+ plural,
36
+ singularCamel: toCamelCase(singular),
37
+ pluralCamel: toCamelCase(plural),
38
+ singularConst: toScreamingSnake(singular),
39
+ pluralConst: toScreamingSnake(plural),
40
+ };
41
+ }
42
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/generator/naming.ts"],"names":[],"mappings":"AAeA,SAAS,WAAW,CAAC,MAAc;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,MAAM,CAAC;IAC3B,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc;IACtC,OAAO,MAAM;SACV,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;SACxC,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC5C,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClF,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IACvC,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EACtB,cAAuB;IAEvB,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrH,MAAM,IAAI,KAAK,CACb,yEAAyE,cAAc,IAAI,CAC5F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,yDAAyD,MAAM,IAAI,CAAC,CAAC;IACvF,CAAC;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,aAAa,EAAE,WAAW,CAAC,QAAQ,CAAC;QACpC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC;QAChC,aAAa,EAAE,gBAAgB,CAAC,QAAQ,CAAC;QACzC,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { TemplateDefinition } from '../types.js';
2
+ export declare function listTemplates(): TemplateDefinition[];
3
+ export declare function getTemplate(name: string): TemplateDefinition | undefined;
4
+ export declare function registerTemplate(template: TemplateDefinition): void;
5
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/generator/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAatD,wBAAgB,aAAa,IAAI,kBAAkB,EAAE,CAEpD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAExE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAEnE"}
@@ -0,0 +1,20 @@
1
+ import { helloWorldTemplate } from './hello-world.js';
2
+ import { resourceApiTemplate } from './resource-api.js';
3
+ import { resourceHooksTemplate } from './resource-hooks.js';
4
+ import { resourcePageTemplate } from './resource-page.js';
5
+ const templates = {
6
+ [helloWorldTemplate.name]: helloWorldTemplate,
7
+ [resourceApiTemplate.name]: resourceApiTemplate,
8
+ [resourceHooksTemplate.name]: resourceHooksTemplate,
9
+ [resourcePageTemplate.name]: resourcePageTemplate,
10
+ };
11
+ export function listTemplates() {
12
+ return Object.values(templates);
13
+ }
14
+ export function getTemplate(name) {
15
+ return templates[name];
16
+ }
17
+ export function registerTemplate(template) {
18
+ templates[template.name] = template;
19
+ }
20
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/generator/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,SAAS,GAAuC;IACpD,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,kBAAkB;IAC7C,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,mBAAmB;IAC/C,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,qBAAqB;IACnD,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,oBAAoB;CAClD,CAAC;AAEF,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAA4B;IAC3D,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;AACtC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { TemplateDefinition } from '../types.js';
2
+ export declare const resourceApiTemplate: TemplateDefinition;
3
+ //# sourceMappingURL=resource-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-api.d.ts","sourceRoot":"","sources":["../../src/generator/resource-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,kBAAkB,EAAgB,MAAM,aAAa,CAAC;AAqHrF,eAAO,MAAM,mBAAmB,EAAE,kBAgDjC,CAAC"}