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,250 @@
1
+ "use strict";
2
+ // Archetype init - creates config + infrastructure + installs deps
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.getRecommendedConfig = void 0;
38
+ exports.init = init;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const child_process_1 = require("child_process");
42
+ const dependencies_1 = require("./dependencies");
43
+ const templates_1 = require("./templates");
44
+ const prompts_1 = require("./prompts");
45
+ const registry_1 = require("../template/registry");
46
+ async function init(options = {}) {
47
+ const targetDir = options.directory || process.cwd();
48
+ // Check if archetype.config.ts already exists
49
+ const configPath = path.join(targetDir, 'archetype.config.ts');
50
+ if (fs.existsSync(configPath)) {
51
+ (0, prompts_1.displayError)('archetype.config.ts already exists. Remove it first to reinitialize.');
52
+ process.exit(1);
53
+ }
54
+ // Get configuration
55
+ let config;
56
+ if (options.yes || options.headless) {
57
+ // Use specified template or first available
58
+ const templates = (0, registry_1.listTemplates)();
59
+ if (templates.length === 0) {
60
+ (0, prompts_1.displayError)('No templates available.');
61
+ process.exit(1);
62
+ }
63
+ const templateId = options.template || templates[0].id;
64
+ const mode = options.headless ? 'headless' : 'full';
65
+ config = (0, dependencies_1.getRecommendedConfig)(templateId, mode);
66
+ }
67
+ else {
68
+ config = await (0, prompts_1.runPrompts)();
69
+ }
70
+ if (!config) {
71
+ process.exit(0);
72
+ }
73
+ (0, prompts_1.displayConfigSummary)(config);
74
+ const s = (0, prompts_1.createSpinner)();
75
+ try {
76
+ // Write template files
77
+ s.start('Creating archetype config and infrastructure');
78
+ writeTemplateFiles(targetDir, config);
79
+ s.stop('Created archetype config and infrastructure');
80
+ // Update package.json scripts if it exists
81
+ const packageJsonPath = path.join(targetDir, 'package.json');
82
+ if (fs.existsSync(packageJsonPath)) {
83
+ s.start('Adding npm scripts');
84
+ updatePackageJson(packageJsonPath, config);
85
+ s.stop('Added npm scripts');
86
+ }
87
+ // Install dependencies
88
+ s.start('Installing dependencies');
89
+ await installDependencies(targetDir, config);
90
+ s.stop('Installed dependencies');
91
+ (0, prompts_1.displaySuccess)(config);
92
+ }
93
+ catch (error) {
94
+ s.stop('Error occurred');
95
+ (0, prompts_1.displayError)(error instanceof Error ? error.message : 'Unknown error');
96
+ process.exit(1);
97
+ }
98
+ }
99
+ /**
100
+ * Detect project structure - whether it uses src/ directory or root-level
101
+ * Next.js projects can have either /app or /src/app
102
+ */
103
+ function detectProjectStructure(targetDir) {
104
+ // Check if src/app exists (src-based structure)
105
+ const srcAppPath = path.join(targetDir, 'src', 'app');
106
+ if (fs.existsSync(srcAppPath)) {
107
+ return { useSrcDir: true };
108
+ }
109
+ // Check if root /app exists (root-based structure)
110
+ const rootAppPath = path.join(targetDir, 'app');
111
+ if (fs.existsSync(rootAppPath)) {
112
+ return { useSrcDir: false };
113
+ }
114
+ // Default to src-based if neither exists (new project)
115
+ return { useSrcDir: true };
116
+ }
117
+ function writeTemplateFiles(targetDir, config) {
118
+ const structure = detectProjectStructure(targetDir);
119
+ const files = (0, templates_1.getAllTemplateFiles)(config, structure);
120
+ for (const file of files) {
121
+ const fullPath = path.join(targetDir, file.path);
122
+ const dir = path.dirname(fullPath);
123
+ if (!fs.existsSync(dir)) {
124
+ fs.mkdirSync(dir, { recursive: true });
125
+ }
126
+ fs.writeFileSync(fullPath, file.content, 'utf-8');
127
+ }
128
+ // Update existing layout.tsx to wrap children with Providers
129
+ updateLayoutWithProviders(targetDir, structure);
130
+ }
131
+ /**
132
+ * Update the existing layout.tsx to wrap children with Providers
133
+ * This enables tRPC context for the entire app
134
+ */
135
+ function updateLayoutWithProviders(targetDir, structure) {
136
+ const prefix = structure.useSrcDir ? 'src/' : '';
137
+ const layoutPath = path.join(targetDir, `${prefix}app/layout.tsx`);
138
+ if (!fs.existsSync(layoutPath))
139
+ return;
140
+ let content = fs.readFileSync(layoutPath, 'utf-8');
141
+ // Skip if already has Providers
142
+ if (content.includes('Providers'))
143
+ return;
144
+ // Add import for Providers after other imports
145
+ const importStatement = 'import { Providers } from "./providers";\n';
146
+ // Find the last import statement and add after it
147
+ const importRegex = /^import .+$/gm;
148
+ let lastImportMatch = null;
149
+ let match;
150
+ while ((match = importRegex.exec(content)) !== null) {
151
+ lastImportMatch = match;
152
+ }
153
+ if (lastImportMatch) {
154
+ const insertPos = lastImportMatch.index + lastImportMatch[0].length;
155
+ content = content.slice(0, insertPos) + '\n' + importStatement + content.slice(insertPos);
156
+ }
157
+ // Wrap {children} with <Providers>{children}</Providers>
158
+ // Handle both {children} and { children } patterns
159
+ content = content.replace(/(\s*)\{(\s*)children(\s*)\}(\s*)/g, '$1<Providers>{children}</Providers>$4');
160
+ fs.writeFileSync(layoutPath, content, 'utf-8');
161
+ }
162
+ function updatePackageJson(packageJsonPath, config) {
163
+ const content = fs.readFileSync(packageJsonPath, 'utf-8');
164
+ const packageJson = JSON.parse(content);
165
+ const scripts = (0, templates_1.getPackageJsonScripts)(config);
166
+ packageJson.scripts = {
167
+ ...(packageJson.scripts || {}),
168
+ ...scripts,
169
+ };
170
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
171
+ }
172
+ async function installDependencies(targetDir, config) {
173
+ const { deps, devDeps } = (0, dependencies_1.getDependencies)(config);
174
+ // Check if archetype-engine is symlinked (npm link) before installing
175
+ // npm install can remove manually linked packages
176
+ const archetypeLinkPath = path.join(targetDir, 'node_modules', 'archetype-engine');
177
+ let wasSymlinked = false;
178
+ try {
179
+ const stat = fs.lstatSync(archetypeLinkPath);
180
+ wasSymlinked = stat.isSymbolicLink();
181
+ }
182
+ catch {
183
+ // Path doesn't exist, not linked
184
+ }
185
+ // Install production dependencies
186
+ if (deps.length > 0) {
187
+ await runNpmInstall(targetDir, deps, false);
188
+ }
189
+ // Install dev dependencies
190
+ if (devDeps.length > 0) {
191
+ await runNpmInstall(targetDir, devDeps, true);
192
+ }
193
+ // Restore npm link if it was removed by npm install
194
+ if (wasSymlinked) {
195
+ try {
196
+ fs.lstatSync(archetypeLinkPath);
197
+ }
198
+ catch {
199
+ // Link was removed, restore it
200
+ await runNpmLink(targetDir);
201
+ }
202
+ }
203
+ }
204
+ function runNpmInstall(targetDir, packages, isDev) {
205
+ return new Promise((resolve, reject) => {
206
+ const args = ['install', ...(isDev ? ['--save-dev'] : []), ...packages];
207
+ const child = (0, child_process_1.spawn)('npm', args, {
208
+ cwd: targetDir,
209
+ stdio: 'pipe',
210
+ });
211
+ let stderr = '';
212
+ child.stderr?.on('data', (data) => {
213
+ stderr += data.toString();
214
+ });
215
+ child.on('close', (code) => {
216
+ if (code === 0) {
217
+ resolve();
218
+ }
219
+ else {
220
+ reject(new Error(`npm install failed: ${stderr}`));
221
+ }
222
+ });
223
+ child.on('error', (error) => {
224
+ reject(error);
225
+ });
226
+ });
227
+ }
228
+ function runNpmLink(targetDir) {
229
+ return new Promise((resolve, reject) => {
230
+ const child = (0, child_process_1.spawn)('npm', ['link', 'archetype-engine'], {
231
+ cwd: targetDir,
232
+ stdio: 'pipe',
233
+ });
234
+ child.on('close', (code) => {
235
+ if (code === 0) {
236
+ resolve();
237
+ }
238
+ else {
239
+ // Non-fatal - user can manually run npm link
240
+ resolve();
241
+ }
242
+ });
243
+ child.on('error', () => {
244
+ // Non-fatal
245
+ resolve();
246
+ });
247
+ });
248
+ }
249
+ var dependencies_2 = require("./dependencies");
250
+ Object.defineProperty(exports, "getRecommendedConfig", { enumerable: true, get: function () { return dependencies_2.getRecommendedConfig; } });
@@ -0,0 +1,11 @@
1
+ import type { InitConfig } from './dependencies';
2
+ export declare function runPrompts(): Promise<InitConfig | null>;
3
+ export declare function displayConfigSummary(config: InitConfig): void;
4
+ export declare function displaySuccess(config: InitConfig): void;
5
+ export declare function displayError(message: string): void;
6
+ export declare function createSpinner(): {
7
+ start: (msg?: string) => void;
8
+ stop: (msg?: string, code?: number) => void;
9
+ message: (msg?: string) => void;
10
+ };
11
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/init/prompts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA0B,UAAU,EAAgB,MAAM,gBAAgB,CAAA;AAGtF,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA6L7D;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAyB7D;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CA8CvD;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAGD,wBAAgB,aAAa;eA5IjB,CAAC;cACW,CAAC,cAGrB,CAAD;iBACG,CAAC;EAyIN"}
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ // TUI prompts for archetype init
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.runPrompts = runPrompts;
38
+ exports.displayConfigSummary = displayConfigSummary;
39
+ exports.displaySuccess = displaySuccess;
40
+ exports.displayError = displayError;
41
+ exports.createSpinner = createSpinner;
42
+ const p = __importStar(require("@clack/prompts"));
43
+ const registry_1 = require("../template/registry");
44
+ async function runPrompts() {
45
+ p.intro('Welcome to Archetype!');
46
+ // Get available templates from registry
47
+ const templates = (0, registry_1.listTemplates)();
48
+ if (templates.length === 0) {
49
+ p.cancel('No templates available.');
50
+ return null;
51
+ }
52
+ // First, ask which template to use
53
+ const template = await p.select({
54
+ message: 'Which template would you like to use?',
55
+ options: templates.map(t => ({
56
+ value: t.id,
57
+ label: t.name,
58
+ hint: t.description,
59
+ })),
60
+ });
61
+ if (p.isCancel(template)) {
62
+ p.cancel('Setup cancelled.');
63
+ return null;
64
+ }
65
+ // Ask for mode (full or headless)
66
+ const mode = await p.select({
67
+ message: 'What type of project are you building?',
68
+ options: [
69
+ { value: 'full', label: 'Full Stack', hint: 'Local database with Drizzle ORM' },
70
+ { value: 'headless', label: 'Headless', hint: 'External APIs, no local database' },
71
+ ],
72
+ });
73
+ if (p.isCancel(mode)) {
74
+ p.cancel('Setup cancelled.');
75
+ return null;
76
+ }
77
+ let database;
78
+ let externalApiUrl;
79
+ if (mode === 'full') {
80
+ // Full mode: ask for database
81
+ const dbChoice = await p.select({
82
+ message: 'Which database would you like to use?',
83
+ options: [
84
+ { value: 'sqlite', label: 'SQLite', hint: 'Simple, file-based, great for development' },
85
+ { value: 'postgres', label: 'PostgreSQL', hint: 'Production-ready, full-featured' },
86
+ { value: 'mysql', label: 'MySQL', hint: 'Widely used, good performance' },
87
+ ],
88
+ });
89
+ if (p.isCancel(dbChoice)) {
90
+ p.cancel('Setup cancelled.');
91
+ return null;
92
+ }
93
+ database = dbChoice;
94
+ }
95
+ else {
96
+ // Headless mode: ask for API URL (optional)
97
+ const apiUrl = await p.text({
98
+ message: 'External API base URL (or env variable like env:API_URL):',
99
+ placeholder: 'env:API_URL',
100
+ defaultValue: 'env:API_URL',
101
+ });
102
+ if (p.isCancel(apiUrl)) {
103
+ p.cancel('Setup cancelled.');
104
+ return null;
105
+ }
106
+ externalApiUrl = apiUrl;
107
+ }
108
+ const auth = await p.confirm({
109
+ message: 'Do you want to include authentication (next-auth)?',
110
+ initialValue: false,
111
+ });
112
+ if (p.isCancel(auth)) {
113
+ p.cancel('Setup cancelled.');
114
+ return null;
115
+ }
116
+ let authProviders;
117
+ if (auth) {
118
+ const providers = await p.multiselect({
119
+ message: 'Select authentication providers:',
120
+ options: [
121
+ { value: 'credentials', label: 'Credentials', hint: 'Email/password login' },
122
+ { value: 'google', label: 'Google', hint: 'OAuth with Google' },
123
+ { value: 'github', label: 'GitHub', hint: 'OAuth with GitHub' },
124
+ { value: 'discord', label: 'Discord', hint: 'OAuth with Discord' },
125
+ ],
126
+ required: true,
127
+ initialValues: ['credentials'],
128
+ });
129
+ if (p.isCancel(providers)) {
130
+ p.cancel('Setup cancelled.');
131
+ return null;
132
+ }
133
+ authProviders = providers;
134
+ }
135
+ const wantI18n = await p.confirm({
136
+ message: 'Do you want internationalization (i18n) support?',
137
+ initialValue: false,
138
+ });
139
+ if (p.isCancel(wantI18n)) {
140
+ p.cancel('Setup cancelled.');
141
+ return null;
142
+ }
143
+ let i18n = null;
144
+ if (wantI18n) {
145
+ const languages = await p.multiselect({
146
+ message: 'Select languages to support:',
147
+ options: [
148
+ { value: 'en', label: 'English', hint: 'Default' },
149
+ { value: 'es', label: 'Spanish' },
150
+ { value: 'fr', label: 'French' },
151
+ { value: 'de', label: 'German' },
152
+ { value: 'pt', label: 'Portuguese' },
153
+ { value: 'zh', label: 'Chinese' },
154
+ { value: 'ja', label: 'Japanese' },
155
+ { value: 'ko', label: 'Korean' },
156
+ ],
157
+ required: true,
158
+ initialValues: ['en'],
159
+ });
160
+ if (p.isCancel(languages)) {
161
+ p.cancel('Setup cancelled.');
162
+ return null;
163
+ }
164
+ i18n = languages;
165
+ }
166
+ const includeExamples = await p.confirm({
167
+ message: 'Would you like to start with example entities?',
168
+ initialValue: true,
169
+ });
170
+ if (p.isCancel(includeExamples)) {
171
+ p.cancel('Setup cancelled.');
172
+ return null;
173
+ }
174
+ let entityTemplateChoice;
175
+ if (includeExamples) {
176
+ const templateChoice = await p.select({
177
+ message: 'Choose a starter template:',
178
+ options: [
179
+ { value: 'simple', label: 'Simple (Task)', hint: 'Single entity to get started' },
180
+ { value: 'saas', label: 'SaaS Multi-Tenant', hint: 'Workspace, Team, Member' },
181
+ { value: 'ecommerce', label: 'E-commerce', hint: 'Product, Order, Customer' },
182
+ { value: 'blog', label: 'Blog/CMS', hint: 'Post, Author, Comment' },
183
+ { value: 'task', label: 'Task Management', hint: 'Project, Task, Label' },
184
+ ],
185
+ });
186
+ if (p.isCancel(templateChoice)) {
187
+ p.cancel('Setup cancelled.');
188
+ return null;
189
+ }
190
+ entityTemplateChoice = templateChoice;
191
+ }
192
+ return {
193
+ template: template,
194
+ mode: mode,
195
+ database,
196
+ externalApiUrl,
197
+ auth: auth,
198
+ authProviders,
199
+ i18n,
200
+ includeExamples: includeExamples,
201
+ entityTemplate: entityTemplateChoice,
202
+ };
203
+ }
204
+ // Display the configuration summary
205
+ function displayConfigSummary(config) {
206
+ const lines = [
207
+ `Template: ${config.template}`,
208
+ `Mode: ${config.mode === 'headless' ? 'Headless (external APIs)' : 'Full Stack (local DB)'}`,
209
+ ];
210
+ if (config.mode === 'full' && config.database) {
211
+ lines.push(`Database: ${config.database}`);
212
+ }
213
+ if (config.mode === 'headless' && config.externalApiUrl) {
214
+ lines.push(`API URL: ${config.externalApiUrl}`);
215
+ }
216
+ const authDisplay = config.auth
217
+ ? `Yes (${config.authProviders?.join(', ') || 'credentials'})`
218
+ : 'No';
219
+ lines.push(`Authentication: ${authDisplay}`, `Internationalization: ${config.i18n ? config.i18n.join(', ') : 'No'}`, `Example entities: ${config.includeExamples ? 'Yes' : 'No'}`);
220
+ p.note(lines.join('\n'), 'Configuration');
221
+ }
222
+ // Display success message and next steps
223
+ function displaySuccess(config) {
224
+ const authNote = config.auth
225
+ ? `\n\nšŸ“§ Auth setup:\n - Copy .env.example to .env.local\n - Add your OAuth credentials (if using Google/GitHub/Discord)\n - Generate auth secret: npx auth secret`
226
+ : '';
227
+ const templateNote = config.entityTemplate && config.entityTemplate !== 'simple'
228
+ ? `\n\nšŸ“¦ Starter template: ${config.entityTemplate}\n - Check archetype/entities/ for pre-built entities\n - Customize them to fit your needs`
229
+ : '';
230
+ if (config.mode === 'headless') {
231
+ p.outro(`āœ… Archetype initialized in headless mode!
232
+
233
+ šŸ“ Next steps:
234
+ 1. npx archetype generate # Generate code from entities
235
+ 2. npm run dev # Start development server
236
+
237
+ šŸ’” Tips:
238
+ - Add more entities in archetype/entities/
239
+ - Run 'npx archetype generate' after changes
240
+ - View ERD: 'npx archetype view'
241
+
242
+ Note: No database setup needed - entities will use external APIs.${authNote}${templateNote}
243
+
244
+ šŸ“š Docs: https://archetype-engine.dev/docs
245
+ šŸ› Issues: https://github.com/yourusername/archetype-engine/issues`);
246
+ }
247
+ else {
248
+ const dbCommand = config.database === 'sqlite'
249
+ ? 'npx drizzle-kit push'
250
+ : 'npx drizzle-kit push # Make sure DATABASE_URL is set in .env.local';
251
+ p.outro(`āœ… Archetype initialized!
252
+
253
+ šŸ“ Next steps:
254
+ 1. npx archetype generate # Generate code from entities
255
+ 2. ${dbCommand} # Create database tables
256
+ 3. npm run dev # Start development server
257
+
258
+ šŸ’” Tips:
259
+ - Add more entities in archetype/entities/
260
+ - Run 'npx archetype generate' after entity changes
261
+ - View ERD: 'npx archetype view'
262
+ - Open Drizzle Studio: 'npm run db:studio'${authNote}${templateNote}
263
+
264
+ šŸ“š Docs: https://archetype-engine.dev/docs
265
+ šŸ› Issues: https://github.com/yourusername/archetype-engine/issues`);
266
+ }
267
+ }
268
+ // Display error
269
+ function displayError(message) {
270
+ p.cancel(message);
271
+ }
272
+ // Create a spinner
273
+ function createSpinner() {
274
+ return p.spinner();
275
+ }
@@ -0,0 +1,24 @@
1
+ import type { InitConfig, DatabaseType } from './dependencies';
2
+ export declare function getConfigTemplate(config: InitConfig): string;
3
+ export declare function getTaskEntityTemplate(): string;
4
+ export declare function getProductEntityTemplate(): string;
5
+ export declare function getDbTemplate(database: DatabaseType): string;
6
+ export declare function getTrpcServerTemplate(config: InitConfig): string;
7
+ export declare function getTrpcClientTemplate(): string;
8
+ export declare function getProvidersTemplate(): string;
9
+ export declare function getApiRouteTemplate(config: InitConfig): string;
10
+ export declare function getDrizzleConfigTemplate(database: DatabaseType): string;
11
+ export declare function getAuthTemplate(config: InitConfig): string;
12
+ export declare function getAuthRouteTemplate(): string;
13
+ export declare function getEnvExampleTemplate(config: InitConfig): string;
14
+ export declare function getGitignoreTemplate(): string;
15
+ export interface TemplateFile {
16
+ path: string;
17
+ content: string;
18
+ }
19
+ export interface ProjectStructure {
20
+ useSrcDir: boolean;
21
+ }
22
+ export declare function getAllTemplateFiles(config: InitConfig, structure: ProjectStructure): TemplateFile[];
23
+ export declare function getPackageJsonScripts(config: InitConfig): Record<string, string>;
24
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/init/templates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAI9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA2G5D;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAe9C;AAGD,wBAAgB,wBAAwB,IAAI,MAAM,CAejD;AAGD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CA2B5D;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAyGhE;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAyB7C;AAGD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAgC9D;AAGD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAsBvE;AAGD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA6E1D;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAkChE;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CA6B7C;AAGD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAmFnG;AAGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAahF"}