create-stackr 0.2.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 (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +642 -0
  3. package/bin/cli.js +12 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +113 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config/dependencies.d.ts +82 -0
  9. package/dist/config/dependencies.d.ts.map +1 -0
  10. package/dist/config/dependencies.js +82 -0
  11. package/dist/config/dependencies.js.map +1 -0
  12. package/dist/config/presets.d.ts +3 -0
  13. package/dist/config/presets.d.ts.map +1 -0
  14. package/dist/config/presets.js +174 -0
  15. package/dist/config/presets.js.map +1 -0
  16. package/dist/generators/index.d.ts +40 -0
  17. package/dist/generators/index.d.ts.map +1 -0
  18. package/dist/generators/index.js +130 -0
  19. package/dist/generators/index.js.map +1 -0
  20. package/dist/generators/onboarding.d.ts +8 -0
  21. package/dist/generators/onboarding.d.ts.map +1 -0
  22. package/dist/generators/onboarding.js +141 -0
  23. package/dist/generators/onboarding.js.map +1 -0
  24. package/dist/index.d.ts +3 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +65 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/prompts/features.d.ts +14 -0
  29. package/dist/prompts/features.d.ts.map +1 -0
  30. package/dist/prompts/features.js +96 -0
  31. package/dist/prompts/features.js.map +1 -0
  32. package/dist/prompts/index.d.ts +3 -0
  33. package/dist/prompts/index.d.ts.map +1 -0
  34. package/dist/prompts/index.js +93 -0
  35. package/dist/prompts/index.js.map +1 -0
  36. package/dist/prompts/onboarding.d.ts +6 -0
  37. package/dist/prompts/onboarding.d.ts.map +1 -0
  38. package/dist/prompts/onboarding.js +37 -0
  39. package/dist/prompts/onboarding.js.map +1 -0
  40. package/dist/prompts/orm.d.ts +3 -0
  41. package/dist/prompts/orm.d.ts.map +1 -0
  42. package/dist/prompts/orm.js +23 -0
  43. package/dist/prompts/orm.js.map +1 -0
  44. package/dist/prompts/packageManager.d.ts +2 -0
  45. package/dist/prompts/packageManager.d.ts.map +1 -0
  46. package/dist/prompts/packageManager.js +18 -0
  47. package/dist/prompts/packageManager.js.map +1 -0
  48. package/dist/prompts/platform.d.ts +3 -0
  49. package/dist/prompts/platform.d.ts.map +1 -0
  50. package/dist/prompts/platform.js +21 -0
  51. package/dist/prompts/platform.js.map +1 -0
  52. package/dist/prompts/preset.d.ts +4 -0
  53. package/dist/prompts/preset.d.ts.map +1 -0
  54. package/dist/prompts/preset.js +165 -0
  55. package/dist/prompts/preset.js.map +1 -0
  56. package/dist/prompts/project.d.ts +2 -0
  57. package/dist/prompts/project.d.ts.map +1 -0
  58. package/dist/prompts/project.js +27 -0
  59. package/dist/prompts/project.js.map +1 -0
  60. package/dist/prompts/sdks.d.ts +2 -0
  61. package/dist/prompts/sdks.d.ts.map +1 -0
  62. package/dist/prompts/sdks.js +46 -0
  63. package/dist/prompts/sdks.js.map +1 -0
  64. package/dist/types/index.d.ts +77 -0
  65. package/dist/types/index.d.ts.map +1 -0
  66. package/dist/types/index.js +25 -0
  67. package/dist/types/index.js.map +1 -0
  68. package/dist/utils/cleanup.d.ts +5 -0
  69. package/dist/utils/cleanup.d.ts.map +1 -0
  70. package/dist/utils/cleanup.js +38 -0
  71. package/dist/utils/cleanup.js.map +1 -0
  72. package/dist/utils/copy.d.ts +10 -0
  73. package/dist/utils/copy.d.ts.map +1 -0
  74. package/dist/utils/copy.js +53 -0
  75. package/dist/utils/copy.js.map +1 -0
  76. package/dist/utils/errors.d.ts +33 -0
  77. package/dist/utils/errors.d.ts.map +1 -0
  78. package/dist/utils/errors.js +136 -0
  79. package/dist/utils/errors.js.map +1 -0
  80. package/dist/utils/git.d.ts +5 -0
  81. package/dist/utils/git.d.ts.map +1 -0
  82. package/dist/utils/git.js +33 -0
  83. package/dist/utils/git.js.map +1 -0
  84. package/dist/utils/logger.d.ts +9 -0
  85. package/dist/utils/logger.d.ts.map +1 -0
  86. package/dist/utils/logger.js +22 -0
  87. package/dist/utils/logger.js.map +1 -0
  88. package/dist/utils/package.d.ts +16 -0
  89. package/dist/utils/package.d.ts.map +1 -0
  90. package/dist/utils/package.js +86 -0
  91. package/dist/utils/package.js.map +1 -0
  92. package/dist/utils/system-validation.d.ts +9 -0
  93. package/dist/utils/system-validation.d.ts.map +1 -0
  94. package/dist/utils/system-validation.js +31 -0
  95. package/dist/utils/system-validation.js.map +1 -0
  96. package/dist/utils/template.d.ts +20 -0
  97. package/dist/utils/template.d.ts.map +1 -0
  98. package/dist/utils/template.js +234 -0
  99. package/dist/utils/template.js.map +1 -0
  100. package/dist/utils/validation.d.ts +8 -0
  101. package/dist/utils/validation.d.ts.map +1 -0
  102. package/dist/utils/validation.js +94 -0
  103. package/dist/utils/validation.js.map +1 -0
  104. package/package.json +96 -0
  105. package/templates/base/backend/.dockerignore.ejs +62 -0
  106. package/templates/base/backend/.env.example.ejs +116 -0
  107. package/templates/base/backend/Dockerfile.ejs +142 -0
  108. package/templates/base/backend/controllers/event-queue/index.ts +20 -0
  109. package/templates/base/backend/controllers/event-queue/workers/user.ts +39 -0
  110. package/templates/base/backend/controllers/rest-api/index.ts +48 -0
  111. package/templates/base/backend/controllers/rest-api/plugins/auth.ts +152 -0
  112. package/templates/base/backend/controllers/rest-api/plugins/config.ts +64 -0
  113. package/templates/base/backend/controllers/rest-api/plugins/error-handler.ts +118 -0
  114. package/templates/base/backend/controllers/rest-api/routes/auth.ts.ejs +180 -0
  115. package/templates/base/backend/controllers/rest-api/routes/device-sessions.ts +197 -0
  116. package/templates/base/backend/controllers/rest-api/routes/oauth-web.ts.ejs +375 -0
  117. package/templates/base/backend/controllers/rest-api/server.ts.ejs +87 -0
  118. package/templates/base/backend/domain/device-session/repository.drizzle.ts +209 -0
  119. package/templates/base/backend/domain/device-session/repository.prisma.ts +248 -0
  120. package/templates/base/backend/domain/device-session/schema.ts +72 -0
  121. package/templates/base/backend/domain/session/repository.drizzle.ts +72 -0
  122. package/templates/base/backend/domain/session/repository.prisma.ts +72 -0
  123. package/templates/base/backend/domain/session/schema.ts +29 -0
  124. package/templates/base/backend/domain/user/repository.drizzle.ts +127 -0
  125. package/templates/base/backend/domain/user/repository.prisma.ts +115 -0
  126. package/templates/base/backend/domain/user/schema.ts +14 -0
  127. package/templates/base/backend/drizzle/schema.drizzle.ts +111 -0
  128. package/templates/base/backend/drizzle.config.drizzle.ts +13 -0
  129. package/templates/base/backend/lib/auth.drizzle.ts.ejs +104 -0
  130. package/templates/base/backend/lib/auth.prisma.ts.ejs +97 -0
  131. package/templates/base/backend/lib/constants.ts.ejs +29 -0
  132. package/templates/base/backend/package.json.ejs +50 -0
  133. package/templates/base/backend/prisma/schema.prisma.ejs +102 -0
  134. package/templates/base/backend/prisma.config.prisma.ts +12 -0
  135. package/templates/base/backend/tsconfig.json +39 -0
  136. package/templates/base/backend/utils/db.drizzle.ts +41 -0
  137. package/templates/base/backend/utils/db.prisma.ts +51 -0
  138. package/templates/base/backend/utils/email.ts.ejs +35 -0
  139. package/templates/base/backend/utils/errors.ts +348 -0
  140. package/templates/base/backend/utils/redis.ts.ejs +279 -0
  141. package/templates/base/mobile/.env.example.ejs +35 -0
  142. package/templates/base/mobile/.gitignore.ejs +167 -0
  143. package/templates/base/mobile/app/+not-found.tsx +85 -0
  144. package/templates/base/mobile/app/_layout.tsx.ejs +71 -0
  145. package/templates/base/mobile/app.json.ejs +88 -0
  146. package/templates/base/mobile/assets/images/adaptive-icon.png +0 -0
  147. package/templates/base/mobile/assets/images/favicon.png +0 -0
  148. package/templates/base/mobile/assets/images/icon.png +0 -0
  149. package/templates/base/mobile/assets/images/onboarding_page_1.png +0 -0
  150. package/templates/base/mobile/assets/images/onboarding_page_2.png +0 -0
  151. package/templates/base/mobile/assets/images/onboarding_page_3.png +0 -0
  152. package/templates/base/mobile/assets/images/paywall_image.png +0 -0
  153. package/templates/base/mobile/assets/images/splash.png +0 -0
  154. package/templates/base/mobile/eas.json.ejs +49 -0
  155. package/templates/base/mobile/metro.config.js +9 -0
  156. package/templates/base/mobile/package.json.ejs +53 -0
  157. package/templates/base/mobile/src/components/ui/Button.tsx +131 -0
  158. package/templates/base/mobile/src/components/ui/Card.tsx +68 -0
  159. package/templates/base/mobile/src/components/ui/IconSymbol.tsx +90 -0
  160. package/templates/base/mobile/src/components/ui/Input.tsx +142 -0
  161. package/templates/base/mobile/src/components/ui/LoadingSpinner.tsx +98 -0
  162. package/templates/base/mobile/src/components/ui/OnboardingLayout.tsx +356 -0
  163. package/templates/base/mobile/src/components/ui/PaywallLayout.tsx +311 -0
  164. package/templates/base/mobile/src/components/ui/Skeleton.tsx +58 -0
  165. package/templates/base/mobile/src/components/ui/index.ts +6 -0
  166. package/templates/base/mobile/src/constants/Theme.ts +163 -0
  167. package/templates/base/mobile/src/context/ThemeContext.tsx +157 -0
  168. package/templates/base/mobile/src/lib/auth-client.ts.ejs +51 -0
  169. package/templates/base/mobile/src/services/api.ts.ejs +71 -0
  170. package/templates/base/mobile/src/services/errorService.ts +179 -0
  171. package/templates/base/mobile/src/services/sdkInitializer.ts.ejs +36 -0
  172. package/templates/base/mobile/src/store/index.ts.ejs +18 -0
  173. package/templates/base/mobile/src/store/ui.store.ts +100 -0
  174. package/templates/base/mobile/src/utils/formatters.ts +105 -0
  175. package/templates/base/mobile/src/utils/logger.ts +73 -0
  176. package/templates/base/mobile/src/utils/responsive.ts +234 -0
  177. package/templates/base/mobile/tsconfig.json +32 -0
  178. package/templates/base/web/.env.example.ejs +26 -0
  179. package/templates/base/web/components.json +22 -0
  180. package/templates/base/web/eslint.config.mjs +18 -0
  181. package/templates/base/web/next.config.ts +7 -0
  182. package/templates/base/web/package.json.ejs +35 -0
  183. package/templates/base/web/postcss.config.mjs +7 -0
  184. package/templates/base/web/public/.gitkeep +0 -0
  185. package/templates/base/web/public/file.svg +1 -0
  186. package/templates/base/web/public/globe.svg +1 -0
  187. package/templates/base/web/public/next.svg +1 -0
  188. package/templates/base/web/public/vercel.svg +1 -0
  189. package/templates/base/web/public/window.svg +1 -0
  190. package/templates/base/web/src/app/favicon.ico +0 -0
  191. package/templates/base/web/src/app/globals.css +152 -0
  192. package/templates/base/web/src/app/layout.tsx.ejs +54 -0
  193. package/templates/base/web/src/app/page.tsx.ejs +92 -0
  194. package/templates/base/web/src/components/auth/auth-hydrator.tsx.ejs +19 -0
  195. package/templates/base/web/src/components/auth/protected-route.tsx.ejs +109 -0
  196. package/templates/base/web/src/components/providers/device-session-setup.tsx.ejs +56 -0
  197. package/templates/base/web/src/components/providers/theme-provider.tsx +17 -0
  198. package/templates/base/web/src/components/theme-toggle.tsx +34 -0
  199. package/templates/base/web/src/components/ui/button.tsx +62 -0
  200. package/templates/base/web/src/components/ui/card.tsx +92 -0
  201. package/templates/base/web/src/components/ui/input.tsx +21 -0
  202. package/templates/base/web/src/components/ui/label.tsx +24 -0
  203. package/templates/base/web/src/components/ui/skeleton.tsx +13 -0
  204. package/templates/base/web/src/components/ui/spinner.tsx +20 -0
  205. package/templates/base/web/src/hooks/use-device-session.ts.ejs +40 -0
  206. package/templates/base/web/src/hooks/use-session.ts.ejs +56 -0
  207. package/templates/base/web/src/lib/auth/actions.ts.ejs +334 -0
  208. package/templates/base/web/src/lib/auth/config.ts.ejs +65 -0
  209. package/templates/base/web/src/lib/auth/cookies.ts.ejs +74 -0
  210. package/templates/base/web/src/lib/auth/index.ts.ejs +40 -0
  211. package/templates/base/web/src/lib/auth/oauth.ts.ejs +72 -0
  212. package/templates/base/web/src/lib/auth/pkce.ts.ejs +48 -0
  213. package/templates/base/web/src/lib/auth/sessions.ts.ejs +135 -0
  214. package/templates/base/web/src/lib/auth/user-agent.ts.ejs +47 -0
  215. package/templates/base/web/src/lib/device/actions.ts.ejs +148 -0
  216. package/templates/base/web/src/lib/device/id.ts.ejs +74 -0
  217. package/templates/base/web/src/lib/utils.ts +6 -0
  218. package/templates/base/web/src/proxy.ts.ejs +66 -0
  219. package/templates/base/web/src/store/auth.store.ts.ejs +89 -0
  220. package/templates/base/web/src/store/deviceSession.store.ts.ejs +141 -0
  221. package/templates/base/web/tsconfig.json +34 -0
  222. package/templates/features/mobile/auth/app/(auth)/_layout.tsx +16 -0
  223. package/templates/features/mobile/auth/app/(auth)/login.tsx +86 -0
  224. package/templates/features/mobile/auth/app/(auth)/register.tsx +86 -0
  225. package/templates/features/mobile/auth/components/auth/LoginForm.tsx.ejs +349 -0
  226. package/templates/features/mobile/auth/components/auth/RegisterForm.tsx.ejs +407 -0
  227. package/templates/features/mobile/auth/components/auth/index.ts +2 -0
  228. package/templates/features/mobile/auth/hooks/index.ts.ejs +1 -0
  229. package/templates/features/mobile/auth/hooks/useAuth.ts.ejs +367 -0
  230. package/templates/features/mobile/auth/services/deviceSession.ts +370 -0
  231. package/templates/features/mobile/auth/store/deviceSession.store.ts +326 -0
  232. package/templates/features/mobile/onboarding/app/(onboarding)/_layout.tsx.ejs +11 -0
  233. package/templates/features/mobile/onboarding/app/(onboarding)/page-1.tsx.ejs +52 -0
  234. package/templates/features/mobile/onboarding/app/(onboarding)/page-2.tsx.ejs +52 -0
  235. package/templates/features/mobile/onboarding/app/(onboarding)/page-3.tsx.ejs +60 -0
  236. package/templates/features/mobile/paywall/app/paywall.tsx +550 -0
  237. package/templates/features/mobile/tabs/app/(tabs)/_layout.tsx +26 -0
  238. package/templates/features/mobile/tabs/app/(tabs)/index.tsx +565 -0
  239. package/templates/features/web/.gitkeep +0 -0
  240. package/templates/features/web/auth/app/(app)/dashboard/dashboard-client.tsx.ejs +166 -0
  241. package/templates/features/web/auth/app/(app)/dashboard/page.tsx.ejs +24 -0
  242. package/templates/features/web/auth/app/(app)/layout.tsx.ejs +43 -0
  243. package/templates/features/web/auth/app/(app)/settings/sessions/page.tsx.ejs +29 -0
  244. package/templates/features/web/auth/app/(app)/settings/sessions/sessions-client.tsx.ejs +77 -0
  245. package/templates/features/web/auth/app/(auth)/forgot-password/page.tsx.ejs +127 -0
  246. package/templates/features/web/auth/app/(auth)/layout.tsx.ejs +32 -0
  247. package/templates/features/web/auth/app/(auth)/login/page.tsx.ejs +35 -0
  248. package/templates/features/web/auth/app/(auth)/register/page.tsx.ejs +19 -0
  249. package/templates/features/web/auth/app/(auth)/reset-password/page.tsx.ejs +40 -0
  250. package/templates/features/web/auth/app/(auth)/verify-email/page.tsx.ejs +198 -0
  251. package/templates/features/web/auth/app/auth/callback/route.ts.ejs +152 -0
  252. package/templates/features/web/auth/components/auth/login-form.tsx.ejs +100 -0
  253. package/templates/features/web/auth/components/auth/oauth-buttons.tsx.ejs +126 -0
  254. package/templates/features/web/auth/components/auth/password-reset-form.tsx.ejs +103 -0
  255. package/templates/features/web/auth/components/auth/register-form.tsx.ejs +139 -0
  256. package/templates/features/web/auth/components/settings/session-card.tsx.ejs +132 -0
  257. package/templates/integrations/mobile/adjust/services/adjustService.ts.ejs +163 -0
  258. package/templates/integrations/mobile/adjust/store/adjust.store.ts +243 -0
  259. package/templates/integrations/mobile/att/services/attService.ts +84 -0
  260. package/templates/integrations/mobile/att/services/trackingPermissions.ts +208 -0
  261. package/templates/integrations/mobile/att/store/att.store.ts +162 -0
  262. package/templates/integrations/mobile/revenuecat/services/revenuecatService.ts.ejs +174 -0
  263. package/templates/integrations/mobile/revenuecat/store/revenuecat.store.ts +286 -0
  264. package/templates/integrations/mobile/scate/services/scateService.ts.ejs +85 -0
  265. package/templates/integrations/mobile/scate/store/scate.store.ts +125 -0
  266. package/templates/integrations/web/.gitkeep +0 -0
  267. package/templates/shared/.env.example.ejs +21 -0
  268. package/templates/shared/.gitignore.ejs +145 -0
  269. package/templates/shared/README.md.ejs +134 -0
  270. package/templates/shared/docker-compose.prod.yml.ejs +120 -0
  271. package/templates/shared/docker-compose.yml.ejs +129 -0
  272. package/templates/shared/scripts/docker-dev.sh.ejs +395 -0
  273. package/templates/shared/scripts/docker-prod.sh.ejs +542 -0
  274. package/templates/shared/scripts/setup.sh.ejs +979 -0
@@ -0,0 +1,165 @@
1
+ import inquirer from 'inquirer';
2
+ import chalk from 'chalk';
3
+ import { PRESETS } from '../config/presets.js';
4
+ export async function selectPreset() {
5
+ const choices = [
6
+ ...PRESETS.map((preset) => ({
7
+ name: `${preset.icon} ${preset.name} - ${preset.description}`,
8
+ value: preset.name,
9
+ short: preset.name,
10
+ })),
11
+ {
12
+ name: '⚙️ Custom - Pick exactly what you need',
13
+ value: 'custom',
14
+ short: 'Custom',
15
+ },
16
+ ];
17
+ const { preset } = await inquirer.prompt([
18
+ {
19
+ type: 'list',
20
+ name: 'preset',
21
+ message: 'Choose a starting template:',
22
+ choices,
23
+ pageSize: 10,
24
+ },
25
+ ]);
26
+ // If custom, return null to trigger custom flow
27
+ if (preset === 'custom') {
28
+ return null;
29
+ }
30
+ // Load preset config
31
+ const selectedPreset = PRESETS.find((p) => p.name === preset);
32
+ if (!selectedPreset) {
33
+ throw new Error(`Preset not found: ${preset}`);
34
+ }
35
+ return selectedPreset.config;
36
+ }
37
+ export async function customizePreset(config) {
38
+ const { customize } = await inquirer.prompt([
39
+ {
40
+ type: 'confirm',
41
+ name: 'customize',
42
+ message: 'Do you want to customize this preset?',
43
+ default: false,
44
+ },
45
+ ]);
46
+ if (!customize) {
47
+ return config;
48
+ }
49
+ console.log(chalk.cyan('\n📝 Customize your preset:\n'));
50
+ // Show current configuration
51
+ displayPresetSummary(config);
52
+ // @ts-expect-error - inquirer types are too strict for our use case
53
+ const answers = await inquirer.prompt([
54
+ {
55
+ type: 'confirm',
56
+ name: 'onboarding',
57
+ message: 'Include onboarding flow?',
58
+ default: config.features.onboarding.enabled,
59
+ },
60
+ {
61
+ type: 'number',
62
+ name: 'onboardingPages',
63
+ message: 'How many onboarding pages? (1-5)',
64
+ default: config.features.onboarding.pages || 3,
65
+ when: (answers) => answers.onboarding,
66
+ validate: (input) => {
67
+ if (input < 1 || input > 5) {
68
+ return 'Please enter a number between 1 and 5';
69
+ }
70
+ return true;
71
+ },
72
+ },
73
+ {
74
+ type: 'confirm',
75
+ name: 'paywall',
76
+ message: 'Include subscription paywall?',
77
+ default: config.features.paywall,
78
+ },
79
+ {
80
+ type: 'confirm',
81
+ name: 'revenueCat',
82
+ message: 'Include RevenueCat (subscriptions)?',
83
+ default: config.integrations.revenueCat.enabled,
84
+ when: (answers) => answers.paywall,
85
+ },
86
+ {
87
+ type: 'confirm',
88
+ name: 'adjust',
89
+ message: 'Include Adjust (attribution)?',
90
+ default: config.integrations.adjust.enabled,
91
+ },
92
+ {
93
+ type: 'confirm',
94
+ name: 'scate',
95
+ message: 'Include Scate (engagement)?',
96
+ default: config.integrations.scate.enabled,
97
+ },
98
+ {
99
+ type: 'checkbox',
100
+ name: 'oauthProviders',
101
+ message: 'Select OAuth providers to enable:',
102
+ choices: [
103
+ { name: 'Google', value: 'google', checked: config.features.authentication.providers.google },
104
+ { name: 'Apple', value: 'apple', checked: config.features.authentication.providers.apple },
105
+ { name: 'GitHub', value: 'github', checked: config.features.authentication.providers.github },
106
+ ],
107
+ },
108
+ ]);
109
+ // Update config with answers
110
+ return {
111
+ ...config,
112
+ features: {
113
+ ...config.features,
114
+ onboarding: {
115
+ enabled: answers.onboarding,
116
+ pages: answers.onboardingPages || 3,
117
+ skipButton: config.features.onboarding.skipButton,
118
+ showPaywall: answers.paywall && answers.revenueCat,
119
+ },
120
+ authentication: {
121
+ ...config.features.authentication,
122
+ providers: {
123
+ emailPassword: true,
124
+ google: answers.oauthProviders?.includes('google') ?? config.features.authentication.providers.google,
125
+ apple: answers.oauthProviders?.includes('apple') ?? config.features.authentication.providers.apple,
126
+ github: answers.oauthProviders?.includes('github') ?? config.features.authentication.providers.github,
127
+ },
128
+ },
129
+ paywall: answers.paywall,
130
+ },
131
+ integrations: {
132
+ ...config.integrations,
133
+ revenueCat: {
134
+ ...config.integrations.revenueCat,
135
+ enabled: answers.revenueCat || false,
136
+ },
137
+ adjust: {
138
+ ...config.integrations.adjust,
139
+ enabled: answers.adjust,
140
+ },
141
+ scate: {
142
+ ...config.integrations.scate,
143
+ enabled: answers.scate,
144
+ },
145
+ att: {
146
+ ...config.integrations.att,
147
+ enabled: answers.adjust, // Auto-enable ATT with Adjust
148
+ },
149
+ },
150
+ customized: true,
151
+ };
152
+ }
153
+ function displayPresetSummary(config) {
154
+ console.log(chalk.gray('Current configuration:'));
155
+ console.log(chalk.gray(` • Onboarding: ${config.features.onboarding.enabled ? 'Yes' : 'No'}`));
156
+ console.log(chalk.gray(` • Paywall: ${config.features.paywall ? 'Yes' : 'No'}`));
157
+ console.log(chalk.gray(` • RevenueCat: ${config.integrations.revenueCat.enabled ? 'Yes' : 'No'}`));
158
+ console.log(chalk.gray(` • Adjust: ${config.integrations.adjust.enabled ? 'Yes' : 'No'}`));
159
+ console.log(chalk.gray(` • Scate: ${config.integrations.scate.enabled ? 'Yes' : 'No'}`));
160
+ console.log(chalk.gray(` • Google OAuth: ${config.features.authentication.providers.google ? 'Yes' : 'No'}`));
161
+ console.log(chalk.gray(` • Apple OAuth: ${config.features.authentication.providers.apple ? 'Yes' : 'No'}`));
162
+ console.log(chalk.gray(` • GitHub OAuth: ${config.features.authentication.providers.github ? 'Yes' : 'No'}`));
163
+ console.log();
164
+ }
165
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../../src/prompts/preset.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function promptProjectName(providedName: string | undefined): Promise<string>;
2
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/prompts/project.ts"],"names":[],"mappings":"AAEA,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
@@ -0,0 +1,27 @@
1
+ import inquirer from 'inquirer';
2
+ export async function promptProjectName(providedName) {
3
+ // If name was provided via CLI argument, use it
4
+ if (providedName) {
5
+ return providedName;
6
+ }
7
+ // Otherwise, prompt for it
8
+ const { projectName } = await inquirer.prompt([
9
+ {
10
+ type: 'input',
11
+ name: 'projectName',
12
+ message: 'What is your project name?',
13
+ default: 'my-fullstack-app',
14
+ validate: (input) => {
15
+ if (!input || input.trim().length === 0) {
16
+ return 'Project name cannot be empty';
17
+ }
18
+ if (!/^[a-z0-9-]+$/.test(input)) {
19
+ return 'Project name must contain only lowercase letters, numbers, and hyphens';
20
+ }
21
+ return true;
22
+ },
23
+ },
24
+ ]);
25
+ return projectName;
26
+ }
27
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/prompts/project.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,YAAgC;IAEhC,gDAAgD;IAChD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,2BAA2B;IAC3B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC5C;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,4BAA4B;YACrC,OAAO,EAAE,kBAAkB;YAC3B,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACxC,OAAO,8BAA8B,CAAC;gBACxC,CAAC;gBACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;oBAChC,OAAO,wEAAwE,CAAC;gBAClF,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;SACF;KACF,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function promptSDKs(): Promise<any>;
2
+ //# sourceMappingURL=sdks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdks.d.ts","sourceRoot":"","sources":["../../src/prompts/sdks.ts"],"names":[],"mappings":"AAEA,wBAAsB,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,CA6C/C"}
@@ -0,0 +1,46 @@
1
+ import inquirer from 'inquirer';
2
+ export async function promptSDKs() {
3
+ const answers = await inquirer.prompt([
4
+ {
5
+ type: 'checkbox',
6
+ name: 'sdks',
7
+ message: 'Which analytics/monetization SDKs do you want?',
8
+ choices: [
9
+ {
10
+ name: 'RevenueCat - In-app subscriptions & purchases',
11
+ value: 'revenueCat',
12
+ },
13
+ {
14
+ name: 'Adjust - Mobile attribution & analytics',
15
+ value: 'adjust',
16
+ },
17
+ {
18
+ name: 'Scate - User engagement & retention',
19
+ value: 'scate',
20
+ },
21
+ ],
22
+ },
23
+ ]);
24
+ // Auto-enable ATT if Adjust is selected
25
+ const attEnabled = answers.sdks.includes('adjust');
26
+ return {
27
+ revenueCat: {
28
+ enabled: answers.sdks.includes('revenueCat'),
29
+ iosKey: 'YOUR_IOS_API_KEY_HERE',
30
+ androidKey: 'YOUR_ANDROID_API_KEY_HERE',
31
+ },
32
+ adjust: {
33
+ enabled: answers.sdks.includes('adjust'),
34
+ appToken: 'YOUR_ADJUST_APP_TOKEN_HERE',
35
+ environment: 'sandbox',
36
+ },
37
+ scate: {
38
+ enabled: answers.sdks.includes('scate'),
39
+ apiKey: 'YOUR_SCATE_API_KEY_HERE',
40
+ },
41
+ att: {
42
+ enabled: attEnabled,
43
+ },
44
+ };
45
+ }
46
+ //# sourceMappingURL=sdks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdks.js","sourceRoot":"","sources":["../../src/prompts/sdks.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QACpC;YACE,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,gDAAgD;YACzD,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,+CAA+C;oBACrD,KAAK,EAAE,YAAY;iBACpB;gBACD;oBACE,IAAI,EAAE,yCAAyC;oBAC/C,KAAK,EAAE,QAAQ;iBAChB;gBACD;oBACE,IAAI,EAAE,qCAAqC;oBAC3C,KAAK,EAAE,OAAO;iBACf;aACF;SACF;KACF,CAAC,CAAC;IAEH,wCAAwC;IACxC,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEnD,OAAO;QACL,UAAU,EAAE;YACV,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;YAC5C,MAAM,EAAE,uBAAuB;YAC/B,UAAU,EAAE,2BAA2B;SACxC;QACD,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACxC,QAAQ,EAAE,4BAA4B;YACtC,WAAW,EAAE,SAAkB;SAChC;QACD,KAAK,EAAE;YACL,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YACvC,MAAM,EAAE,yBAAyB;SAClC;QACD,GAAG,EAAE;YACH,OAAO,EAAE,UAAU;SACpB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,77 @@
1
+ export type ORMChoice = 'prisma' | 'drizzle';
2
+ export type Platform = 'mobile' | 'web';
3
+ export interface ProjectConfig {
4
+ projectName: string;
5
+ packageManager: 'npm' | 'yarn' | 'bun';
6
+ appScheme: string;
7
+ platforms: Platform[];
8
+ features: {
9
+ onboarding: {
10
+ enabled: boolean;
11
+ pages: number;
12
+ skipButton: boolean;
13
+ showPaywall: boolean;
14
+ };
15
+ authentication: {
16
+ enabled: boolean;
17
+ providers: {
18
+ emailPassword: boolean;
19
+ google: boolean;
20
+ apple: boolean;
21
+ github: boolean;
22
+ };
23
+ emailVerification: boolean;
24
+ passwordReset: boolean;
25
+ twoFactor: boolean;
26
+ };
27
+ paywall: boolean;
28
+ sessionManagement: boolean;
29
+ };
30
+ integrations: {
31
+ revenueCat: {
32
+ enabled: boolean;
33
+ iosKey: string;
34
+ androidKey: string;
35
+ };
36
+ adjust: {
37
+ enabled: boolean;
38
+ appToken: string;
39
+ environment: 'sandbox' | 'production';
40
+ };
41
+ scate: {
42
+ enabled: boolean;
43
+ apiKey: string;
44
+ };
45
+ att: {
46
+ enabled: boolean;
47
+ };
48
+ };
49
+ backend: {
50
+ database: 'postgresql';
51
+ orm: ORMChoice;
52
+ eventQueue: boolean;
53
+ docker: boolean;
54
+ };
55
+ preset?: 'minimal' | 'full-featured' | 'analytics-focused' | 'custom';
56
+ customized: boolean;
57
+ }
58
+ export interface PresetDefinition {
59
+ name: string;
60
+ description: string;
61
+ icon: string;
62
+ config: Omit<ProjectConfig, 'projectName' | 'packageManager' | 'appScheme'>;
63
+ }
64
+ /**
65
+ * Derives a valid URL scheme from the project name
66
+ * - Converts to lowercase
67
+ * - Removes all non-alphanumeric characters
68
+ * - Ensures it starts with a letter (required by iOS/Android)
69
+ * - Falls back to "app" if result is empty
70
+ */
71
+ export declare function deriveAppScheme(projectName: string): string;
72
+ export interface CLIOptions {
73
+ template?: string;
74
+ defaults?: boolean;
75
+ verbose?: boolean;
76
+ }
77
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAG7C,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;AAExC,MAAM,WAAW,aAAa;IAE5B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAGvC,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,EAAE,QAAQ,EAAE,CAAC;IAGtB,QAAQ,EAAE;QACR,UAAU,EAAE;YACV,OAAO,EAAE,OAAO,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,OAAO,CAAC;YACpB,WAAW,EAAE,OAAO,CAAC;SACtB,CAAC;QACF,cAAc,EAAE;YACd,OAAO,EAAE,OAAO,CAAC;YACjB,SAAS,EAAE;gBACT,aAAa,EAAE,OAAO,CAAC;gBACvB,MAAM,EAAE,OAAO,CAAC;gBAChB,KAAK,EAAE,OAAO,CAAC;gBACf,MAAM,EAAE,OAAO,CAAC;aACjB,CAAC;YACF,iBAAiB,EAAE,OAAO,CAAC;YAC3B,aAAa,EAAE,OAAO,CAAC;YACvB,SAAS,EAAE,OAAO,CAAC;SACpB,CAAC;QACF,OAAO,EAAE,OAAO,CAAC;QACjB,iBAAiB,EAAE,OAAO,CAAC;KAC5B,CAAC;IAGF,YAAY,EAAE;QACZ,UAAU,EAAE;YACV,OAAO,EAAE,OAAO,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;YACf,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC;YACjB,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;SACvC,CAAC;QACF,KAAK,EAAE;YACL,OAAO,EAAE,OAAO,CAAC;YACjB,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;QACF,GAAG,EAAE;YACH,OAAO,EAAE,OAAO,CAAC;SAClB,CAAC;KACH,CAAC;IAGF,OAAO,EAAE;QACP,QAAQ,EAAE,YAAY,CAAC;QACvB,GAAG,EAAE,SAAS,CAAC;QACf,UAAU,EAAE,OAAO,CAAC;QACpB,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IAGF,MAAM,CAAC,EAAE,SAAS,GAAG,eAAe,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IACtE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,aAAa,GAAG,gBAAgB,GAAG,WAAW,CAAC,CAAC;CAC7E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAoB3D;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Derives a valid URL scheme from the project name
3
+ * - Converts to lowercase
4
+ * - Removes all non-alphanumeric characters
5
+ * - Ensures it starts with a letter (required by iOS/Android)
6
+ * - Falls back to "app" if result is empty
7
+ */
8
+ export function deriveAppScheme(projectName) {
9
+ // Handle undefined or empty project name
10
+ if (!projectName) {
11
+ return 'app';
12
+ }
13
+ // Remove non-alphanumeric characters and convert to lowercase
14
+ let scheme = projectName.toLowerCase().replace(/[^a-z0-9]/g, '');
15
+ // URL schemes must start with a letter
16
+ if (scheme && !/^[a-z]/.test(scheme)) {
17
+ scheme = 'app' + scheme;
18
+ }
19
+ // Fallback if empty
20
+ if (!scheme) {
21
+ scheme = 'app';
22
+ }
23
+ return scheme;
24
+ }
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAkFA;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,yCAAyC;IACzC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8DAA8D;IAC9D,IAAI,MAAM,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAEjE,uCAAuC;IACvC,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1B,CAAC;IAED,oBAAoB;IACpB,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Clean up partial project on error
3
+ */
4
+ export declare function cleanup(targetDir: string): Promise<void>;
5
+ //# sourceMappingURL=cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/utils/cleanup.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B9D"}
@@ -0,0 +1,38 @@
1
+ import fs from 'fs-extra';
2
+ import inquirer from 'inquirer';
3
+ import chalk from 'chalk';
4
+ /**
5
+ * Clean up partial project on error
6
+ */
7
+ export async function cleanup(targetDir) {
8
+ // Check if directory exists
9
+ if (!(await fs.pathExists(targetDir))) {
10
+ return; // Nothing to clean up
11
+ }
12
+ // Ask user if they want to clean up
13
+ const { shouldCleanup } = await inquirer.prompt([
14
+ {
15
+ type: 'confirm',
16
+ name: 'shouldCleanup',
17
+ message: 'Remove partially generated project?',
18
+ default: true,
19
+ },
20
+ ]);
21
+ if (shouldCleanup) {
22
+ console.log(chalk.yellow('\n🗑️ Cleaning up...\n'));
23
+ try {
24
+ // Remove the entire project directory
25
+ await fs.remove(targetDir);
26
+ console.log(chalk.green('✓ Cleanup complete'));
27
+ }
28
+ catch {
29
+ console.error(chalk.red('✗ Cleanup failed'));
30
+ console.log(chalk.yellow(`⚠️ Please manually remove: ${targetDir}`));
31
+ }
32
+ }
33
+ else {
34
+ console.log(chalk.yellow(`\n⚠️ Partial project left at: ${targetDir}`));
35
+ console.log(chalk.gray('You may need to manually clean up this directory\n'));
36
+ }
37
+ }
38
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/utils/cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB;IAC7C,4BAA4B;IAC5B,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,sBAAsB;IAChC,CAAC;IAED,oCAAoC;IACpC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC9C;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,qCAAqC;YAC9C,OAAO,EAAE,IAAI;SACd;KACF,CAAC,CAAC;IAEH,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAErD,IAAI,CAAC;YACH,sCAAsC;YACtC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+BAA+B,SAAS,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,kCAAkC,SAAS,EAAE,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ProjectConfig } from '../types/index.js';
2
+ /**
3
+ * Copy all template files to target directory
4
+ */
5
+ export declare function copyTemplateFiles(targetDir: string, config: ProjectConfig): Promise<void>;
6
+ /**
7
+ * Copy a single file or directory
8
+ */
9
+ export declare function copyFile(src: string, dest: string, config?: ProjectConfig): Promise<void>;
10
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/utils/copy.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,53 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import { globby } from 'globby';
4
+ import { TEMPLATE_DIR, renderTemplate, shouldIncludeFile, isTemplate, getDestinationPath, } from './template.js';
5
+ /**
6
+ * Copy all template files to target directory
7
+ */
8
+ export async function copyTemplateFiles(targetDir, config) {
9
+ // Get all files from templates directory
10
+ const files = await globby('**/*', {
11
+ cwd: TEMPLATE_DIR,
12
+ dot: true,
13
+ ignore: ['**/node_modules/**'],
14
+ });
15
+ for (const file of files) {
16
+ const fullPath = path.join(TEMPLATE_DIR, file);
17
+ const stats = await fs.stat(fullPath);
18
+ // Skip directories
19
+ if (stats.isDirectory()) {
20
+ continue;
21
+ }
22
+ // Check if file should be included
23
+ if (!shouldIncludeFile(file, config)) {
24
+ continue;
25
+ }
26
+ // Get destination path
27
+ const destPath = getDestinationPath(file, targetDir);
28
+ // Ensure destination directory exists
29
+ await fs.ensureDir(path.dirname(destPath));
30
+ // Process template or copy static file
31
+ if (isTemplate(file)) {
32
+ const rendered = await renderTemplate(file, config);
33
+ await fs.writeFile(destPath, rendered);
34
+ }
35
+ else {
36
+ await fs.copy(fullPath, destPath);
37
+ }
38
+ }
39
+ }
40
+ /**
41
+ * Copy a single file or directory
42
+ */
43
+ export async function copyFile(src, dest, config) {
44
+ await fs.ensureDir(path.dirname(dest));
45
+ if (config && isTemplate(src)) {
46
+ const rendered = await renderTemplate(src, config);
47
+ await fs.writeFile(dest, rendered);
48
+ }
49
+ else {
50
+ await fs.copy(src, dest);
51
+ }
52
+ }
53
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/utils/copy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,MAAqB;IAErB,yCAAyC;IACzC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE;QACjC,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtC,mBAAmB;QACnB,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YACrC,SAAS;QACX,CAAC;QAED,uBAAuB;QACvB,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAErD,sCAAsC;QACtC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE3C,uCAAuC;QACvC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACpD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,IAAY,EACZ,MAAsB;IAEtB,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEvC,IAAI,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ export declare class ProjectGenerationError extends Error {
2
+ readonly cause?: Error | undefined;
3
+ readonly hints?: string[] | undefined;
4
+ readonly recovery?: string[] | undefined;
5
+ constructor(message: string, cause?: Error | undefined, hints?: string[] | undefined, recovery?: string[] | undefined);
6
+ }
7
+ export declare function displayError(error: ProjectGenerationError | Error): void;
8
+ /**
9
+ * Common error scenarios with helpful messages
10
+ */
11
+ export declare const errors: {
12
+ directoryExists: (name: string) => ProjectGenerationError;
13
+ invalidProjectName: (name: string, reason: string) => ProjectGenerationError;
14
+ configValidationFailed: (errors: string[]) => ProjectGenerationError;
15
+ templateNotFound: (template: string) => ProjectGenerationError;
16
+ templateRenderFailed: (file: string, cause: Error) => ProjectGenerationError;
17
+ fileCopyFailed: (src: string, dest: string, cause: Error) => ProjectGenerationError;
18
+ dependencyInstallFailed: (packageManager: string, dir: string) => ProjectGenerationError;
19
+ gitInitFailed: (cause: Error) => ProjectGenerationError;
20
+ nodeVersionTooLow: (current: string, required: string) => ProjectGenerationError;
21
+ diskSpaceError: () => ProjectGenerationError;
22
+ networkError: (operation: string) => ProjectGenerationError;
23
+ packageManagerNotFound: (pm: string) => ProjectGenerationError;
24
+ };
25
+ /**
26
+ * Display a warning (non-fatal)
27
+ */
28
+ export declare function displayWarning(message: string, details?: string[]): void;
29
+ /**
30
+ * Display success message with box
31
+ */
32
+ export declare function displaySuccess(message: string, details?: string[]): void;
33
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAGA,qBAAa,sBAAuB,SAAQ,KAAK;aAG7B,KAAK,CAAC,EAAE,KAAK;aACb,KAAK,CAAC,EAAE,MAAM,EAAE;aAChB,QAAQ,CAAC,EAAE,MAAM,EAAE;gBAHnC,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,KAAK,YAAA,EACb,KAAK,CAAC,EAAE,MAAM,EAAE,YAAA,EAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAA;CAKtC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,sBAAsB,GAAG,KAAK,GAAG,IAAI,CA8BxE;AAED;;GAEG;AACH,eAAO,MAAM,MAAM;4BACO,MAAM;+BAWH,MAAM,UAAU,MAAM;qCAYhB,MAAM,EAAE;iCAQZ,MAAM;iCAcN,MAAM,SAAS,KAAK;0BAW3B,MAAM,QAAQ,MAAM,SAAS,KAAK;8CAWd,MAAM,OAAO,MAAM;2BAetC,KAAK;iCAWC,MAAM,YAAY,MAAM;;8BAoB3B,MAAM;iCAgBH,MAAM;CAapC,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAWxE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAgBxE"}