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,587 @@
1
+ "use strict";
2
+ // File templates for archetype init
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.getConfigTemplate = getConfigTemplate;
5
+ exports.getTaskEntityTemplate = getTaskEntityTemplate;
6
+ exports.getProductEntityTemplate = getProductEntityTemplate;
7
+ exports.getDbTemplate = getDbTemplate;
8
+ exports.getTrpcServerTemplate = getTrpcServerTemplate;
9
+ exports.getTrpcClientTemplate = getTrpcClientTemplate;
10
+ exports.getProvidersTemplate = getProvidersTemplate;
11
+ exports.getApiRouteTemplate = getApiRouteTemplate;
12
+ exports.getDrizzleConfigTemplate = getDrizzleConfigTemplate;
13
+ exports.getAuthTemplate = getAuthTemplate;
14
+ exports.getAuthRouteTemplate = getAuthRouteTemplate;
15
+ exports.getEnvExampleTemplate = getEnvExampleTemplate;
16
+ exports.getGitignoreTemplate = getGitignoreTemplate;
17
+ exports.getAllTemplateFiles = getAllTemplateFiles;
18
+ exports.getPackageJsonScripts = getPackageJsonScripts;
19
+ const entity_templates_1 = require("./entity-templates");
20
+ // archetype.config.ts
21
+ function getConfigTemplate(config) {
22
+ // Headless mode config
23
+ if (config.mode === 'headless') {
24
+ const authConfig = config.auth && config.authProviders
25
+ ? `
26
+ auth: {
27
+ enabled: true,
28
+ providers: ${JSON.stringify(config.authProviders)},
29
+ },`
30
+ : '';
31
+ const i18nConfig = config.i18n
32
+ ? `
33
+ i18n: {
34
+ languages: ${JSON.stringify(config.i18n)},
35
+ defaultLanguage: '${config.i18n[0]}',
36
+ },`
37
+ : '';
38
+ const entityImport = config.includeExamples
39
+ ? `import { Product } from './archetype/entities/product'`
40
+ : '';
41
+ const entities = config.includeExamples ? '[Product]' : '[]';
42
+ const sourceUrl = config.externalApiUrl || 'env:API_URL';
43
+ return `import { defineConfig, external } from 'archetype-engine'
44
+ ${entityImport}
45
+
46
+ export default defineConfig({
47
+ template: '${config.template}',
48
+ mode: 'headless',
49
+ source: external('${sourceUrl}'),
50
+ entities: ${entities},${authConfig}${i18nConfig}
51
+ })
52
+ `;
53
+ }
54
+ // Full mode config (with database)
55
+ const dbConfig = config.database === 'sqlite'
56
+ ? `{
57
+ type: 'sqlite',
58
+ file: './sqlite.db',
59
+ }`
60
+ : config.database === 'postgres'
61
+ ? `{
62
+ type: 'postgres',
63
+ url: process.env.DATABASE_URL!,
64
+ }`
65
+ : `{
66
+ type: 'mysql',
67
+ url: process.env.DATABASE_URL!,
68
+ }`;
69
+ const authConfig = config.auth && config.authProviders
70
+ ? `
71
+ auth: {
72
+ enabled: true,
73
+ providers: ${JSON.stringify(config.authProviders)},
74
+ },`
75
+ : '';
76
+ const i18nConfig = config.i18n
77
+ ? `
78
+ i18n: {
79
+ languages: ${JSON.stringify(config.i18n)},
80
+ defaultLanguage: '${config.i18n[0]}',
81
+ },`
82
+ : '';
83
+ let entityImport = '';
84
+ let entities = '[]';
85
+ if (config.includeExamples) {
86
+ if (config.entityTemplate && config.entityTemplate !== 'simple') {
87
+ const template = (0, entity_templates_1.getEntityTemplate)(config.entityTemplate);
88
+ if (template) {
89
+ // Import all entities from the template
90
+ const imports = template.entities.map(e => {
91
+ const entityName = e.filename.replace('.ts', '').split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
92
+ return `import { ${entityName} } from './archetype/entities/${e.filename.replace('.ts', '')}'`;
93
+ });
94
+ entityImport = imports.join('\n');
95
+ const entityNames = template.entities.map(e => {
96
+ return e.filename.replace('.ts', '').split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
97
+ });
98
+ entities = `[${entityNames.join(', ')}]`;
99
+ }
100
+ }
101
+ else {
102
+ entityImport = `import { Task } from './archetype/entities/task'`;
103
+ entities = '[Task]';
104
+ }
105
+ }
106
+ return `import { defineConfig } from 'archetype-engine'
107
+ ${entityImport}
108
+
109
+ export default defineConfig({
110
+ template: '${config.template}',
111
+ entities: ${entities},
112
+ database: ${dbConfig},${authConfig}${i18nConfig}
113
+ })
114
+ `;
115
+ }
116
+ // archetype/entities/task.ts (example entity for full mode)
117
+ function getTaskEntityTemplate() {
118
+ return `import { defineEntity, text, boolean, date } from 'archetype-engine'
119
+
120
+ export const Task = defineEntity('Task', {
121
+ fields: {
122
+ title: text().required().min(1).max(200).label('Title'),
123
+ description: text().optional().max(2000).label('Description'),
124
+ completed: boolean().default(false).label('Completed'),
125
+ dueDate: date().optional().label('Due Date'),
126
+ },
127
+ behaviors: {
128
+ timestamps: true,
129
+ },
130
+ })
131
+ `;
132
+ }
133
+ // archetype/entities/product.ts (example entity for headless mode)
134
+ function getProductEntityTemplate() {
135
+ return `import { defineEntity, text, number } from 'archetype-engine'
136
+
137
+ // Example entity for headless mode - uses external API
138
+ // The source is inherited from the config's global source
139
+ export const Product = defineEntity('Product', {
140
+ fields: {
141
+ sku: text().required().label('SKU'),
142
+ name: text().required().min(1).max(200).label('Name'),
143
+ description: text().optional().max(2000).label('Description'),
144
+ price: number().required().positive().label('Price'),
145
+ stock: number().optional().integer().min(0).label('Stock'),
146
+ },
147
+ })
148
+ `;
149
+ }
150
+ // src/server/db.ts
151
+ function getDbTemplate(database) {
152
+ switch (database) {
153
+ case 'sqlite':
154
+ return `import { drizzle } from 'drizzle-orm/better-sqlite3'
155
+ import Database from 'better-sqlite3'
156
+ import * as schema from '@/generated/db/schema'
157
+
158
+ const sqlite = new Database('sqlite.db')
159
+ export const db = drizzle(sqlite, { schema })
160
+ `;
161
+ case 'postgres':
162
+ return `import { drizzle } from 'drizzle-orm/postgres-js'
163
+ import postgres from 'postgres'
164
+ import * as schema from '@/generated/db/schema'
165
+
166
+ const client = postgres(process.env.DATABASE_URL!)
167
+ export const db = drizzle(client, { schema })
168
+ `;
169
+ case 'mysql':
170
+ return `import { drizzle } from 'drizzle-orm/mysql2'
171
+ import mysql from 'mysql2/promise'
172
+ import * as schema from '@/generated/db/schema'
173
+
174
+ const connection = await mysql.createConnection(process.env.DATABASE_URL!)
175
+ export const db = drizzle(connection, { schema, mode: 'default' })
176
+ `;
177
+ }
178
+ }
179
+ // src/server/trpc.ts
180
+ function getTrpcServerTemplate(config) {
181
+ // Headless mode (no database)
182
+ if (config.mode === 'headless') {
183
+ if (config.auth) {
184
+ return `import { initTRPC, TRPCError } from '@trpc/server'
185
+ import { auth } from './auth'
186
+
187
+ interface Context {
188
+ session: Awaited<ReturnType<typeof auth>> | null
189
+ }
190
+
191
+ export async function createContext(): Promise<Context> {
192
+ const session = await auth()
193
+ return { session }
194
+ }
195
+
196
+ const t = initTRPC.context<Context>().create()
197
+
198
+ export const router = t.router
199
+ export const publicProcedure = t.procedure
200
+
201
+ /**
202
+ * Protected procedure - requires authentication
203
+ * Use for entity operations that need auth
204
+ */
205
+ export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
206
+ if (!ctx.session?.user) {
207
+ throw new TRPCError({ code: 'UNAUTHORIZED', message: 'You must be logged in' })
208
+ }
209
+ return next({
210
+ ctx: {
211
+ ...ctx,
212
+ session: ctx.session,
213
+ user: ctx.session.user,
214
+ },
215
+ })
216
+ })
217
+ `;
218
+ }
219
+ return `import { initTRPC } from '@trpc/server'
220
+
221
+ const t = initTRPC.create()
222
+
223
+ export const router = t.router
224
+ export const publicProcedure = t.procedure
225
+ `;
226
+ }
227
+ // Full mode (with database)
228
+ if (config.auth) {
229
+ return `import { initTRPC, TRPCError } from '@trpc/server'
230
+ import { auth } from './auth'
231
+ import { db } from './db'
232
+
233
+ interface Context {
234
+ session: Awaited<ReturnType<typeof auth>> | null
235
+ db: typeof db
236
+ }
237
+
238
+ export async function createContext(): Promise<Context> {
239
+ const session = await auth()
240
+ return { session, db }
241
+ }
242
+
243
+ const t = initTRPC.context<Context>().create()
244
+
245
+ export const router = t.router
246
+ export const publicProcedure = t.procedure
247
+
248
+ /**
249
+ * Protected procedure - requires authentication
250
+ * Use for entity operations that need auth
251
+ */
252
+ export const protectedProcedure = t.procedure.use(async ({ ctx, next }) => {
253
+ if (!ctx.session?.user) {
254
+ throw new TRPCError({ code: 'UNAUTHORIZED', message: 'You must be logged in' })
255
+ }
256
+ return next({
257
+ ctx: {
258
+ ...ctx,
259
+ session: ctx.session,
260
+ user: ctx.session.user,
261
+ },
262
+ })
263
+ })
264
+ `;
265
+ }
266
+ return `import { initTRPC } from '@trpc/server'
267
+ import { db } from './db'
268
+
269
+ interface Context {
270
+ db: typeof db
271
+ }
272
+
273
+ export function createContext(): Context {
274
+ return { db }
275
+ }
276
+
277
+ const t = initTRPC.context<Context>().create()
278
+
279
+ export const router = t.router
280
+ export const publicProcedure = t.procedure
281
+ `;
282
+ }
283
+ // src/lib/trpc.ts
284
+ function getTrpcClientTemplate() {
285
+ return `import { createTRPCReact } from '@trpc/react-query'
286
+ import type { AppRouter } from '@/generated/trpc/routers'
287
+
288
+ export const trpc = createTRPCReact<AppRouter>()
289
+ `;
290
+ }
291
+ // src/app/providers.tsx
292
+ function getProvidersTemplate() {
293
+ return `'use client'
294
+
295
+ import { useState } from 'react'
296
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
297
+ import { httpBatchLink } from '@trpc/client'
298
+ import { trpc } from '@/lib/trpc'
299
+
300
+ export function Providers({ children }: { children: React.ReactNode }) {
301
+ const [queryClient] = useState(() => new QueryClient())
302
+ const [trpcClient] = useState(() =>
303
+ trpc.createClient({
304
+ links: [httpBatchLink({ url: '/api/trpc' })],
305
+ })
306
+ )
307
+
308
+ return (
309
+ <trpc.Provider client={trpcClient} queryClient={queryClient}>
310
+ <QueryClientProvider client={queryClient}>
311
+ {children}
312
+ </QueryClientProvider>
313
+ </trpc.Provider>
314
+ )
315
+ }
316
+ `;
317
+ }
318
+ // src/app/api/trpc/[trpc]/route.ts
319
+ function getApiRouteTemplate(config) {
320
+ if (config.auth) {
321
+ return `import { fetchRequestHandler } from '@trpc/server/adapters/fetch'
322
+ import { appRouter } from '@/generated/trpc/routers'
323
+ import { createContext } from '@/server/trpc'
324
+
325
+ const handler = (req: Request) =>
326
+ fetchRequestHandler({
327
+ endpoint: '/api/trpc',
328
+ req,
329
+ router: appRouter,
330
+ createContext,
331
+ })
332
+
333
+ export { handler as GET, handler as POST }
334
+ `;
335
+ }
336
+ return `import { fetchRequestHandler } from '@trpc/server/adapters/fetch'
337
+ import { appRouter } from '@/generated/trpc/routers'
338
+ import { createContext } from '@/server/trpc'
339
+
340
+ const handler = (req: Request) =>
341
+ fetchRequestHandler({
342
+ endpoint: '/api/trpc',
343
+ req,
344
+ router: appRouter,
345
+ createContext,
346
+ })
347
+
348
+ export { handler as GET, handler as POST }
349
+ `;
350
+ }
351
+ // drizzle.config.ts
352
+ function getDrizzleConfigTemplate(database) {
353
+ const dialectMap = {
354
+ sqlite: 'sqlite',
355
+ postgres: 'postgresql',
356
+ mysql: 'mysql',
357
+ };
358
+ const credentialsMap = {
359
+ sqlite: "url: 'sqlite.db'",
360
+ postgres: 'url: process.env.DATABASE_URL!',
361
+ mysql: 'url: process.env.DATABASE_URL!',
362
+ };
363
+ return `import { defineConfig } from 'drizzle-kit'
364
+
365
+ export default defineConfig({
366
+ schema: ['./generated/db/schema.ts', './generated/db/auth-schema.ts'],
367
+ out: './drizzle',
368
+ dialect: '${dialectMap[database]}',
369
+ dbCredentials: { ${credentialsMap[database]} },
370
+ })
371
+ `;
372
+ }
373
+ // src/server/auth.ts - NextAuth configuration
374
+ function getAuthTemplate(config) {
375
+ const providers = config.authProviders || ['credentials'];
376
+ const imports = ['import NextAuth from "next-auth"'];
377
+ const providerSetups = [];
378
+ if (providers.includes('credentials')) {
379
+ imports.push('import Credentials from "next-auth/providers/credentials"');
380
+ providerSetups.push(` Credentials({
381
+ credentials: {
382
+ email: { label: "Email", type: "email" },
383
+ password: { label: "Password", type: "password" },
384
+ },
385
+ async authorize(credentials) {
386
+ // SCAFFOLD: Replace this placeholder with your authentication logic
387
+ // Example implementation:
388
+ // 1. Validate credentials exist
389
+ // 2. Look up user in database by email
390
+ // 3. Verify password with bcrypt
391
+ // 4. Return user object or null
392
+ if (!credentials?.email || !credentials?.password) return null
393
+
394
+ // Example: look up user in database
395
+ // const user = await db.query.users.findFirst({
396
+ // where: eq(users.email, credentials.email)
397
+ // })
398
+ // if (!user || !await bcrypt.compare(credentials.password, user.password)) {
399
+ // return null
400
+ // }
401
+ // return { id: user.id, email: user.email, name: user.name }
402
+
403
+ return null
404
+ },
405
+ })`);
406
+ }
407
+ if (providers.includes('google')) {
408
+ imports.push('import Google from "next-auth/providers/google"');
409
+ providerSetups.push(' Google');
410
+ }
411
+ if (providers.includes('github')) {
412
+ imports.push('import GitHub from "next-auth/providers/github"');
413
+ providerSetups.push(' GitHub');
414
+ }
415
+ if (providers.includes('discord')) {
416
+ imports.push('import Discord from "next-auth/providers/discord"');
417
+ providerSetups.push(' Discord');
418
+ }
419
+ return `${imports.join('\n')}
420
+ import { DrizzleAdapter } from "@auth/drizzle-adapter"
421
+ import { db } from "./db"
422
+ import * as authSchema from "@/generated/db/auth-schema"
423
+
424
+ export const { handlers, auth, signIn, signOut } = NextAuth({
425
+ adapter: DrizzleAdapter(db, {
426
+ usersTable: authSchema.users,
427
+ accountsTable: authSchema.accounts,
428
+ sessionsTable: authSchema.sessions,
429
+ verificationTokensTable: authSchema.verificationTokens,
430
+ }),
431
+ session: { strategy: "jwt" },
432
+ providers: [
433
+ ${providerSetups.join(',\n')},
434
+ ],
435
+ callbacks: {
436
+ session: ({ session, token }) => ({
437
+ ...session,
438
+ user: {
439
+ ...session.user,
440
+ id: token.sub,
441
+ },
442
+ }),
443
+ },
444
+ })
445
+ `;
446
+ }
447
+ // src/app/api/auth/[...nextauth]/route.ts
448
+ function getAuthRouteTemplate() {
449
+ return `import { handlers } from "@/server/auth"
450
+
451
+ export const { GET, POST } = handlers
452
+ `;
453
+ }
454
+ // .env.example
455
+ function getEnvExampleTemplate(config) {
456
+ const lines = ['# Authentication'];
457
+ lines.push('AUTH_SECRET=your-auth-secret-here # Generate with: npx auth secret');
458
+ const providers = config.authProviders || [];
459
+ if (providers.includes('google')) {
460
+ lines.push('');
461
+ lines.push('# Google OAuth');
462
+ lines.push('AUTH_GOOGLE_ID=your-google-client-id');
463
+ lines.push('AUTH_GOOGLE_SECRET=your-google-client-secret');
464
+ }
465
+ if (providers.includes('github')) {
466
+ lines.push('');
467
+ lines.push('# GitHub OAuth');
468
+ lines.push('AUTH_GITHUB_ID=your-github-client-id');
469
+ lines.push('AUTH_GITHUB_SECRET=your-github-client-secret');
470
+ }
471
+ if (providers.includes('discord')) {
472
+ lines.push('');
473
+ lines.push('# Discord OAuth');
474
+ lines.push('AUTH_DISCORD_ID=your-discord-client-id');
475
+ lines.push('AUTH_DISCORD_SECRET=your-discord-client-secret');
476
+ }
477
+ if (config.database && config.database !== 'sqlite') {
478
+ lines.push('');
479
+ lines.push('# Database');
480
+ lines.push('DATABASE_URL=your-database-url');
481
+ }
482
+ return lines.join('\n') + '\n';
483
+ }
484
+ // .gitignore for Archetype projects
485
+ function getGitignoreTemplate() {
486
+ return `# Generated by Archetype
487
+ generated/
488
+
489
+ # Dependencies
490
+ node_modules/
491
+
492
+ # Database
493
+ *.db
494
+ *.db-shm
495
+ *.db-wal
496
+ drizzle/
497
+
498
+ # Environment
499
+ .env
500
+ .env.local
501
+ .env*.local
502
+
503
+ # Next.js
504
+ .next/
505
+ out/
506
+ build/
507
+ dist/
508
+
509
+ # Misc
510
+ .DS_Store
511
+ *.log
512
+ .turbo
513
+ `;
514
+ }
515
+ function getAllTemplateFiles(config, structure) {
516
+ const prefix = structure.useSrcDir ? 'src/' : '';
517
+ const files = [
518
+ // Config - always needed
519
+ { path: 'archetype.config.ts', content: getConfigTemplate(config) },
520
+ // Gitignore - always needed
521
+ { path: '.gitignore', content: getGitignoreTemplate() },
522
+ ];
523
+ if (config.mode === 'headless') {
524
+ // Headless mode: tRPC but no database
525
+ files.push({ path: `${prefix}server/trpc.ts`, content: getTrpcServerTemplate(config) }, { path: `${prefix}lib/trpc.ts`, content: getTrpcClientTemplate() }, { path: `${prefix}app/providers.tsx`, content: getProvidersTemplate() }, { path: `${prefix}app/api/trpc/[trpc]/route.ts`, content: getApiRouteTemplate(config) });
526
+ // Example entity for headless mode
527
+ if (config.includeExamples) {
528
+ if (config.entityTemplate && config.entityTemplate !== 'simple') {
529
+ // Use advanced template
530
+ const template = (0, entity_templates_1.getEntityTemplate)(config.entityTemplate);
531
+ if (template) {
532
+ template.entities.forEach(entity => {
533
+ files.push({ path: `archetype/entities/${entity.filename}`, content: entity.code });
534
+ });
535
+ }
536
+ }
537
+ else {
538
+ // Use simple product example
539
+ files.push({ path: 'archetype/entities/product.ts', content: getProductEntityTemplate() });
540
+ }
541
+ }
542
+ // Auth files for headless mode (if auth enabled)
543
+ if (config.auth) {
544
+ files.push({ path: `${prefix}server/auth.ts`, content: getAuthTemplate(config) }, { path: `${prefix}app/api/auth/[...nextauth]/route.ts`, content: getAuthRouteTemplate() }, { path: '.env.example', content: getEnvExampleTemplate(config) });
545
+ }
546
+ }
547
+ else {
548
+ // Full mode: database + tRPC
549
+ // database is guaranteed to be defined in full mode
550
+ const db = config.database;
551
+ files.push({ path: 'drizzle.config.ts', content: getDrizzleConfigTemplate(db) }, { path: `${prefix}server/db.ts`, content: getDbTemplate(db) }, { path: `${prefix}server/trpc.ts`, content: getTrpcServerTemplate(config) }, { path: `${prefix}lib/trpc.ts`, content: getTrpcClientTemplate() }, { path: `${prefix}app/providers.tsx`, content: getProvidersTemplate() }, { path: `${prefix}app/api/trpc/[trpc]/route.ts`, content: getApiRouteTemplate(config) });
552
+ // Example entities for full mode
553
+ if (config.includeExamples) {
554
+ if (config.entityTemplate && config.entityTemplate !== 'simple') {
555
+ // Use advanced template
556
+ const template = (0, entity_templates_1.getEntityTemplate)(config.entityTemplate);
557
+ if (template) {
558
+ template.entities.forEach(entity => {
559
+ files.push({ path: `archetype/entities/${entity.filename}`, content: entity.code });
560
+ });
561
+ }
562
+ }
563
+ else {
564
+ // Use simple task example
565
+ files.push({ path: 'archetype/entities/task.ts', content: getTaskEntityTemplate() });
566
+ }
567
+ }
568
+ // Auth files for full mode (if auth enabled)
569
+ if (config.auth) {
570
+ files.push({ path: `${prefix}server/auth.ts`, content: getAuthTemplate(config) }, { path: `${prefix}app/api/auth/[...nextauth]/route.ts`, content: getAuthRouteTemplate() }, { path: '.env.example', content: getEnvExampleTemplate(config) });
571
+ }
572
+ }
573
+ return files;
574
+ }
575
+ // package.json scripts to add
576
+ function getPackageJsonScripts(config) {
577
+ const scripts = {
578
+ 'archetype:generate': 'archetype generate',
579
+ 'archetype:view': 'archetype view',
580
+ };
581
+ // Only add database scripts for full mode
582
+ if (config.mode === 'full') {
583
+ scripts['db:push'] = 'drizzle-kit push';
584
+ scripts['db:studio'] = 'drizzle-kit studio';
585
+ }
586
+ return scripts;
587
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * JSON Input Module
3
+ *
4
+ * Provides types and parsers for AI agents to generate manifests using JSON
5
+ * instead of TypeScript code.
6
+ *
7
+ * @module json
8
+ */
9
+ export * from './types';
10
+ export * from './parser';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/json/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * JSON Input Module
4
+ *
5
+ * Provides types and parsers for AI agents to generate manifests using JSON
6
+ * instead of TypeScript code.
7
+ *
8
+ * @module json
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ __exportStar(require("./types"), exports);
26
+ __exportStar(require("./parser"), exports);
@@ -0,0 +1,61 @@
1
+ /**
2
+ * JSON Parser - converts JSON manifest to IR
3
+ *
4
+ * @module json/parser
5
+ */
6
+ import { FieldConfig } from '../fields';
7
+ import { RelationConfig } from '../relations';
8
+ import { EntityIR, ProtectedIR, HooksIR } from '../entity';
9
+ import { ManifestIR } from '../manifest';
10
+ import { ExternalSourceConfig } from '../source';
11
+ import { FieldJSON, RelationJSON, EntityJSON, ManifestJSON, ExternalSourceJSON, ProtectedJSON, HooksJSON } from './types';
12
+ /**
13
+ * Parse a JSON field definition to FieldConfig
14
+ */
15
+ export declare function parseFieldJSON(field: FieldJSON): FieldConfig;
16
+ /**
17
+ * Parse a JSON relation definition to RelationConfig
18
+ */
19
+ export declare function parseRelationJSON(relation: RelationJSON): RelationConfig;
20
+ /**
21
+ * Parse a JSON external source to ExternalSourceConfig
22
+ */
23
+ export declare function parseExternalSourceJSON(source: ExternalSourceJSON): ExternalSourceConfig;
24
+ /**
25
+ * Parse a JSON protected option to ProtectedIR
26
+ */
27
+ export declare function parseProtectedJSON(option?: ProtectedJSON): ProtectedIR;
28
+ /**
29
+ * Parse a JSON hooks option to HooksIR
30
+ */
31
+ export declare function parseHooksJSON(option?: boolean | HooksJSON): HooksIR;
32
+ /**
33
+ * Parse a JSON entity definition to EntityIR
34
+ */
35
+ export declare function parseEntityJSON(entity: EntityJSON): EntityIR;
36
+ /**
37
+ * Parse a JSON manifest to ManifestIR
38
+ *
39
+ * @param json - JSON manifest object or string
40
+ * @returns Compiled ManifestIR
41
+ * @throws Error if JSON is invalid or validation fails
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const manifest = parseManifestJSON({
46
+ * entities: [
47
+ * { name: 'User', fields: { email: { type: 'text', email: true } } }
48
+ * ],
49
+ * database: { type: 'sqlite', file: './app.db' }
50
+ * })
51
+ * ```
52
+ */
53
+ export declare function parseManifestJSON(json: ManifestJSON | string): ManifestIR;
54
+ /**
55
+ * Load manifest from a JSON file
56
+ *
57
+ * @param filePath - Path to JSON file
58
+ * @returns Compiled ManifestIR
59
+ */
60
+ export declare function loadManifestFromJSONFile(filePath: string): Promise<ManifestIR>;
61
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/json/parser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAc,MAAM,WAAW,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAmB,OAAO,EAAE,MAAM,WAAW,CAAA;AAC3E,OAAO,EAAE,UAAU,EAA6B,MAAM,aAAa,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAChD,OAAO,EACL,SAAS,EACT,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,SAAS,EACV,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,WAAW,CA8C5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,cAAc,CAMxE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,kBAAkB,GAAG,oBAAoB,CAuBxF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAWtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAuBpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAsC5D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAkEzE;AAED;;;;;GAKG;AACH,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAIpF"}