@compilr-dev/factory 0.1.7 → 0.1.9

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 (54) hide show
  1. package/dist/factory/registry.js +4 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +4 -0
  4. package/dist/toolkits/next-prisma/api-routes.d.ts +10 -0
  5. package/dist/toolkits/next-prisma/api-routes.js +155 -0
  6. package/dist/toolkits/next-prisma/config.d.ts +9 -0
  7. package/dist/toolkits/next-prisma/config.js +139 -0
  8. package/dist/toolkits/next-prisma/dashboard.d.ts +9 -0
  9. package/dist/toolkits/next-prisma/dashboard.js +87 -0
  10. package/dist/toolkits/next-prisma/entity-components.d.ts +10 -0
  11. package/dist/toolkits/next-prisma/entity-components.js +217 -0
  12. package/dist/toolkits/next-prisma/entity-pages.d.ts +12 -0
  13. package/dist/toolkits/next-prisma/entity-pages.js +348 -0
  14. package/dist/toolkits/next-prisma/helpers.d.ts +13 -0
  15. package/dist/toolkits/next-prisma/helpers.js +37 -0
  16. package/dist/toolkits/next-prisma/index.d.ts +9 -0
  17. package/dist/toolkits/next-prisma/index.js +57 -0
  18. package/dist/toolkits/next-prisma/layout.d.ts +9 -0
  19. package/dist/toolkits/next-prisma/layout.js +157 -0
  20. package/dist/toolkits/next-prisma/prisma.d.ts +8 -0
  21. package/dist/toolkits/next-prisma/prisma.js +76 -0
  22. package/dist/toolkits/next-prisma/seed.d.ts +9 -0
  23. package/dist/toolkits/next-prisma/seed.js +100 -0
  24. package/dist/toolkits/next-prisma/static.d.ts +8 -0
  25. package/dist/toolkits/next-prisma/static.js +61 -0
  26. package/dist/toolkits/next-prisma/types-gen.d.ts +10 -0
  27. package/dist/toolkits/next-prisma/types-gen.js +62 -0
  28. package/dist/toolkits/react-node/config.d.ts +1 -4
  29. package/dist/toolkits/react-node/config.js +3 -84
  30. package/dist/toolkits/react-node/helpers.d.ts +2 -23
  31. package/dist/toolkits/react-node/helpers.js +2 -67
  32. package/dist/toolkits/react-node/seed.d.ts +4 -3
  33. package/dist/toolkits/react-node/seed.js +4 -111
  34. package/dist/toolkits/react-node/shared.d.ts +2 -3
  35. package/dist/toolkits/react-node/shared.js +2 -115
  36. package/dist/toolkits/shared/color-utils.d.ts +10 -0
  37. package/dist/toolkits/shared/color-utils.js +85 -0
  38. package/dist/toolkits/shared/components.d.ts +12 -0
  39. package/dist/toolkits/shared/components.js +121 -0
  40. package/dist/toolkits/shared/helpers.d.ts +28 -0
  41. package/dist/toolkits/shared/helpers.js +72 -0
  42. package/dist/toolkits/shared/index.d.ts +9 -0
  43. package/dist/toolkits/shared/index.js +9 -0
  44. package/dist/toolkits/shared/seed-data.d.ts +18 -0
  45. package/dist/toolkits/shared/seed-data.js +119 -0
  46. package/dist/toolkits/static-landing/config.d.ts +8 -0
  47. package/dist/toolkits/static-landing/config.js +63 -0
  48. package/dist/toolkits/static-landing/index.d.ts +8 -0
  49. package/dist/toolkits/static-landing/index.js +35 -0
  50. package/dist/toolkits/static-landing/pages.d.ts +8 -0
  51. package/dist/toolkits/static-landing/pages.js +191 -0
  52. package/dist/toolkits/static-landing/static.d.ts +8 -0
  53. package/dist/toolkits/static-landing/static.js +65 -0
  54. package/package.json +1 -1
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — Prisma Schema Generator
3
+ *
4
+ * Generates: prisma/schema.prisma, lib/prisma.ts
5
+ */
6
+ import { toCamelCase } from '../../model/naming.js';
7
+ import { prismaFieldType, prismaModelName, fkFieldName, belongsToRels, hasManyRels, } from './helpers.js';
8
+ export function generatePrismaFiles(model) {
9
+ return [generateSchema(model), generatePrismaClient()];
10
+ }
11
+ function generateSchema(model) {
12
+ const lines = [];
13
+ lines.push(`generator client {`);
14
+ lines.push(` provider = "prisma-client-js"`);
15
+ lines.push(`}`);
16
+ lines.push('');
17
+ lines.push(`datasource db {`);
18
+ lines.push(` provider = "sqlite"`);
19
+ lines.push(` url = env("DATABASE_URL")`);
20
+ lines.push(`}`);
21
+ for (const entity of model.entities) {
22
+ lines.push('');
23
+ lines.push(generatePrismaModel(model, entity));
24
+ }
25
+ lines.push('');
26
+ return { path: 'prisma/schema.prisma', content: lines.join('\n') };
27
+ }
28
+ function generatePrismaModel(model, entity) {
29
+ const modelName = prismaModelName(entity);
30
+ const bto = belongsToRels(entity);
31
+ const hm = hasManyRels(entity);
32
+ const lines = [];
33
+ lines.push(`model ${modelName} {`);
34
+ lines.push(` id Int @id @default(autoincrement())`);
35
+ // Regular fields
36
+ for (const field of entity.fields) {
37
+ const pType = prismaFieldType(field);
38
+ const optional = field.required ? '' : '?';
39
+ lines.push(` ${field.name.padEnd(9)} ${pType}${optional}`);
40
+ }
41
+ // BelongsTo relationships — FK field + relation
42
+ for (const rel of bto) {
43
+ const fk = fkFieldName(rel);
44
+ const targetModel = prismaModelName({ name: rel.target });
45
+ const relField = toCamelCase(rel.target);
46
+ lines.push(` ${fk.padEnd(9)} Int`);
47
+ lines.push(` ${relField.padEnd(9)} ${targetModel} @relation(fields: [${fk}], references: [id])`);
48
+ }
49
+ // HasMany relationships — reverse relation array
50
+ for (const rel of hm) {
51
+ const targetEntity = model.entities.find((e) => e.name === rel.target);
52
+ if (!targetEntity)
53
+ continue;
54
+ const targetModel = prismaModelName(targetEntity);
55
+ const relField = toCamelCase(targetEntity.pluralName);
56
+ lines.push(` ${relField.padEnd(9)} ${targetModel}[]`);
57
+ }
58
+ // Timestamps
59
+ lines.push(` createdAt DateTime @default(now())`);
60
+ lines.push(` updatedAt DateTime @updatedAt`);
61
+ lines.push(`}`);
62
+ return lines.join('\n');
63
+ }
64
+ function generatePrismaClient() {
65
+ return {
66
+ path: 'lib/prisma.ts',
67
+ content: `import { PrismaClient } from '@prisma/client';
68
+
69
+ const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
70
+
71
+ export const prisma = globalForPrisma.prisma || new PrismaClient();
72
+
73
+ if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
74
+ `,
75
+ };
76
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — Seed Data Generator
3
+ *
4
+ * Generates prisma/seed.ts using Prisma's createMany for bulk inserts.
5
+ * Entities are ordered by dependency (parents before children).
6
+ */
7
+ import type { ApplicationModel } from '../../model/types.js';
8
+ import type { FactoryFile } from '../types.js';
9
+ export declare function generateSeedFile(model: ApplicationModel): FactoryFile[];
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — Seed Data Generator
3
+ *
4
+ * Generates prisma/seed.ts using Prisma's createMany for bulk inserts.
5
+ * Entities are ordered by dependency (parents before children).
6
+ */
7
+ import { toCamelCase } from '../../model/naming.js';
8
+ import { fkFieldName, belongsToRels } from './helpers.js';
9
+ import { generateFieldValue, SEED_COUNT } from '../shared/seed-data.js';
10
+ export function generateSeedFile(model) {
11
+ const ordered = topologicalSort(model.entities);
12
+ const seedBlocks = ordered.map((entity) => generateEntitySeed(model, entity)).join('\n\n');
13
+ return [
14
+ {
15
+ path: 'prisma/seed.ts',
16
+ content: `import { PrismaClient } from '@prisma/client';
17
+
18
+ const prisma = new PrismaClient();
19
+
20
+ async function main() {
21
+ ${seedBlocks}
22
+
23
+ console.log('Seed data created successfully.');
24
+ }
25
+
26
+ main()
27
+ .then(() => prisma.$disconnect())
28
+ .catch((e) => {
29
+ console.error(e);
30
+ prisma.$disconnect();
31
+ process.exit(1);
32
+ });
33
+ `,
34
+ },
35
+ ];
36
+ }
37
+ function generateEntitySeed(model, entity) {
38
+ const camel = toCamelCase(entity.name);
39
+ const rels = belongsToRels(entity);
40
+ const items = [];
41
+ for (let i = 0; i < SEED_COUNT; i++) {
42
+ const fields = [];
43
+ for (const field of entity.fields) {
44
+ const value = generateFieldValue(field, i, entity.name);
45
+ // For Prisma, booleans and numbers don't need quotes; strings already have them
46
+ if (field.type === 'date') {
47
+ // Prisma expects Date objects for DateTime fields
48
+ fields.push(` ${field.name}: new Date(${value}),`);
49
+ }
50
+ else {
51
+ fields.push(` ${field.name}: ${value},`);
52
+ }
53
+ }
54
+ // FK fields from belongsTo relationships
55
+ for (const rel of rels) {
56
+ const fk = fkFieldName(rel);
57
+ const targetCount = SEED_COUNT;
58
+ fields.push(` ${fk}: ${String((i % targetCount) + 1)},`);
59
+ }
60
+ items.push(` {\n${fields.join('\n')}\n },`);
61
+ }
62
+ return ` await prisma.${camel}.createMany({
63
+ data: [
64
+ ${items.join('\n')}
65
+ ],
66
+ });`;
67
+ }
68
+ /** Sort entities so that parents come before children (entities with belongsTo go after their targets). */
69
+ function topologicalSort(entities) {
70
+ const entityMap = new Map(entities.map((e) => [e.name, e]));
71
+ const sorted = [];
72
+ const visited = new Set();
73
+ const visiting = new Set();
74
+ function visit(entity) {
75
+ if (visited.has(entity.name))
76
+ return;
77
+ if (visiting.has(entity.name)) {
78
+ // Circular dependency — just add it
79
+ sorted.push(entity);
80
+ visited.add(entity.name);
81
+ return;
82
+ }
83
+ visiting.add(entity.name);
84
+ // Visit dependencies first
85
+ for (const rel of entity.relationships) {
86
+ if (rel.type === 'belongsTo') {
87
+ const target = entityMap.get(rel.target);
88
+ if (target)
89
+ visit(target);
90
+ }
91
+ }
92
+ visiting.delete(entity.name);
93
+ visited.add(entity.name);
94
+ sorted.push(entity);
95
+ }
96
+ for (const entity of entities) {
97
+ visit(entity);
98
+ }
99
+ return sorted;
100
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — Static Files Generator
3
+ *
4
+ * Generates: .gitignore, README.md
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,61 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — Static Files Generator
3
+ *
4
+ * Generates: .gitignore, README.md
5
+ */
6
+ export function generateStaticFiles(model) {
7
+ return [generateGitignore(), generateReadme(model)];
8
+ }
9
+ function generateGitignore() {
10
+ return {
11
+ path: '.gitignore',
12
+ content: `node_modules
13
+ .next
14
+ .env
15
+ prisma/dev.db
16
+ prisma/dev.db-journal
17
+ *.local
18
+ `,
19
+ };
20
+ }
21
+ function generateReadme(model) {
22
+ let entitiesSection = '';
23
+ if (model.entities.length > 0) {
24
+ const entityLines = model.entities
25
+ .map((e) => {
26
+ const relCount = e.relationships.length;
27
+ const parts = [`${String(e.fields.length)} fields`];
28
+ if (relCount > 0) {
29
+ parts.push(`${String(relCount)} relationship${relCount > 1 ? 's' : ''}`);
30
+ }
31
+ return `- **${e.name}** (${e.icon}) — ${parts.join(', ')}`;
32
+ })
33
+ .join('\n');
34
+ entitiesSection = `\n## Entities\n\n${entityLines}\n`;
35
+ }
36
+ return {
37
+ path: 'README.md',
38
+ content: `# ${model.identity.name}
39
+
40
+ ${model.identity.description}
41
+ ${entitiesSection}
42
+ ## Getting Started
43
+
44
+ \`\`\`bash
45
+ npm install
46
+ npx prisma db push
47
+ npx prisma db seed
48
+ npm run dev
49
+ \`\`\`
50
+
51
+ - **App:** http://localhost:3000
52
+
53
+ ## Tech Stack
54
+
55
+ - Next.js 14 (App Router)
56
+ - TypeScript
57
+ - Prisma ORM (SQLite)
58
+ - Tailwind CSS
59
+ `,
60
+ };
61
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — TypeScript Types Generator
3
+ *
4
+ * Generates src/types/index.ts with interfaces for each entity.
5
+ * These serve as the frontend contract (Client Components use these types;
6
+ * Prisma generates its own types server-side).
7
+ */
8
+ import type { ApplicationModel } from '../../model/types.js';
9
+ import type { FactoryFile } from '../types.js';
10
+ export declare function generateTypesFile(model: ApplicationModel): FactoryFile[];
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Next.js + Prisma Toolkit — TypeScript Types Generator
3
+ *
4
+ * Generates src/types/index.ts with interfaces for each entity.
5
+ * These serve as the frontend contract (Client Components use these types;
6
+ * Prisma generates its own types server-side).
7
+ */
8
+ import { tsType, fkFieldName, belongsToRels } from './helpers.js';
9
+ const SHARED_TYPES = `// --- Shared API Types ---
10
+
11
+ export interface PaginatedResponse<T> {
12
+ data: T[];
13
+ total: number;
14
+ page: number;
15
+ pageSize: number;
16
+ totalPages: number;
17
+ }
18
+
19
+ export interface ApiResponse<T> {
20
+ data: T;
21
+ error?: string;
22
+ }
23
+
24
+ export interface ApiListResponse<T> {
25
+ data: T[];
26
+ total: number;
27
+ }
28
+
29
+ export interface SortParams {
30
+ field: string;
31
+ direction: 'asc' | 'desc';
32
+ }`;
33
+ export function generateTypesFile(model) {
34
+ const lines = ['// Auto-generated TypeScript types from Application Model', ''];
35
+ lines.push(SHARED_TYPES);
36
+ lines.push('');
37
+ for (const entity of model.entities) {
38
+ lines.push(generateInterface(entity));
39
+ lines.push('');
40
+ }
41
+ return [{ path: 'src/types/index.ts', content: lines.join('\n') }];
42
+ }
43
+ function generateInterface(entity) {
44
+ const lines = [];
45
+ lines.push(`export interface ${entity.name} {`);
46
+ lines.push(' id: number;');
47
+ for (const field of entity.fields) {
48
+ const optional = field.required ? '' : '?';
49
+ lines.push(` ${field.name}${optional}: ${tsType(field)};`);
50
+ }
51
+ // FK fields from belongsTo
52
+ for (const rel of belongsToRels(entity)) {
53
+ const fk = fkFieldName(rel);
54
+ lines.push(` ${fk}: number;`);
55
+ lines.push(` ${rel.target.charAt(0).toLowerCase() + rel.target.slice(1)}?: ${rel.target};`);
56
+ }
57
+ // Implicit timestamps
58
+ lines.push(' createdAt: string;');
59
+ lines.push(' updatedAt: string;');
60
+ lines.push('}');
61
+ return lines.join('\n');
62
+ }
@@ -7,7 +7,4 @@
7
7
  import type { ApplicationModel } from '../../model/types.js';
8
8
  import type { FactoryFile } from '../types.js';
9
9
  export declare function generateConfigFiles(model: ApplicationModel): FactoryFile[];
10
- declare function hexToHsl(hex: string): [number, number, number];
11
- declare function hslToHex(h: number, s: number, l: number): string;
12
- declare function generateColorShades(hex: string): string;
13
- export { hexToHsl, hslToHex, generateColorShades };
10
+ export { hexToHsl, hslToHex, generateColorShades } from '../shared/color-utils.js';
@@ -5,6 +5,7 @@
5
5
  * tsconfig.json, postcss.config.js
6
6
  */
7
7
  import { toKebabCase } from '../../model/naming.js';
8
+ import { generateColorShades } from '../shared/color-utils.js';
8
9
  export function generateConfigFiles(model) {
9
10
  const appSlug = toKebabCase(model.identity.name);
10
11
  return [
@@ -109,90 +110,8 @@ function generateTsConfig() {
109
110
  };
110
111
  return { path: 'tsconfig.json', content: JSON.stringify(config, null, 2) + '\n' };
111
112
  }
112
- // =============================================================================
113
- // Color Shade Utilities
114
- // =============================================================================
115
- const SHADE_LIGHTNESS = {
116
- '50': 97,
117
- '100': 94,
118
- '200': 86,
119
- '300': 77,
120
- '400': 66,
121
- '500': 55,
122
- '600': 44,
123
- '700': 36,
124
- '800': 27,
125
- '900': 20,
126
- '950': 14,
127
- };
128
- function hexToHsl(hex) {
129
- const raw = hex.replace('#', '');
130
- const r = parseInt(raw.substring(0, 2), 16) / 255;
131
- const g = parseInt(raw.substring(2, 4), 16) / 255;
132
- const b = parseInt(raw.substring(4, 6), 16) / 255;
133
- const max = Math.max(r, g, b);
134
- const min = Math.min(r, g, b);
135
- const l = (max + min) / 2;
136
- if (max === min)
137
- return [0, 0, Math.round(l * 100)];
138
- const d = max - min;
139
- const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
140
- let h = 0;
141
- if (max === r)
142
- h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
143
- else if (max === g)
144
- h = ((b - r) / d + 2) / 6;
145
- else
146
- h = ((r - g) / d + 4) / 6;
147
- return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];
148
- }
149
- function hslToHex(h, s, l) {
150
- const sN = s / 100;
151
- const lN = l / 100;
152
- const c = (1 - Math.abs(2 * lN - 1)) * sN;
153
- const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
154
- const m = lN - c / 2;
155
- let r = 0, g = 0, b = 0;
156
- if (h < 60)
157
- [r, g, b] = [c, x, 0];
158
- else if (h < 120)
159
- [r, g, b] = [x, c, 0];
160
- else if (h < 180)
161
- [r, g, b] = [0, c, x];
162
- else if (h < 240)
163
- [r, g, b] = [0, x, c];
164
- else if (h < 300)
165
- [r, g, b] = [x, 0, c];
166
- else
167
- [r, g, b] = [c, 0, x];
168
- const toHex = (v) => Math.round((v + m) * 255)
169
- .toString(16)
170
- .padStart(2, '0');
171
- return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
172
- }
173
- function generateColorShades(hex) {
174
- const [h, s] = hexToHsl(hex);
175
- const entries = [];
176
- for (const [shade, lightness] of Object.entries(SHADE_LIGHTNESS)) {
177
- entries.push(` ${shade}: '${hslToHex(h, s, lightness)}',`);
178
- }
179
- // Find the shade closest to the original for DEFAULT
180
- const [, , originalL] = hexToHsl(hex);
181
- let closestShade = '500';
182
- let closestDiff = Infinity;
183
- for (const [shade, lightness] of Object.entries(SHADE_LIGHTNESS)) {
184
- const diff = Math.abs(lightness - originalL);
185
- if (diff < closestDiff) {
186
- closestDiff = diff;
187
- closestShade = shade;
188
- }
189
- }
190
- const defaultHex = hslToHex(h, s, SHADE_LIGHTNESS[closestShade]);
191
- entries.push(` DEFAULT: '${defaultHex}',`);
192
- return `{\n${entries.join('\n')}\n }`;
193
- }
194
- // Export for testing
195
- export { hexToHsl, hslToHex, generateColorShades };
113
+ // Re-export for testing (from shared)
114
+ export { hexToHsl, hslToHex, generateColorShades } from '../shared/color-utils.js';
196
115
  function generatePostCssConfig() {
197
116
  return {
198
117
  path: 'postcss.config.js',
@@ -1,27 +1,6 @@
1
1
  /**
2
2
  * React+Node Toolkit — Shared Helpers
3
3
  *
4
- * Utility functions used across generators.
4
+ * Re-exports from the shared helpers module.
5
5
  */
6
- import type { Entity, Field, Relationship } from '../../model/types.js';
7
- /** Indent every line of a multi-line string. */
8
- export declare function indent(text: string, spaces: number): string;
9
- /** Map a model FieldType to a TypeScript type string. */
10
- export declare function tsType(field: Field): string;
11
- /** Get the FK field name for a belongsTo relationship. */
12
- export declare function fkFieldName(rel: Relationship): string;
13
- /** Get belongsTo relationships for an entity. */
14
- export declare function belongsToRels(entity: Entity): readonly Relationship[];
15
- /** Get hasMany relationships for an entity. */
16
- export declare function hasManyRels(entity: Entity): readonly Relationship[];
17
- /** Generate a route path from entity plural name. */
18
- export declare function routePath(entity: Entity): string;
19
- /** Generate an API path from entity plural name. */
20
- export declare function apiPath(entity: Entity): string;
21
- /** Map a model FieldType to an HTML input type. */
22
- export declare function inputType(field: Field): string;
23
- /** Generate import statement lines. */
24
- export declare function generateImports(imports: Array<{
25
- from: string;
26
- names: string[];
27
- }>): string;
6
+ export { indent, tsType, fkFieldName, belongsToRels, hasManyRels, routePath, apiPath, inputType, generateImports, } from '../shared/helpers.js';
@@ -1,71 +1,6 @@
1
1
  /**
2
2
  * React+Node Toolkit — Shared Helpers
3
3
  *
4
- * Utility functions used across generators.
4
+ * Re-exports from the shared helpers module.
5
5
  */
6
- import { toCamelCase, toKebabCase } from '../../model/naming.js';
7
- /** Indent every line of a multi-line string. */
8
- export function indent(text, spaces) {
9
- const pad = ' '.repeat(spaces);
10
- return text
11
- .split('\n')
12
- .map((line) => (line.trim() === '' ? '' : pad + line))
13
- .join('\n');
14
- }
15
- /** Map a model FieldType to a TypeScript type string. */
16
- export function tsType(field) {
17
- switch (field.type) {
18
- case 'string':
19
- case 'enum':
20
- return 'string';
21
- case 'number':
22
- return 'number';
23
- case 'boolean':
24
- return 'boolean';
25
- case 'date':
26
- return 'string'; // ISO date string
27
- default:
28
- return 'string';
29
- }
30
- }
31
- /** Get the FK field name for a belongsTo relationship. */
32
- export function fkFieldName(rel) {
33
- return rel.fieldName ?? toCamelCase(rel.target) + 'Id';
34
- }
35
- /** Get belongsTo relationships for an entity. */
36
- export function belongsToRels(entity) {
37
- return entity.relationships.filter((r) => r.type === 'belongsTo');
38
- }
39
- /** Get hasMany relationships for an entity. */
40
- export function hasManyRels(entity) {
41
- return entity.relationships.filter((r) => r.type === 'hasMany');
42
- }
43
- /** Generate a route path from entity plural name. */
44
- export function routePath(entity) {
45
- return '/' + toKebabCase(entity.pluralName).toLowerCase();
46
- }
47
- /** Generate an API path from entity plural name. */
48
- export function apiPath(entity) {
49
- return '/api/' + toKebabCase(entity.pluralName).toLowerCase();
50
- }
51
- /** Map a model FieldType to an HTML input type. */
52
- export function inputType(field) {
53
- switch (field.type) {
54
- case 'string':
55
- return 'text';
56
- case 'number':
57
- return 'number';
58
- case 'boolean':
59
- return 'checkbox';
60
- case 'date':
61
- return 'date';
62
- case 'enum':
63
- return 'select';
64
- default:
65
- return 'text';
66
- }
67
- }
68
- /** Generate import statement lines. */
69
- export function generateImports(imports) {
70
- return imports.map((i) => `import { ${i.names.join(', ')} } from '${i.from}';`).join('\n');
71
- }
6
+ export { indent, tsType, fkFieldName, belongsToRels, hasManyRels, routePath, apiPath, inputType, generateImports, } from '../shared/helpers.js';
@@ -2,10 +2,11 @@
2
2
  * React+Node Toolkit — Seed Data Generator
3
3
  *
4
4
  * Generates realistic mock data based on field semantics.
5
- * Deterministic: same input same output (uses index-based logic, not Math.random).
5
+ * Uses shared generateFieldValue for deterministic values,
6
+ * wraps them in JavaScript array format for in-memory data stores.
6
7
  */
7
8
  import type { ApplicationModel, Entity } from '../../model/types.js';
8
- declare const SEED_COUNT = 8;
9
- /** Generate seed data items for a single entity. */
9
+ import { SEED_COUNT } from '../shared/seed-data.js';
10
+ /** Generate seed data items for a single entity (JS array format). */
10
11
  export declare function generateSeedData(model: ApplicationModel, entity: Entity): string;
11
12
  export { SEED_COUNT };