archetype-engine 2.0.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/src/ai/adapters/anthropic.d.ts +31 -0
  4. package/dist/src/ai/adapters/anthropic.d.ts.map +1 -0
  5. package/dist/src/ai/adapters/anthropic.js +75 -0
  6. package/dist/src/ai/adapters/openai.d.ts +33 -0
  7. package/dist/src/ai/adapters/openai.d.ts.map +1 -0
  8. package/dist/src/ai/adapters/openai.js +120 -0
  9. package/dist/src/ai/adapters/vercel.d.ts +434 -0
  10. package/dist/src/ai/adapters/vercel.d.ts.map +1 -0
  11. package/dist/src/ai/adapters/vercel.js +162 -0
  12. package/dist/src/ai/index.d.ts +492 -0
  13. package/dist/src/ai/index.d.ts.map +1 -0
  14. package/dist/src/ai/index.js +71 -0
  15. package/dist/src/ai/state.d.ts +13 -0
  16. package/dist/src/ai/state.d.ts.map +1 -0
  17. package/dist/src/ai/state.js +215 -0
  18. package/dist/src/ai/tools.d.ts +13 -0
  19. package/dist/src/ai/tools.d.ts.map +1 -0
  20. package/dist/src/ai/tools.js +257 -0
  21. package/dist/src/ai/types.d.ts +196 -0
  22. package/dist/src/ai/types.d.ts.map +1 -0
  23. package/dist/src/ai/types.js +9 -0
  24. package/dist/src/cli.d.ts +3 -0
  25. package/dist/src/cli.d.ts.map +1 -0
  26. package/dist/src/cli.js +540 -0
  27. package/dist/src/core/utils.d.ts +27 -0
  28. package/dist/src/core/utils.d.ts.map +1 -0
  29. package/dist/src/core/utils.js +56 -0
  30. package/dist/src/entity.d.ts +165 -0
  31. package/dist/src/entity.d.ts.map +1 -0
  32. package/dist/src/entity.js +108 -0
  33. package/dist/src/fields.d.ts +207 -0
  34. package/dist/src/fields.d.ts.map +1 -0
  35. package/dist/src/fields.js +291 -0
  36. package/dist/src/generators/erd-ir.d.ts +10 -0
  37. package/dist/src/generators/erd-ir.d.ts.map +1 -0
  38. package/dist/src/generators/erd-ir.js +119 -0
  39. package/dist/src/index.d.ts +51 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +101 -0
  42. package/dist/src/init/dependencies.d.ts +31 -0
  43. package/dist/src/init/dependencies.d.ts.map +1 -0
  44. package/dist/src/init/dependencies.js +101 -0
  45. package/dist/src/init/entity-templates.d.ts +42 -0
  46. package/dist/src/init/entity-templates.d.ts.map +1 -0
  47. package/dist/src/init/entity-templates.js +367 -0
  48. package/dist/src/init/index.d.ts +10 -0
  49. package/dist/src/init/index.d.ts.map +1 -0
  50. package/dist/src/init/index.js +250 -0
  51. package/dist/src/init/prompts.d.ts +11 -0
  52. package/dist/src/init/prompts.d.ts.map +1 -0
  53. package/dist/src/init/prompts.js +275 -0
  54. package/dist/src/init/templates.d.ts +24 -0
  55. package/dist/src/init/templates.d.ts.map +1 -0
  56. package/dist/src/init/templates.js +587 -0
  57. package/dist/src/json/index.d.ts +11 -0
  58. package/dist/src/json/index.d.ts.map +1 -0
  59. package/dist/src/json/index.js +26 -0
  60. package/dist/src/json/parser.d.ts +61 -0
  61. package/dist/src/json/parser.d.ts.map +1 -0
  62. package/dist/src/json/parser.js +309 -0
  63. package/dist/src/json/types.d.ts +275 -0
  64. package/dist/src/json/types.d.ts.map +1 -0
  65. package/dist/src/json/types.js +10 -0
  66. package/dist/src/manifest.d.ts +147 -0
  67. package/dist/src/manifest.d.ts.map +1 -0
  68. package/dist/src/manifest.js +104 -0
  69. package/dist/src/relations.d.ts +96 -0
  70. package/dist/src/relations.d.ts.map +1 -0
  71. package/dist/src/relations.js +108 -0
  72. package/dist/src/source.d.ts +93 -0
  73. package/dist/src/source.d.ts.map +1 -0
  74. package/dist/src/source.js +89 -0
  75. package/dist/src/template/context.d.ts +34 -0
  76. package/dist/src/template/context.d.ts.map +1 -0
  77. package/dist/src/template/context.js +31 -0
  78. package/dist/src/template/index.d.ts +6 -0
  79. package/dist/src/template/index.d.ts.map +1 -0
  80. package/dist/src/template/index.js +12 -0
  81. package/dist/src/template/registry.d.ts +18 -0
  82. package/dist/src/template/registry.d.ts.map +1 -0
  83. package/dist/src/template/registry.js +89 -0
  84. package/dist/src/template/runner.d.ts +9 -0
  85. package/dist/src/template/runner.d.ts.map +1 -0
  86. package/dist/src/template/runner.js +125 -0
  87. package/dist/src/template/types.d.ts +73 -0
  88. package/dist/src/template/types.d.ts.map +1 -0
  89. package/dist/src/template/types.js +3 -0
  90. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts +22 -0
  91. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.d.ts.map +1 -0
  92. package/dist/src/templates/nextjs-drizzle-trpc/generators/api.js +866 -0
  93. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts +20 -0
  94. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.d.ts.map +1 -0
  95. package/dist/src/templates/nextjs-drizzle-trpc/generators/auth.js +273 -0
  96. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts +22 -0
  97. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.d.ts.map +1 -0
  98. package/dist/src/templates/nextjs-drizzle-trpc/generators/crud-hooks.js +237 -0
  99. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts +30 -0
  100. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.d.ts.map +1 -0
  101. package/dist/src/templates/nextjs-drizzle-trpc/generators/hooks.js +345 -0
  102. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts +25 -0
  103. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.d.ts.map +1 -0
  104. package/dist/src/templates/nextjs-drizzle-trpc/generators/i18n.js +199 -0
  105. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts +8 -0
  106. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.d.ts.map +1 -0
  107. package/dist/src/templates/nextjs-drizzle-trpc/generators/index.js +18 -0
  108. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts +22 -0
  109. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.d.ts.map +1 -0
  110. package/dist/src/templates/nextjs-drizzle-trpc/generators/schema.js +270 -0
  111. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts +23 -0
  112. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.d.ts.map +1 -0
  113. package/dist/src/templates/nextjs-drizzle-trpc/generators/service.js +304 -0
  114. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts +21 -0
  115. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.d.ts.map +1 -0
  116. package/dist/src/templates/nextjs-drizzle-trpc/generators/validation.js +248 -0
  117. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts +30 -0
  118. package/dist/src/templates/nextjs-drizzle-trpc/index.d.ts.map +1 -0
  119. package/dist/src/templates/nextjs-drizzle-trpc/index.js +71 -0
  120. package/dist/src/validation/index.d.ts +71 -0
  121. package/dist/src/validation/index.d.ts.map +1 -0
  122. package/dist/src/validation/index.js +314 -0
  123. package/package.json +86 -0
@@ -0,0 +1,345 @@
1
+ "use strict";
2
+ /**
3
+ * React Hooks Generator
4
+ *
5
+ * Generates React hooks for data fetching and form handling using tRPC and React Hook Form.
6
+ * Provides a complete set of hooks for each entity's CRUD operations.
7
+ *
8
+ * Generated files:
9
+ * - hooks/use{Entity}.ts - Hooks for list, get, create, edit, and remove operations
10
+ *
11
+ * Generated hooks per entity:
12
+ * - use{Entity}s() - List all entities (useQuery)
13
+ * - use{Entity}(id) - Get single entity by ID (useQuery)
14
+ * - use{Entity}Form() - Create form with validation and mutation
15
+ * - use{Entity}EditForm(id) - Edit form with data loading and mutation
16
+ * - use{Entity}Remove() - Delete mutation with cache invalidation
17
+ * - useCreate{Entity}() - Create mutation without form
18
+ * - useUpdate{Entity}() - Update mutation without form
19
+ *
20
+ * Features:
21
+ * - Zod validation integration via zodResolver
22
+ * - Automatic tRPC cache invalidation on mutations
23
+ * - i18n support for validation messages when multiple languages configured
24
+ * - Form reset on successful create
25
+ * - Null-to-undefined conversion for form compatibility
26
+ *
27
+ * @module generators/hooks
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.hooksGenerator = void 0;
31
+ /**
32
+ * Generate filter type definitions for an entity
33
+ */
34
+ function generateFilterTypes(entity) {
35
+ const filterFields = Object.entries(entity.fields).map(([fieldName, field]) => {
36
+ switch (field.type) {
37
+ case 'text':
38
+ return ` ${fieldName}?: string | {
39
+ eq?: string
40
+ ne?: string
41
+ contains?: string
42
+ startsWith?: string
43
+ endsWith?: string
44
+ }`;
45
+ case 'number':
46
+ return ` ${fieldName}?: number | {
47
+ eq?: number
48
+ ne?: number
49
+ gt?: number
50
+ gte?: number
51
+ lt?: number
52
+ lte?: number
53
+ }`;
54
+ case 'boolean':
55
+ return ` ${fieldName}?: boolean`;
56
+ case 'date':
57
+ return ` ${fieldName}?: string | {
58
+ eq?: string
59
+ ne?: string
60
+ gt?: string
61
+ gte?: string
62
+ lt?: string
63
+ lte?: string
64
+ }`;
65
+ default:
66
+ return ` ${fieldName}?: string`;
67
+ }
68
+ }).join('\n');
69
+ // Get field names for orderBy
70
+ const fieldNames = Object.keys(entity.fields);
71
+ const orderByFields = [...fieldNames, 'createdAt', 'updatedAt'];
72
+ return `// Filter operators for ${entity.name}
73
+ export interface ${entity.name}Filter {
74
+ ${filterFields}
75
+ }
76
+
77
+ // OrderBy options for ${entity.name}
78
+ export interface ${entity.name}OrderBy {
79
+ field: ${orderByFields.map(f => `'${f}'`).join(' | ')}
80
+ direction?: 'asc' | 'desc'
81
+ }`;
82
+ }
83
+ /**
84
+ * JavaScript reserved words that can't be used as variable names
85
+ */
86
+ const JS_RESERVED_WORDS = new Set([
87
+ 'break', 'case', 'catch', 'continue', 'debugger', 'default', 'delete',
88
+ 'do', 'else', 'finally', 'for', 'function', 'if', 'in', 'instanceof',
89
+ 'new', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'var',
90
+ 'void', 'while', 'with', 'class', 'const', 'enum', 'export', 'extends',
91
+ 'import', 'super', 'implements', 'interface', 'let', 'package', 'private',
92
+ 'protected', 'public', 'static', 'yield', 'await', 'null', 'undefined', 'true', 'false'
93
+ ]);
94
+ /**
95
+ * Get a safe variable name, prefixing with underscore if it's a reserved word
96
+ */
97
+ function getSafeVarName(name) {
98
+ return JS_RESERVED_WORDS.has(name.toLowerCase()) ? `_${name.toLowerCase()}` : name.toLowerCase();
99
+ }
100
+ /**
101
+ * Generate complete hooks file for an entity
102
+ *
103
+ * @param entity - Entity IR with name and field definitions
104
+ * @param manifest - Manifest IR with i18n configuration
105
+ * @returns Complete hooks file content as string
106
+ */
107
+ function generateEntityHooks(entity, manifest) {
108
+ const name = entity.name;
109
+ const lowerName = name.toLowerCase();
110
+ const safeVarName = getSafeVarName(name);
111
+ const useI18n = manifest.i18n.languages.length > 1;
112
+ // Schema imports
113
+ const schemaImport = useI18n
114
+ ? `import { ${lowerName}CreateSchemaI18n, ${lowerName}UpdateSchemaI18n, ${name}Create, ${name}Update } from '@/generated/schemas/${lowerName}'`
115
+ : `import { ${lowerName}CreateSchema, ${lowerName}UpdateSchema, ${name}Create, ${name}Update } from '@/generated/schemas/${lowerName}'`;
116
+ const i18nImport = useI18n
117
+ ? `import { useTranslations } from 'next-intl'`
118
+ : '';
119
+ const tDeclaration = useI18n
120
+ ? ` const t = useTranslations('validation')`
121
+ : '';
122
+ const resolverSchema = useI18n
123
+ ? `${lowerName}CreateSchemaI18n(t)`
124
+ : `${lowerName}CreateSchema`;
125
+ const updateResolverSchema = useI18n
126
+ ? `${lowerName}UpdateSchemaI18n(t)`
127
+ : `${lowerName}UpdateSchema`;
128
+ // Generate filter types
129
+ const filterTypes = generateFilterTypes(entity);
130
+ return `// Auto-generated hooks for ${name}
131
+ // Do not edit manually - regenerate with: npx archetype generate
132
+
133
+ 'use client'
134
+
135
+ import { useMemo } from 'react'
136
+ import { useForm } from 'react-hook-form'
137
+ import { zodResolver } from '@hookform/resolvers/zod'
138
+ import { trpc } from '@/lib/trpc'
139
+ ${i18nImport}
140
+ ${schemaImport}
141
+
142
+ // Convert null values to undefined for form compatibility
143
+ type NullToUndefined<T> = {
144
+ [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>
145
+ }
146
+
147
+ function nullToUndefined<T extends Record<string, unknown>>(
148
+ obj: T | null | undefined
149
+ ): NullToUndefined<T> | undefined {
150
+ if (!obj) return undefined
151
+ return Object.fromEntries(
152
+ Object.entries(obj).map(([k, v]) => [k, v === null ? undefined : v])
153
+ ) as NullToUndefined<T>
154
+ }
155
+
156
+ ${filterTypes}
157
+
158
+ // ============ LIST WITH PAGINATION, FILTERING, SORTING, AND SEARCH ============
159
+ export interface Use${name}sOptions {
160
+ // Pagination
161
+ page?: number
162
+ limit?: number
163
+ // Filtering
164
+ where?: ${name}Filter
165
+ // Sorting
166
+ orderBy?: ${name}OrderBy
167
+ // Search across text fields
168
+ search?: string
169
+ }
170
+
171
+ // React Query options for controlling query behavior
172
+ export interface QueryOptions {
173
+ enabled?: boolean
174
+ }
175
+
176
+ export function use${name}s(options?: Use${name}sOptions, queryOptions?: QueryOptions) {
177
+ return trpc.${lowerName}.list.useQuery({
178
+ page: options?.page ?? 1,
179
+ limit: options?.limit ?? 20,
180
+ where: options?.where,
181
+ orderBy: options?.orderBy,
182
+ search: options?.search,
183
+ }, queryOptions)
184
+ }
185
+
186
+ // ============ GET ============
187
+ export function use${name}(id: string) {
188
+ return trpc.${lowerName}.get.useQuery({ id }, {
189
+ enabled: !!id,
190
+ })
191
+ }
192
+
193
+ // ============ CREATE FORM ============
194
+ export function use${name}Form() {
195
+ ${tDeclaration}
196
+ const utils = trpc.useUtils()
197
+
198
+ const form = useForm<${name}Create>({
199
+ resolver: zodResolver(${resolverSchema}),
200
+ })
201
+
202
+ const mutation = trpc.${lowerName}.create.useMutation({
203
+ onSuccess: () => {
204
+ utils.${lowerName}.list.invalidate()
205
+ form.reset()
206
+ },
207
+ })
208
+
209
+ return {
210
+ ...form,
211
+ submit: form.handleSubmit((data) => mutation.mutate(data)),
212
+ isPending: mutation.isPending,
213
+ error: mutation.error,
214
+ isSuccess: mutation.isSuccess,
215
+ reset: () => {
216
+ form.reset()
217
+ mutation.reset()
218
+ },
219
+ }
220
+ }
221
+
222
+ // ============ EDIT FORM ============
223
+ export function use${name}EditForm(id: string) {
224
+ ${tDeclaration}
225
+ const utils = trpc.useUtils()
226
+ const { data: ${safeVarName}, isLoading } = trpc.${lowerName}.get.useQuery({ id })
227
+
228
+ const mutation = trpc.${lowerName}.update.useMutation({
229
+ onSuccess: () => {
230
+ utils.${lowerName}.invalidate()
231
+ },
232
+ })
233
+
234
+ const formValues = useMemo(() => nullToUndefined(${safeVarName}) as ${name}Update | undefined, [${safeVarName}])
235
+
236
+ const form = useForm<${name}Update>({
237
+ resolver: zodResolver(${updateResolverSchema}),
238
+ values: formValues,
239
+ })
240
+
241
+ return {
242
+ ...form,
243
+ submit: form.handleSubmit((data) => mutation.mutate({ id, data })),
244
+ isPending: mutation.isPending,
245
+ isLoading,
246
+ error: mutation.error,
247
+ isSuccess: mutation.isSuccess,
248
+ }
249
+ }
250
+
251
+ // ============ REMOVE ============
252
+ export function use${name}Remove() {
253
+ const utils = trpc.useUtils()
254
+ const mutation = trpc.${lowerName}.remove.useMutation({
255
+ onSuccess: () => {
256
+ utils.${lowerName}.list.invalidate()
257
+ },
258
+ })
259
+
260
+ return {
261
+ remove: (id: string) => mutation.mutate({ id }),
262
+ isPending: mutation.isPending,
263
+ error: mutation.error,
264
+ isSuccess: mutation.isSuccess,
265
+ }
266
+ }
267
+
268
+ // ============ CREATE MUTATION (without form) ============
269
+ export function useCreate${name}() {
270
+ const utils = trpc.useUtils()
271
+ return trpc.${lowerName}.create.useMutation({
272
+ onSuccess: () => {
273
+ utils.${lowerName}.list.invalidate()
274
+ },
275
+ })
276
+ }
277
+
278
+ // ============ UPDATE MUTATION (without form) ============
279
+ export function useUpdate${name}() {
280
+ const utils = trpc.useUtils()
281
+ return trpc.${lowerName}.update.useMutation({
282
+ onSuccess: () => {
283
+ utils.${lowerName}.invalidate()
284
+ },
285
+ })
286
+ }
287
+
288
+ // ============ BATCH OPERATIONS ============
289
+
290
+ // Create multiple ${name}s at once
291
+ export function useCreateMany${name}s() {
292
+ const utils = trpc.useUtils()
293
+ const mutation = trpc.${lowerName}.createMany.useMutation({
294
+ onSuccess: () => {
295
+ utils.${lowerName}.list.invalidate()
296
+ },
297
+ })
298
+
299
+ return {
300
+ createMany: (items: ${name}Create[]) => mutation.mutate({ items }),
301
+ ...mutation,
302
+ }
303
+ }
304
+
305
+ // Update multiple ${name}s at once
306
+ export function useUpdateMany${name}s() {
307
+ const utils = trpc.useUtils()
308
+ const mutation = trpc.${lowerName}.updateMany.useMutation({
309
+ onSuccess: () => {
310
+ utils.${lowerName}.invalidate()
311
+ },
312
+ })
313
+
314
+ return {
315
+ updateMany: (items: { id: string; data: ${name}Update }[]) => mutation.mutate({ items }),
316
+ ...mutation,
317
+ }
318
+ }
319
+
320
+ // Remove multiple ${name}s at once
321
+ export function useRemoveMany${name}s() {
322
+ const utils = trpc.useUtils()
323
+ const mutation = trpc.${lowerName}.removeMany.useMutation({
324
+ onSuccess: () => {
325
+ utils.${lowerName}.list.invalidate()
326
+ },
327
+ })
328
+
329
+ return {
330
+ removeMany: (ids: string[]) => mutation.mutate({ ids }),
331
+ ...mutation,
332
+ }
333
+ }
334
+ `;
335
+ }
336
+ exports.hooksGenerator = {
337
+ name: 'react-hooks',
338
+ description: 'Generate React hooks with React Hook Form integration',
339
+ generate(manifest, ctx) {
340
+ return manifest.entities.map(entity => ({
341
+ path: `hooks/use${entity.name}.ts`,
342
+ content: generateEntityHooks(entity, manifest),
343
+ }));
344
+ },
345
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * i18n Translation Files Generator
3
+ *
4
+ * Generates JSON translation files for internationalized validation messages.
5
+ * Only runs when multiple languages are configured in the manifest.
6
+ *
7
+ * Generated files:
8
+ * - i18n/{lang}/validation.json - Validation error messages
9
+ * - i18n/{lang}/fields.json - Field labels per entity
10
+ * - i18n/{lang}/entities.json - Entity display names
11
+ *
12
+ * Supported languages (with built-in translations):
13
+ * - en (English), es (Spanish), fr (French), de (German)
14
+ * - pt (Portuguese), it (Italian), ja (Japanese), zh (Chinese), ko (Korean)
15
+ *
16
+ * Features:
17
+ * - Parameterized message templates ({field}, {min}, {max}, {values})
18
+ * - Compatible with next-intl ICU message format
19
+ * - Falls back to English for unsupported languages
20
+ *
21
+ * @module generators/i18n
22
+ */
23
+ import type { Generator } from '../../../template/types';
24
+ export declare const i18nGenerator: Generator;
25
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../../../../src/templates/nextjs-drizzle-trpc/generators/i18n.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,yBAAyB,CAAA;AAoJvE,eAAO,MAAM,aAAa,EAAE,SAwC3B,CAAA"}
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ /**
3
+ * i18n Translation Files Generator
4
+ *
5
+ * Generates JSON translation files for internationalized validation messages.
6
+ * Only runs when multiple languages are configured in the manifest.
7
+ *
8
+ * Generated files:
9
+ * - i18n/{lang}/validation.json - Validation error messages
10
+ * - i18n/{lang}/fields.json - Field labels per entity
11
+ * - i18n/{lang}/entities.json - Entity display names
12
+ *
13
+ * Supported languages (with built-in translations):
14
+ * - en (English), es (Spanish), fr (French), de (German)
15
+ * - pt (Portuguese), it (Italian), ja (Japanese), zh (Chinese), ko (Korean)
16
+ *
17
+ * Features:
18
+ * - Parameterized message templates ({field}, {min}, {max}, {values})
19
+ * - Compatible with next-intl ICU message format
20
+ * - Falls back to English for unsupported languages
21
+ *
22
+ * @module generators/i18n
23
+ */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.i18nGenerator = void 0;
26
+ // Default validation messages per language
27
+ const defaultValidationMessages = {
28
+ en: {
29
+ required: '{field} is required',
30
+ email: 'Invalid email address',
31
+ url: 'Invalid URL',
32
+ min: '{field} must be at least {min}',
33
+ max: '{field} must be at most {max}',
34
+ minLength: '{field} must be at least {min} characters',
35
+ maxLength: '{field} must be at most {max} characters',
36
+ oneOf: '{field} must be one of: {values}',
37
+ pattern: '{field} format is invalid',
38
+ integer: '{field} must be a whole number',
39
+ positive: '{field} must be positive',
40
+ },
41
+ es: {
42
+ required: '{field} es requerido',
43
+ email: 'Correo electrónico inválido',
44
+ url: 'URL inválida',
45
+ min: '{field} debe ser al menos {min}',
46
+ max: '{field} debe ser como máximo {max}',
47
+ minLength: '{field} debe tener al menos {min} caracteres',
48
+ maxLength: '{field} debe tener como máximo {max} caracteres',
49
+ oneOf: '{field} debe ser uno de: {values}',
50
+ pattern: 'Formato de {field} inválido',
51
+ integer: '{field} debe ser un número entero',
52
+ positive: '{field} debe ser positivo',
53
+ },
54
+ fr: {
55
+ required: '{field} est requis',
56
+ email: 'Adresse e-mail invalide',
57
+ url: 'URL invalide',
58
+ min: '{field} doit être au moins {min}',
59
+ max: '{field} doit être au plus {max}',
60
+ minLength: '{field} doit contenir au moins {min} caractères',
61
+ maxLength: '{field} doit contenir au plus {max} caractères',
62
+ oneOf: '{field} doit être l\'un des: {values}',
63
+ pattern: 'Format de {field} invalide',
64
+ integer: '{field} doit être un nombre entier',
65
+ positive: '{field} doit être positif',
66
+ },
67
+ de: {
68
+ required: '{field} ist erforderlich',
69
+ email: 'Ungültige E-Mail-Adresse',
70
+ url: 'Ungültige URL',
71
+ min: '{field} muss mindestens {min} sein',
72
+ max: '{field} darf höchstens {max} sein',
73
+ minLength: '{field} muss mindestens {min} Zeichen haben',
74
+ maxLength: '{field} darf höchstens {max} Zeichen haben',
75
+ oneOf: '{field} muss eines von: {values} sein',
76
+ pattern: 'Format von {field} ist ungültig',
77
+ integer: '{field} muss eine ganze Zahl sein',
78
+ positive: '{field} muss positiv sein',
79
+ },
80
+ pt: {
81
+ required: '{field} é obrigatório',
82
+ email: 'Endereço de e-mail inválido',
83
+ url: 'URL inválida',
84
+ min: '{field} deve ser pelo menos {min}',
85
+ max: '{field} deve ser no máximo {max}',
86
+ minLength: '{field} deve ter pelo menos {min} caracteres',
87
+ maxLength: '{field} deve ter no máximo {max} caracteres',
88
+ oneOf: '{field} deve ser um de: {values}',
89
+ pattern: 'Formato de {field} inválido',
90
+ integer: '{field} deve ser um número inteiro',
91
+ positive: '{field} deve ser positivo',
92
+ },
93
+ it: {
94
+ required: '{field} è richiesto',
95
+ email: 'Indirizzo email non valido',
96
+ url: 'URL non valido',
97
+ min: '{field} deve essere almeno {min}',
98
+ max: '{field} deve essere al massimo {max}',
99
+ minLength: '{field} deve contenere almeno {min} caratteri',
100
+ maxLength: '{field} deve contenere al massimo {max} caratteri',
101
+ oneOf: '{field} deve essere uno tra: {values}',
102
+ pattern: 'Formato di {field} non valido',
103
+ integer: '{field} deve essere un numero intero',
104
+ positive: '{field} deve essere positivo',
105
+ },
106
+ ja: {
107
+ required: '{field}は必須です',
108
+ email: '無効なメールアドレス',
109
+ url: '無効なURL',
110
+ min: '{field}は{min}以上である必要があります',
111
+ max: '{field}は{max}以下である必要があります',
112
+ minLength: '{field}は{min}文字以上である必要があります',
113
+ maxLength: '{field}は{max}文字以下である必要があります',
114
+ oneOf: '{field}は次のいずれかである必要があります: {values}',
115
+ pattern: '{field}の形式が無効です',
116
+ integer: '{field}は整数である必要があります',
117
+ positive: '{field}は正の数である必要があります',
118
+ },
119
+ zh: {
120
+ required: '{field}是必填项',
121
+ email: '无效的电子邮件地址',
122
+ url: '无效的URL',
123
+ min: '{field}必须至少为{min}',
124
+ max: '{field}必须最多为{max}',
125
+ minLength: '{field}必须至少为{min}个字符',
126
+ maxLength: '{field}必须最多为{max}个字符',
127
+ oneOf: '{field}必须是以下之一: {values}',
128
+ pattern: '{field}格式无效',
129
+ integer: '{field}必须是整数',
130
+ positive: '{field}必须是正数',
131
+ },
132
+ ko: {
133
+ required: '{field}은(는) 필수입니다',
134
+ email: '유효하지 않은 이메일 주소',
135
+ url: '유효하지 않은 URL',
136
+ min: '{field}은(는) 최소 {min}이어야 합니다',
137
+ max: '{field}은(는) 최대 {max}이어야 합니다',
138
+ minLength: '{field}은(는) 최소 {min}자 이상이어야 합니다',
139
+ maxLength: '{field}은(는) 최대 {max}자 이하이어야 합니다',
140
+ oneOf: '{field}은(는) 다음 중 하나여야 합니다: {values}',
141
+ pattern: '{field} 형식이 유효하지 않습니다',
142
+ integer: '{field}은(는) 정수여야 합니다',
143
+ positive: '{field}은(는) 양수여야 합니다',
144
+ },
145
+ };
146
+ /**
147
+ * Generate field labels mapping from entities
148
+ *
149
+ * Extracts labels from field configurations, falling back to field names.
150
+ *
151
+ * @param entities - Array of entity IRs with field definitions
152
+ * @returns Nested object of entity -> field -> label
153
+ */
154
+ function generateFieldLabels(entities) {
155
+ const labels = {};
156
+ for (const entity of entities) {
157
+ const entityLabels = {};
158
+ for (const [fieldName, config] of Object.entries(entity.fields)) {
159
+ entityLabels[fieldName] = config.label || fieldName;
160
+ }
161
+ labels[entity.name.toLowerCase()] = entityLabels;
162
+ }
163
+ return labels;
164
+ }
165
+ exports.i18nGenerator = {
166
+ name: 'i18n-files',
167
+ description: 'Generate i18n translation files',
168
+ generate(manifest, ctx) {
169
+ const files = [];
170
+ // Only generate if multiple languages are configured
171
+ if (manifest.i18n.languages.length <= 1) {
172
+ return files;
173
+ }
174
+ for (const lang of manifest.i18n.languages) {
175
+ // Validation messages
176
+ const validationMessages = defaultValidationMessages[lang] || defaultValidationMessages.en;
177
+ files.push({
178
+ path: `i18n/${lang}/validation.json`,
179
+ content: JSON.stringify(validationMessages, null, 2),
180
+ });
181
+ // Field labels
182
+ const fieldLabels = generateFieldLabels(manifest.entities);
183
+ files.push({
184
+ path: `i18n/${lang}/fields.json`,
185
+ content: JSON.stringify(fieldLabels, null, 2),
186
+ });
187
+ // Entity names (for UI)
188
+ const entityNames = {};
189
+ for (const entity of manifest.entities) {
190
+ entityNames[entity.name.toLowerCase()] = entity.name;
191
+ }
192
+ files.push({
193
+ path: `i18n/${lang}/entities.json`,
194
+ content: JSON.stringify(entityNames, null, 2),
195
+ });
196
+ }
197
+ return files;
198
+ },
199
+ };
@@ -0,0 +1,8 @@
1
+ export { schemaGenerator } from './schema';
2
+ export { authGenerator } from './auth';
3
+ export { validationGenerator } from './validation';
4
+ export { apiGenerator } from './api';
5
+ export { hooksGenerator } from './hooks';
6
+ export { crudHooksGenerator } from './crud-hooks';
7
+ export { i18nGenerator } from './i18n';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/templates/nextjs-drizzle-trpc/generators/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ // Export all generators for the nextjs-drizzle-trpc template
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.i18nGenerator = exports.crudHooksGenerator = exports.hooksGenerator = exports.apiGenerator = exports.validationGenerator = exports.authGenerator = exports.schemaGenerator = void 0;
5
+ var schema_1 = require("./schema");
6
+ Object.defineProperty(exports, "schemaGenerator", { enumerable: true, get: function () { return schema_1.schemaGenerator; } });
7
+ var auth_1 = require("./auth");
8
+ Object.defineProperty(exports, "authGenerator", { enumerable: true, get: function () { return auth_1.authGenerator; } });
9
+ var validation_1 = require("./validation");
10
+ Object.defineProperty(exports, "validationGenerator", { enumerable: true, get: function () { return validation_1.validationGenerator; } });
11
+ var api_1 = require("./api");
12
+ Object.defineProperty(exports, "apiGenerator", { enumerable: true, get: function () { return api_1.apiGenerator; } });
13
+ var hooks_1 = require("./hooks");
14
+ Object.defineProperty(exports, "hooksGenerator", { enumerable: true, get: function () { return hooks_1.hooksGenerator; } });
15
+ var crud_hooks_1 = require("./crud-hooks");
16
+ Object.defineProperty(exports, "crudHooksGenerator", { enumerable: true, get: function () { return crud_hooks_1.crudHooksGenerator; } });
17
+ var i18n_1 = require("./i18n");
18
+ Object.defineProperty(exports, "i18nGenerator", { enumerable: true, get: function () { return i18n_1.i18nGenerator; } });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Drizzle ORM Schema Generator
3
+ *
4
+ * Generates database table definitions for Drizzle ORM from entity definitions.
5
+ * Supports SQLite, PostgreSQL, and MySQL databases.
6
+ *
7
+ * Generated files:
8
+ * - db/schema.ts - All entity table definitions and junction tables
9
+ *
10
+ * Features:
11
+ * - Maps field types to appropriate database column types
12
+ * - Handles required/optional fields with notNull()
13
+ * - Creates foreign key references for hasOne relations
14
+ * - Generates junction tables for belongsToMany relations
15
+ * - Adds timestamp fields (createdAt, updatedAt) when behaviors.timestamps is true
16
+ * - Adds deletedAt field when behaviors.softDelete is true
17
+ *
18
+ * @module generators/schema
19
+ */
20
+ import type { Generator } from '../../../template/types';
21
+ export declare const schemaGenerator: Generator;
22
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../../src/templates/nextjs-drizzle-trpc/generators/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,yBAAyB,CAAA;AAsPvE,eAAO,MAAM,eAAe,EAAE,SAuC7B,CAAA"}