@compilr-dev/factory 0.1.9 → 0.1.11
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/dist/factory/registry.js +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/toolkits/react-fastapi/api.d.ts +9 -0
- package/dist/toolkits/react-fastapi/api.js +378 -0
- package/dist/toolkits/react-fastapi/config.d.ts +9 -0
- package/dist/toolkits/react-fastapi/config.js +128 -0
- package/dist/toolkits/react-fastapi/helpers.d.ts +13 -0
- package/dist/toolkits/react-fastapi/helpers.js +54 -0
- package/dist/toolkits/react-fastapi/index.d.ts +11 -0
- package/dist/toolkits/react-fastapi/index.js +55 -0
- package/dist/toolkits/react-fastapi/seed.d.ts +12 -0
- package/dist/toolkits/react-fastapi/seed.js +54 -0
- package/dist/toolkits/react-fastapi/shared.d.ts +6 -0
- package/dist/toolkits/react-fastapi/shared.js +6 -0
- package/dist/toolkits/react-fastapi/static.d.ts +8 -0
- package/dist/toolkits/react-fastapi/static.js +123 -0
- package/dist/toolkits/react-go/api.d.ts +12 -0
- package/dist/toolkits/react-go/api.js +523 -0
- package/dist/toolkits/react-go/config.d.ts +9 -0
- package/dist/toolkits/react-go/config.js +129 -0
- package/dist/toolkits/react-go/helpers.d.ts +13 -0
- package/dist/toolkits/react-go/helpers.js +49 -0
- package/dist/toolkits/react-go/index.d.ts +11 -0
- package/dist/toolkits/react-go/index.js +55 -0
- package/dist/toolkits/react-go/seed.d.ts +12 -0
- package/dist/toolkits/react-go/seed.js +55 -0
- package/dist/toolkits/react-go/shared.d.ts +6 -0
- package/dist/toolkits/react-go/shared.js +6 -0
- package/dist/toolkits/react-go/static.d.ts +8 -0
- package/dist/toolkits/react-go/static.js +122 -0
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit — Helpers
|
|
3
|
+
*
|
|
4
|
+
* Go-specific helpers plus re-exports from shared helpers.
|
|
5
|
+
*/
|
|
6
|
+
/** Map a model FieldType to a Go type string. */
|
|
7
|
+
export function goType(field) {
|
|
8
|
+
const lowerName = field.name.toLowerCase();
|
|
9
|
+
switch (field.type) {
|
|
10
|
+
case 'string':
|
|
11
|
+
case 'enum':
|
|
12
|
+
case 'date':
|
|
13
|
+
return 'string';
|
|
14
|
+
case 'number':
|
|
15
|
+
if (lowerName.includes('price') ||
|
|
16
|
+
lowerName.includes('cost') ||
|
|
17
|
+
lowerName.includes('amount')) {
|
|
18
|
+
return 'float64';
|
|
19
|
+
}
|
|
20
|
+
return 'int';
|
|
21
|
+
case 'boolean':
|
|
22
|
+
return 'bool';
|
|
23
|
+
default:
|
|
24
|
+
return 'string';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Generate a Go zero value string for a field. */
|
|
28
|
+
export function goZeroValue(field) {
|
|
29
|
+
switch (field.type) {
|
|
30
|
+
case 'string':
|
|
31
|
+
case 'enum':
|
|
32
|
+
case 'date':
|
|
33
|
+
return '""';
|
|
34
|
+
case 'number':
|
|
35
|
+
return '0';
|
|
36
|
+
case 'boolean':
|
|
37
|
+
return 'false';
|
|
38
|
+
default:
|
|
39
|
+
return '""';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Convert PascalCase or camelCase to snake_case. */
|
|
43
|
+
export function toSnakeCase(name) {
|
|
44
|
+
return name
|
|
45
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
46
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
|
|
47
|
+
.toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
export { indent, tsType, fkFieldName, belongsToRels, hasManyRels, routePath, apiPath, inputType, generateImports, } from '../shared/helpers.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit
|
|
3
|
+
*
|
|
4
|
+
* Generates a full-stack MVP: React 18 + Vite + Tailwind + Go (net/http).
|
|
5
|
+
* Deterministic: same ApplicationModel -> same output files.
|
|
6
|
+
*
|
|
7
|
+
* Frontend is identical to react-node (same React components, Vite config, Tailwind).
|
|
8
|
+
* Backend is Go net/http stdlib with in-memory data stores.
|
|
9
|
+
*/
|
|
10
|
+
import type { FactoryToolkit } from '../types.js';
|
|
11
|
+
export declare const reactGoToolkit: FactoryToolkit;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit
|
|
3
|
+
*
|
|
4
|
+
* Generates a full-stack MVP: React 18 + Vite + Tailwind + Go (net/http).
|
|
5
|
+
* Deterministic: same ApplicationModel -> same output files.
|
|
6
|
+
*
|
|
7
|
+
* Frontend is identical to react-node (same React components, Vite config, Tailwind).
|
|
8
|
+
* Backend is Go net/http stdlib with in-memory data stores.
|
|
9
|
+
*/
|
|
10
|
+
import { generateConfigFiles } from './config.js';
|
|
11
|
+
import { generateStaticFiles } from './static.js';
|
|
12
|
+
import { generateShellFiles } from '../react-node/shell.js';
|
|
13
|
+
import { generateSharedComponents } from './shared.js';
|
|
14
|
+
import { generateDashboard } from '../react-node/dashboard.js';
|
|
15
|
+
import { generateEntityFiles } from '../react-node/entity.js';
|
|
16
|
+
import { generateRouter } from '../react-node/router.js';
|
|
17
|
+
import { generateApiFiles } from './api.js';
|
|
18
|
+
import { generateTypesFile } from '../react-node/types-gen.js';
|
|
19
|
+
export const reactGoToolkit = {
|
|
20
|
+
id: 'react-go',
|
|
21
|
+
name: 'React + Go',
|
|
22
|
+
description: 'React 18 + Vite + Tailwind CSS + Go — full-stack MVP with Go net/http backend',
|
|
23
|
+
requiredSections: ['identity', 'entities', 'layout', 'features', 'theme'],
|
|
24
|
+
generate(model) {
|
|
25
|
+
const warnings = [];
|
|
26
|
+
const allFiles = [];
|
|
27
|
+
// Collect files from all generators
|
|
28
|
+
const generators = [
|
|
29
|
+
generateConfigFiles(model),
|
|
30
|
+
generateStaticFiles(model),
|
|
31
|
+
generateTypesFile(model),
|
|
32
|
+
generateShellFiles(model),
|
|
33
|
+
generateSharedComponents(),
|
|
34
|
+
generateDashboard(model),
|
|
35
|
+
generateEntityFiles(model),
|
|
36
|
+
generateRouter(model),
|
|
37
|
+
generateApiFiles(model),
|
|
38
|
+
];
|
|
39
|
+
for (const files of generators) {
|
|
40
|
+
allFiles.push(...files);
|
|
41
|
+
}
|
|
42
|
+
// Check for potential issues
|
|
43
|
+
if (model.entities.length === 0) {
|
|
44
|
+
warnings.push('No entities defined — generated app will have minimal functionality.');
|
|
45
|
+
}
|
|
46
|
+
if (model.entities.length > 10) {
|
|
47
|
+
warnings.push('Large number of entities — generated sidebar may be crowded.');
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
files: allFiles,
|
|
51
|
+
toolkit: 'react-go',
|
|
52
|
+
warnings,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit — Seed Data Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates realistic mock data in Go struct literal format.
|
|
5
|
+
* Uses shared generateFieldValue for deterministic values,
|
|
6
|
+
* wraps them in Go slice-of-structs format for in-memory data stores.
|
|
7
|
+
*/
|
|
8
|
+
import type { ApplicationModel, Entity } from '../../model/types.js';
|
|
9
|
+
import { SEED_COUNT } from '../shared/seed-data.js';
|
|
10
|
+
/** Generate seed data items for a single entity (Go slice format). */
|
|
11
|
+
export declare function generateSeedData(model: ApplicationModel, entity: Entity): string;
|
|
12
|
+
export { SEED_COUNT };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit — Seed Data Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates realistic mock data in Go struct literal format.
|
|
5
|
+
* Uses shared generateFieldValue for deterministic values,
|
|
6
|
+
* wraps them in Go slice-of-structs format for in-memory data stores.
|
|
7
|
+
*/
|
|
8
|
+
import { belongsToRels, fkFieldName } from './helpers.js';
|
|
9
|
+
import { toPascalCase } from '../../model/naming.js';
|
|
10
|
+
import { generateFieldValue, SEED_COUNT } from '../shared/seed-data.js';
|
|
11
|
+
/** Generate seed data items for a single entity (Go slice format). */
|
|
12
|
+
export function generateSeedData(model, entity) {
|
|
13
|
+
const rels = belongsToRels(entity);
|
|
14
|
+
const lines = [];
|
|
15
|
+
lines.push(`var seedData = []${entity.name}{`);
|
|
16
|
+
for (let i = 0; i < SEED_COUNT; i++) {
|
|
17
|
+
const fields = [];
|
|
18
|
+
fields.push(`ID: ${String(i + 1)}`);
|
|
19
|
+
for (const field of entity.fields) {
|
|
20
|
+
const jsValue = generateFieldValue(field, i, entity.name);
|
|
21
|
+
const goValue = jsToGoValue(jsValue, field.type);
|
|
22
|
+
fields.push(`${toPascalCase(field.name)}: ${goValue}`);
|
|
23
|
+
}
|
|
24
|
+
// FK fields from belongsTo relationships
|
|
25
|
+
for (const rel of rels) {
|
|
26
|
+
const fk = fkFieldName(rel);
|
|
27
|
+
const targetEntity = model.entities.find((e) => e.name === rel.target);
|
|
28
|
+
const targetCount = targetEntity ? SEED_COUNT : SEED_COUNT;
|
|
29
|
+
fields.push(`${toPascalCase(fk)}: ${String((i % targetCount) + 1)}`);
|
|
30
|
+
}
|
|
31
|
+
// Implicit timestamps (deterministic)
|
|
32
|
+
const createdDate = new Date('2025-06-01T10:00:00Z');
|
|
33
|
+
createdDate.setDate(createdDate.getDate() + i * 2);
|
|
34
|
+
const updatedDate = new Date(createdDate);
|
|
35
|
+
updatedDate.setDate(updatedDate.getDate() + i);
|
|
36
|
+
fields.push(`CreatedAt: "${createdDate.toISOString()}"`);
|
|
37
|
+
fields.push(`UpdatedAt: "${updatedDate.toISOString()}"`);
|
|
38
|
+
lines.push(`\t{${fields.join(', ')}},`);
|
|
39
|
+
}
|
|
40
|
+
lines.push('}');
|
|
41
|
+
return lines.join('\n');
|
|
42
|
+
}
|
|
43
|
+
/** Convert a JS seed value string to Go format. */
|
|
44
|
+
function jsToGoValue(jsValue, fieldType) {
|
|
45
|
+
if (fieldType === 'boolean') {
|
|
46
|
+
return jsValue; // true/false same in Go
|
|
47
|
+
}
|
|
48
|
+
// String/enum/date values come wrapped in single quotes — convert to double quotes
|
|
49
|
+
if (jsValue.startsWith("'") && jsValue.endsWith("'")) {
|
|
50
|
+
return `"${jsValue.slice(1, -1)}"`;
|
|
51
|
+
}
|
|
52
|
+
// Numbers pass through unchanged
|
|
53
|
+
return jsValue;
|
|
54
|
+
}
|
|
55
|
+
export { SEED_COUNT };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit — Static Files Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates: .gitignore, .env.example, README.md, index.html, src/main.tsx, src/index.css
|
|
5
|
+
*/
|
|
6
|
+
import type { ApplicationModel } from '../../model/types.js';
|
|
7
|
+
import type { FactoryFile } from '../types.js';
|
|
8
|
+
export declare function generateStaticFiles(model: ApplicationModel): FactoryFile[];
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React+Go Toolkit — Static Files Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates: .gitignore, .env.example, README.md, index.html, src/main.tsx, src/index.css
|
|
5
|
+
*/
|
|
6
|
+
export function generateStaticFiles(model) {
|
|
7
|
+
return [
|
|
8
|
+
generateGitignore(),
|
|
9
|
+
generateEnvExample(),
|
|
10
|
+
generateReadme(model),
|
|
11
|
+
generateIndexHtml(model),
|
|
12
|
+
generateMainTsx(),
|
|
13
|
+
generateIndexCss(),
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
function generateGitignore() {
|
|
17
|
+
return {
|
|
18
|
+
path: '.gitignore',
|
|
19
|
+
content: `node_modules
|
|
20
|
+
dist
|
|
21
|
+
.env
|
|
22
|
+
*.local
|
|
23
|
+
bin/
|
|
24
|
+
*.exe
|
|
25
|
+
`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function generateEnvExample() {
|
|
29
|
+
return {
|
|
30
|
+
path: '.env.example',
|
|
31
|
+
content: `PORT=8080
|
|
32
|
+
VITE_API_URL=http://localhost:8080
|
|
33
|
+
`,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function generateReadme(model) {
|
|
37
|
+
let entitiesSection = '';
|
|
38
|
+
if (model.entities.length > 0) {
|
|
39
|
+
const entityLines = model.entities
|
|
40
|
+
.map((e) => {
|
|
41
|
+
const relCount = e.relationships.length;
|
|
42
|
+
const parts = [`${String(e.fields.length)} fields`];
|
|
43
|
+
if (relCount > 0) {
|
|
44
|
+
parts.push(`${String(relCount)} relationship${relCount > 1 ? 's' : ''}`);
|
|
45
|
+
}
|
|
46
|
+
return `- **${e.name}** (${e.icon}) — ${parts.join(', ')}`;
|
|
47
|
+
})
|
|
48
|
+
.join('\n');
|
|
49
|
+
entitiesSection = `\n## Entities\n\n${entityLines}\n`;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
path: 'README.md',
|
|
53
|
+
content: `# ${model.identity.name}
|
|
54
|
+
|
|
55
|
+
${model.identity.description}
|
|
56
|
+
${entitiesSection}
|
|
57
|
+
## Getting Started
|
|
58
|
+
|
|
59
|
+
\`\`\`bash
|
|
60
|
+
npm install
|
|
61
|
+
go run ./server
|
|
62
|
+
npm run dev
|
|
63
|
+
\`\`\`
|
|
64
|
+
|
|
65
|
+
This starts both the Vite dev server and the Go server.
|
|
66
|
+
|
|
67
|
+
- **Frontend:** http://localhost:5173
|
|
68
|
+
- **API:** http://localhost:8080
|
|
69
|
+
|
|
70
|
+
## Tech Stack
|
|
71
|
+
|
|
72
|
+
- React 18 + TypeScript
|
|
73
|
+
- Vite
|
|
74
|
+
- Tailwind CSS
|
|
75
|
+
- Go (net/http)
|
|
76
|
+
- React Router v6
|
|
77
|
+
`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function generateIndexHtml(model) {
|
|
81
|
+
return {
|
|
82
|
+
path: 'index.html',
|
|
83
|
+
content: `<!doctype html>
|
|
84
|
+
<html lang="en">
|
|
85
|
+
<head>
|
|
86
|
+
<meta charset="UTF-8" />
|
|
87
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
88
|
+
<title>${model.identity.name}</title>
|
|
89
|
+
</head>
|
|
90
|
+
<body>
|
|
91
|
+
<div id="root"></div>
|
|
92
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
93
|
+
</body>
|
|
94
|
+
</html>
|
|
95
|
+
`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function generateMainTsx() {
|
|
99
|
+
return {
|
|
100
|
+
path: 'src/main.tsx',
|
|
101
|
+
content: `import React from 'react';
|
|
102
|
+
import ReactDOM from 'react-dom/client';
|
|
103
|
+
import App from './App';
|
|
104
|
+
import './index.css';
|
|
105
|
+
|
|
106
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
107
|
+
<React.StrictMode>
|
|
108
|
+
<App />
|
|
109
|
+
</React.StrictMode>,
|
|
110
|
+
);
|
|
111
|
+
`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function generateIndexCss() {
|
|
115
|
+
return {
|
|
116
|
+
path: 'src/index.css',
|
|
117
|
+
content: `@tailwind base;
|
|
118
|
+
@tailwind components;
|
|
119
|
+
@tailwind utilities;
|
|
120
|
+
`,
|
|
121
|
+
};
|
|
122
|
+
}
|