@voltro/cli 0.1.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 (626) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +57 -0
  3. package/README.md +26 -0
  4. package/SECURITY.md +56 -0
  5. package/THIRD-PARTY-NOTICES.md +20236 -0
  6. package/bin/voltro.mjs +43 -0
  7. package/dist/bin.d.ts +1 -0
  8. package/dist/bin.js +9 -0
  9. package/dist/commands-CfPH2Wf4.js +18061 -0
  10. package/dist/frameworkInspectState-CX2250XB.js +86 -0
  11. package/dist/index.d.ts +48 -0
  12. package/dist/index.js +5 -0
  13. package/dist/inspectState.d.ts +116 -0
  14. package/dist/inspectState.js +2 -0
  15. package/dist/startup.d.ts +26 -0
  16. package/dist/startup.js +2 -0
  17. package/dist/startupRunner-CRhuUl91.js +71 -0
  18. package/package.json +88 -0
  19. package/templates/AGENTS.core.md +258 -0
  20. package/templates/AGENTS.md +351 -0
  21. package/templates/agent-docs/_index.md +93 -0
  22. package/templates/agent-docs/_manifest.json +655 -0
  23. package/templates/agent-docs/ai.md +1845 -0
  24. package/templates/agent-docs/authentication.md +1788 -0
  25. package/templates/agent-docs/caching.md +624 -0
  26. package/templates/agent-docs/cli.md +1650 -0
  27. package/templates/agent-docs/configuration.md +295 -0
  28. package/templates/agent-docs/data.md +2172 -0
  29. package/templates/agent-docs/database/advancedqueries.md +1583 -0
  30. package/templates/agent-docs/database/columntypes.md +1200 -0
  31. package/templates/agent-docs/database/hosting.md +881 -0
  32. package/templates/agent-docs/database/migrations.md +2938 -0
  33. package/templates/agent-docs/database/misc.md +270 -0
  34. package/templates/agent-docs/database/overview.md +108 -0
  35. package/templates/agent-docs/database/querying.md +1622 -0
  36. package/templates/agent-docs/database/scaling.md +331 -0
  37. package/templates/agent-docs/database/schema.md +1458 -0
  38. package/templates/agent-docs/database/seedsdialects.md +1235 -0
  39. package/templates/agent-docs/database/transactions.md +285 -0
  40. package/templates/agent-docs/deployment.md +999 -0
  41. package/templates/agent-docs/internationalization.md +359 -0
  42. package/templates/agent-docs/introduction.md +438 -0
  43. package/templates/agent-docs/multi-tenancy.md +610 -0
  44. package/templates/agent-docs/observability.md +350 -0
  45. package/templates/agent-docs/plugins.md +1273 -0
  46. package/templates/agent-docs/reference.md +978 -0
  47. package/templates/agent-docs/routing.md +1553 -0
  48. package/templates/agent-docs/scheduling.md +666 -0
  49. package/templates/agent-docs/schema-driven-ui.md +607 -0
  50. package/templates/agent-docs/security.md +42 -0
  51. package/templates/agent-docs/templates/apibackends.md +3214 -0
  52. package/templates/agent-docs/templates/appshells.md +2062 -0
  53. package/templates/agent-docs/templates/custom.md +128 -0
  54. package/templates/agent-docs/templates/overview.md +122 -0
  55. package/templates/agent-docs/templates/serverless.md +315 -0
  56. package/templates/agent-docs/testing.md +376 -0
  57. package/templates/agent-docs/workflows.md +1351 -0
  58. package/templates/apps/api-ai/README.md +105 -0
  59. package/templates/apps/api-ai/actions/summarize.action.server.tsx +32 -0
  60. package/templates/apps/api-ai/actions/summarize.action.ts +33 -0
  61. package/templates/apps/api-ai/agents/support.agent.server.tsx +31 -0
  62. package/templates/apps/api-ai/agents/support.agent.tsx +27 -0
  63. package/templates/apps/api-ai/app.config.ts +57 -0
  64. package/templates/apps/api-ai/database/schema.ts +67 -0
  65. package/templates/apps/api-ai/package.json +27 -0
  66. package/templates/apps/api-ai/seeds/docs.seed.ts +67 -0
  67. package/templates/apps/api-ai/template.json +6 -0
  68. package/templates/apps/api-ai/tests/summarize.test.ts +50 -0
  69. package/templates/apps/api-ai/tools/searchDocs.tool.tsx +60 -0
  70. package/templates/apps/api-ai/tsconfig.json +5 -0
  71. package/templates/apps/api-auth/.env +17 -0
  72. package/templates/apps/api-auth/README.md +109 -0
  73. package/templates/apps/api-auth/actions/me.action.server.ts +20 -0
  74. package/templates/apps/api-auth/actions/me.action.ts +19 -0
  75. package/templates/apps/api-auth/app.config.ts +59 -0
  76. package/templates/apps/api-auth/database/schema.ts +26 -0
  77. package/templates/apps/api-auth/package.json +28 -0
  78. package/templates/apps/api-auth/template.json +6 -0
  79. package/templates/apps/api-auth/tests/me.test.ts +37 -0
  80. package/templates/apps/api-auth/tsconfig.json +5 -0
  81. package/templates/apps/api-backend/README.md +25 -0
  82. package/templates/apps/api-backend/app.config.ts +39 -0
  83. package/templates/apps/api-backend/database/schema.ts +57 -0
  84. package/templates/apps/api-backend/mutations/notes.create.mutation.server.ts +19 -0
  85. package/templates/apps/api-backend/mutations/notes.create.mutation.ts +37 -0
  86. package/templates/apps/api-backend/package.json +28 -0
  87. package/templates/apps/api-backend/queries/notes.query.server.ts +14 -0
  88. package/templates/apps/api-backend/queries/notes.query.ts +20 -0
  89. package/templates/apps/api-backend/template.json +6 -0
  90. package/templates/apps/api-backend/tests/notes.create.test.ts +50 -0
  91. package/templates/apps/api-backend/tsconfig.json +5 -0
  92. package/templates/apps/api-backend-deactivation/README.md +49 -0
  93. package/templates/apps/api-backend-deactivation/actions/users.get.action.server.ts +17 -0
  94. package/templates/apps/api-backend-deactivation/actions/users.get.action.ts +18 -0
  95. package/templates/apps/api-backend-deactivation/app.config.ts +20 -0
  96. package/templates/apps/api-backend-deactivation/database/schema.ts +41 -0
  97. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.server.ts +6 -0
  98. package/templates/apps/api-backend-deactivation/mutations/users.create.mutation.ts +16 -0
  99. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.server.ts +10 -0
  100. package/templates/apps/api-backend-deactivation/mutations/users.deactivate.mutation.ts +19 -0
  101. package/templates/apps/api-backend-deactivation/package.json +28 -0
  102. package/templates/apps/api-backend-deactivation/template.json +6 -0
  103. package/templates/apps/api-backend-deactivation/tests/users.deactivate.test.ts +47 -0
  104. package/templates/apps/api-backend-deactivation/tsconfig.json +5 -0
  105. package/templates/apps/api-backend-mail/README.md +39 -0
  106. package/templates/apps/api-backend-mail/actions/sendWelcome.action.server.ts +15 -0
  107. package/templates/apps/api-backend-mail/actions/sendWelcome.action.ts +21 -0
  108. package/templates/apps/api-backend-mail/app.config.ts +34 -0
  109. package/templates/apps/api-backend-mail/database/schema.ts +57 -0
  110. package/templates/apps/api-backend-mail/emails/welcome.email.tsx +106 -0
  111. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.server.ts +19 -0
  112. package/templates/apps/api-backend-mail/mutations/notes.create.mutation.ts +37 -0
  113. package/templates/apps/api-backend-mail/package.json +30 -0
  114. package/templates/apps/api-backend-mail/queries/notes.query.server.ts +14 -0
  115. package/templates/apps/api-backend-mail/queries/notes.query.ts +20 -0
  116. package/templates/apps/api-backend-mail/template.json +6 -0
  117. package/templates/apps/api-backend-mail/tests/notes.create.test.ts +50 -0
  118. package/templates/apps/api-backend-mail/tsconfig.json +5 -0
  119. package/templates/apps/api-backend-mariadb/.env.example +35 -0
  120. package/templates/apps/api-backend-mariadb/README.md +31 -0
  121. package/templates/apps/api-backend-mariadb/app.config.ts +68 -0
  122. package/templates/apps/api-backend-mariadb/database/schema.ts +57 -0
  123. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.server.ts +19 -0
  124. package/templates/apps/api-backend-mariadb/mutations/notes.create.mutation.ts +37 -0
  125. package/templates/apps/api-backend-mariadb/package.json +30 -0
  126. package/templates/apps/api-backend-mariadb/queries/notes.query.server.ts +14 -0
  127. package/templates/apps/api-backend-mariadb/queries/notes.query.ts +20 -0
  128. package/templates/apps/api-backend-mariadb/template.json +6 -0
  129. package/templates/apps/api-backend-mariadb/tests/notes.create.test.ts +50 -0
  130. package/templates/apps/api-backend-mariadb/tsconfig.json +5 -0
  131. package/templates/apps/api-backend-storage/README.md +86 -0
  132. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.server.ts +21 -0
  133. package/templates/apps/api-backend-storage/actions/uploadAvatar.action.ts +21 -0
  134. package/templates/apps/api-backend-storage/actions/uploadDocument.action.server.ts +21 -0
  135. package/templates/apps/api-backend-storage/actions/uploadDocument.action.ts +20 -0
  136. package/templates/apps/api-backend-storage/app.config.ts +38 -0
  137. package/templates/apps/api-backend-storage/database/schema.ts +57 -0
  138. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.server.ts +19 -0
  139. package/templates/apps/api-backend-storage/mutations/notes.create.mutation.ts +37 -0
  140. package/templates/apps/api-backend-storage/package.json +27 -0
  141. package/templates/apps/api-backend-storage/queries/notes.query.server.ts +14 -0
  142. package/templates/apps/api-backend-storage/queries/notes.query.ts +20 -0
  143. package/templates/apps/api-backend-storage/template.json +6 -0
  144. package/templates/apps/api-backend-storage/tests/notes.create.test.ts +50 -0
  145. package/templates/apps/api-backend-storage/tsconfig.json +5 -0
  146. package/templates/apps/api-data-advanced/.env +17 -0
  147. package/templates/apps/api-data-advanced/README.md +88 -0
  148. package/templates/apps/api-data-advanced/app.config.ts +56 -0
  149. package/templates/apps/api-data-advanced/database/actors.entity.ts +14 -0
  150. package/templates/apps/api-data-advanced/database/authors.entity.ts +30 -0
  151. package/templates/apps/api-data-advanced/database/authors.relations.ts +15 -0
  152. package/templates/apps/api-data-advanced/database/books.entity.ts +59 -0
  153. package/templates/apps/api-data-advanced/database/books.relations.ts +10 -0
  154. package/templates/apps/api-data-advanced/database/index.ts +23 -0
  155. package/templates/apps/api-data-advanced/database/tenants.entity.ts +11 -0
  156. package/templates/apps/api-data-advanced/package.json +28 -0
  157. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.server.ts +18 -0
  158. package/templates/apps/api-data-advanced/queries/authors.withBooks.query.ts +40 -0
  159. package/templates/apps/api-data-advanced/queries/books.search.query.server.ts +17 -0
  160. package/templates/apps/api-data-advanced/queries/books.search.query.ts +39 -0
  161. package/templates/apps/api-data-advanced/seeds/catalog.seed.ts +101 -0
  162. package/templates/apps/api-data-advanced/template.json +6 -0
  163. package/templates/apps/api-data-advanced/tests/queries.test.ts +124 -0
  164. package/templates/apps/api-data-advanced/tsconfig.json +5 -0
  165. package/templates/apps/api-durable/README.md +81 -0
  166. package/templates/apps/api-durable/aggregates/orderStats.aggregate.ts +49 -0
  167. package/templates/apps/api-durable/app.config.ts +41 -0
  168. package/templates/apps/api-durable/database/schema.ts +65 -0
  169. package/templates/apps/api-durable/mutations/orders.approve.mutation.server.ts +43 -0
  170. package/templates/apps/api-durable/mutations/orders.approve.mutation.ts +23 -0
  171. package/templates/apps/api-durable/mutations/orders.place.mutation.server.ts +45 -0
  172. package/templates/apps/api-durable/mutations/orders.place.mutation.ts +40 -0
  173. package/templates/apps/api-durable/package.json +28 -0
  174. package/templates/apps/api-durable/schedules/nightlyReport.cron.tsx +37 -0
  175. package/templates/apps/api-durable/startup/warm.startup.tsx +33 -0
  176. package/templates/apps/api-durable/subscribers/orderChanges.subscribe.ts +27 -0
  177. package/templates/apps/api-durable/template.json +6 -0
  178. package/templates/apps/api-durable/tests/orders.place.test.ts +91 -0
  179. package/templates/apps/api-durable/triggers/order.placed.trigger.tsx +21 -0
  180. package/templates/apps/api-durable/tsconfig.json +5 -0
  181. package/templates/apps/api-durable/workflows/order.fulfill.workflow.server.tsx +103 -0
  182. package/templates/apps/api-durable/workflows/order.fulfill.workflow.tsx +25 -0
  183. package/templates/apps/api-feature-flags/README.md +63 -0
  184. package/templates/apps/api-feature-flags/actions/notes.export.action.server.ts +11 -0
  185. package/templates/apps/api-feature-flags/actions/notes.export.action.ts +18 -0
  186. package/templates/apps/api-feature-flags/app.config.ts +41 -0
  187. package/templates/apps/api-feature-flags/database/schema.ts +37 -0
  188. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.server.ts +29 -0
  189. package/templates/apps/api-feature-flags/mutations/notes.create.mutation.ts +28 -0
  190. package/templates/apps/api-feature-flags/package.json +29 -0
  191. package/templates/apps/api-feature-flags/template.json +6 -0
  192. package/templates/apps/api-feature-flags/tests/notes.create.test.ts +67 -0
  193. package/templates/apps/api-feature-flags/tsconfig.json +5 -0
  194. package/templates/apps/api-governance/.env +4 -0
  195. package/templates/apps/api-governance/README.md +61 -0
  196. package/templates/apps/api-governance/actions/profiles.get.action.server.ts +17 -0
  197. package/templates/apps/api-governance/actions/profiles.get.action.ts +17 -0
  198. package/templates/apps/api-governance/app.config.ts +35 -0
  199. package/templates/apps/api-governance/database/schema.ts +41 -0
  200. package/templates/apps/api-governance/mutations/profiles.create.mutation.server.ts +17 -0
  201. package/templates/apps/api-governance/mutations/profiles.create.mutation.ts +21 -0
  202. package/templates/apps/api-governance/package.json +29 -0
  203. package/templates/apps/api-governance/template.json +6 -0
  204. package/templates/apps/api-governance/tests/profiles.create.test.ts +59 -0
  205. package/templates/apps/api-governance/tsconfig.json +5 -0
  206. package/templates/apps/api-kv/README.md +100 -0
  207. package/templates/apps/api-kv/actions/sync.pull.action.server.ts +75 -0
  208. package/templates/apps/api-kv/actions/sync.pull.action.ts +25 -0
  209. package/templates/apps/api-kv/actions/sync.reset.action.server.ts +25 -0
  210. package/templates/apps/api-kv/actions/sync.reset.action.ts +22 -0
  211. package/templates/apps/api-kv/actions/sync.status.action.server.ts +28 -0
  212. package/templates/apps/api-kv/actions/sync.status.action.ts +17 -0
  213. package/templates/apps/api-kv/app.config.ts +48 -0
  214. package/templates/apps/api-kv/database/schema.ts +62 -0
  215. package/templates/apps/api-kv/package.json +28 -0
  216. package/templates/apps/api-kv/queries/events.list.query.server.ts +14 -0
  217. package/templates/apps/api-kv/queries/events.list.query.ts +23 -0
  218. package/templates/apps/api-kv/template.json +6 -0
  219. package/templates/apps/api-kv/tests/sync.test.ts +103 -0
  220. package/templates/apps/api-kv/tsconfig.json +5 -0
  221. package/templates/apps/api-moderation/README.md +46 -0
  222. package/templates/apps/api-moderation/app.config.ts +33 -0
  223. package/templates/apps/api-moderation/database/schema.ts +45 -0
  224. package/templates/apps/api-moderation/mutations/comments.create.mutation.server.ts +8 -0
  225. package/templates/apps/api-moderation/mutations/comments.create.mutation.ts +20 -0
  226. package/templates/apps/api-moderation/mutations/posts.create.mutation.server.ts +9 -0
  227. package/templates/apps/api-moderation/mutations/posts.create.mutation.ts +25 -0
  228. package/templates/apps/api-moderation/package.json +29 -0
  229. package/templates/apps/api-moderation/template.json +6 -0
  230. package/templates/apps/api-moderation/tests/posts.create.test.ts +79 -0
  231. package/templates/apps/api-moderation/tsconfig.json +5 -0
  232. package/templates/apps/api-observability/README.md +106 -0
  233. package/templates/apps/api-observability/app.config.ts +32 -0
  234. package/templates/apps/api-observability/database/schema.ts +38 -0
  235. package/templates/apps/api-observability/mutations/notes.create.mutation.server.ts +33 -0
  236. package/templates/apps/api-observability/mutations/notes.create.mutation.ts +15 -0
  237. package/templates/apps/api-observability/package.json +29 -0
  238. package/templates/apps/api-observability/queries/notes.list.query.server.ts +7 -0
  239. package/templates/apps/api-observability/queries/notes.list.query.ts +14 -0
  240. package/templates/apps/api-observability/template.json +6 -0
  241. package/templates/apps/api-observability/tests/notes.create.test.ts +36 -0
  242. package/templates/apps/api-observability/tsconfig.json +5 -0
  243. package/templates/apps/api-ratelimit/README.md +49 -0
  244. package/templates/apps/api-ratelimit/app.config.ts +42 -0
  245. package/templates/apps/api-ratelimit/database/schema.ts +37 -0
  246. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.server.ts +16 -0
  247. package/templates/apps/api-ratelimit/mutations/notes.create.mutation.ts +34 -0
  248. package/templates/apps/api-ratelimit/package.json +29 -0
  249. package/templates/apps/api-ratelimit/template.json +6 -0
  250. package/templates/apps/api-ratelimit/tests/notes.create.test.ts +69 -0
  251. package/templates/apps/api-ratelimit/tsconfig.json +5 -0
  252. package/templates/apps/api-rbac/README.md +59 -0
  253. package/templates/apps/api-rbac/app.config.ts +48 -0
  254. package/templates/apps/api-rbac/database/schema.ts +37 -0
  255. package/templates/apps/api-rbac/mutations/notes.create.mutation.server.ts +22 -0
  256. package/templates/apps/api-rbac/mutations/notes.create.mutation.ts +26 -0
  257. package/templates/apps/api-rbac/package.json +29 -0
  258. package/templates/apps/api-rbac/template.json +6 -0
  259. package/templates/apps/api-rbac/tests/notes.create.test.ts +80 -0
  260. package/templates/apps/api-rbac/tsconfig.json +5 -0
  261. package/templates/apps/api-rest/README.md +85 -0
  262. package/templates/apps/api-rest/app.config.ts +70 -0
  263. package/templates/apps/api-rest/database/schema.ts +52 -0
  264. package/templates/apps/api-rest/lib/product.ts +30 -0
  265. package/templates/apps/api-rest/package.json +27 -0
  266. package/templates/apps/api-rest/routes/v1/products.create.route.tsx +45 -0
  267. package/templates/apps/api-rest/routes/v1/products.delete.route.tsx +25 -0
  268. package/templates/apps/api-rest/routes/v1/products.get.route.tsx +29 -0
  269. package/templates/apps/api-rest/routes/v1/products.list.route.tsx +43 -0
  270. package/templates/apps/api-rest/template.json +6 -0
  271. package/templates/apps/api-rest/tests/products.create.test.ts +53 -0
  272. package/templates/apps/api-rest/tsconfig.json +5 -0
  273. package/templates/apps/api-saas/README.md +106 -0
  274. package/templates/apps/api-saas/app.config.ts +51 -0
  275. package/templates/apps/api-saas/database/schema.ts +50 -0
  276. package/templates/apps/api-saas/mutations/projects.create.mutation.server.ts +52 -0
  277. package/templates/apps/api-saas/mutations/projects.create.mutation.ts +18 -0
  278. package/templates/apps/api-saas/package.json +31 -0
  279. package/templates/apps/api-saas/queries/projects.list.query.server.ts +7 -0
  280. package/templates/apps/api-saas/queries/projects.list.query.ts +18 -0
  281. package/templates/apps/api-saas/template.json +6 -0
  282. package/templates/apps/api-saas/tests/projects.create.test.ts +47 -0
  283. package/templates/apps/api-saas/tsconfig.json +5 -0
  284. package/templates/apps/api-search/README.md +68 -0
  285. package/templates/apps/api-search/app.config.ts +31 -0
  286. package/templates/apps/api-search/database/schema.ts +47 -0
  287. package/templates/apps/api-search/lib/search.ts +27 -0
  288. package/templates/apps/api-search/mutations/articles.create.mutation.server.ts +19 -0
  289. package/templates/apps/api-search/mutations/articles.create.mutation.ts +35 -0
  290. package/templates/apps/api-search/package.json +29 -0
  291. package/templates/apps/api-search/queries/articles.list.query.server.ts +14 -0
  292. package/templates/apps/api-search/queries/articles.list.query.ts +19 -0
  293. package/templates/apps/api-search/seeds/articles.seed.ts +41 -0
  294. package/templates/apps/api-search/startup/searchBackfill.startup.tsx +24 -0
  295. package/templates/apps/api-search/template.json +6 -0
  296. package/templates/apps/api-search/tests/articles.create.test.ts +69 -0
  297. package/templates/apps/api-search/tsconfig.json +5 -0
  298. package/templates/apps/api-versioning/README.md +51 -0
  299. package/templates/apps/api-versioning/actions/documents.asOf.action.server.ts +13 -0
  300. package/templates/apps/api-versioning/actions/documents.asOf.action.ts +14 -0
  301. package/templates/apps/api-versioning/actions/documents.history.action.server.ts +15 -0
  302. package/templates/apps/api-versioning/actions/documents.history.action.ts +17 -0
  303. package/templates/apps/api-versioning/app.config.ts +24 -0
  304. package/templates/apps/api-versioning/database/schema.ts +38 -0
  305. package/templates/apps/api-versioning/mutations/documents.create.mutation.server.ts +8 -0
  306. package/templates/apps/api-versioning/mutations/documents.create.mutation.ts +21 -0
  307. package/templates/apps/api-versioning/mutations/documents.update.mutation.server.ts +9 -0
  308. package/templates/apps/api-versioning/mutations/documents.update.mutation.ts +21 -0
  309. package/templates/apps/api-versioning/package.json +29 -0
  310. package/templates/apps/api-versioning/template.json +6 -0
  311. package/templates/apps/api-versioning/tests/documents.create.test.ts +37 -0
  312. package/templates/apps/api-versioning/tsconfig.json +5 -0
  313. package/templates/apps/api-webhooks/.env +6 -0
  314. package/templates/apps/api-webhooks/README.md +106 -0
  315. package/templates/apps/api-webhooks/app.config.ts +16 -0
  316. package/templates/apps/api-webhooks/database/schema.ts +49 -0
  317. package/templates/apps/api-webhooks/events/order.completed.webhook.tsx +22 -0
  318. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.server.ts +37 -0
  319. package/templates/apps/api-webhooks/mutations/orders.fulfill.mutation.ts +15 -0
  320. package/templates/apps/api-webhooks/package.json +28 -0
  321. package/templates/apps/api-webhooks/queries/orders.list.query.server.ts +7 -0
  322. package/templates/apps/api-webhooks/queries/orders.list.query.ts +15 -0
  323. package/templates/apps/api-webhooks/template.json +6 -0
  324. package/templates/apps/api-webhooks/tests/orders.fulfill.test.ts +51 -0
  325. package/templates/apps/api-webhooks/tsconfig.json +5 -0
  326. package/templates/apps/api-webhooks/webhooks/orders.webhook.tsx +35 -0
  327. package/templates/apps/changelog/README.md +77 -0
  328. package/templates/apps/changelog/app.config.ts +27 -0
  329. package/templates/apps/changelog/content/releases/0.1.0.mdx +19 -0
  330. package/templates/apps/changelog/content/releases/0.2.0.mdx +28 -0
  331. package/templates/apps/changelog/package.json +30 -0
  332. package/templates/apps/changelog/scripts/generate-rss.mjs +38 -0
  333. package/templates/apps/changelog/src/globals.css +66 -0
  334. package/templates/apps/changelog/src/globals.d.ts +16 -0
  335. package/templates/apps/changelog/src/lib/locale.test.ts +72 -0
  336. package/templates/apps/changelog/src/lib/locale.ts +55 -0
  337. package/templates/apps/changelog/src/lib/releases.ts +21 -0
  338. package/templates/apps/changelog/src/locales/de.ts +22 -0
  339. package/templates/apps/changelog/src/locales/en.ts +30 -0
  340. package/templates/apps/changelog/src/pages/[locale]/[slug].tsx +24 -0
  341. package/templates/apps/changelog/src/pages/[locale]/index.tsx +13 -0
  342. package/templates/apps/changelog/src/pages/[locale]/mirrors.test.tsx +95 -0
  343. package/templates/apps/changelog/src/pages/[slug].test.tsx +127 -0
  344. package/templates/apps/changelog/src/pages/[slug].tsx +52 -0
  345. package/templates/apps/changelog/src/pages/index.test.tsx +112 -0
  346. package/templates/apps/changelog/src/pages/index.tsx +55 -0
  347. package/templates/apps/changelog/src/pages/layout.tsx +84 -0
  348. package/templates/apps/changelog/template.json +6 -0
  349. package/templates/apps/changelog/tsconfig.json +11 -0
  350. package/templates/apps/edge-functions/README.md +55 -0
  351. package/templates/apps/edge-functions/functions/aiComplete.serverless.ts +58 -0
  352. package/templates/apps/edge-functions/functions/currencyConvert.serverless.ts +47 -0
  353. package/templates/apps/edge-functions/functions/geoGreeting.serverless.ts +44 -0
  354. package/templates/apps/edge-functions/functions/health.serverless.ts +29 -0
  355. package/templates/apps/edge-functions/functions/resolveLink.serverless.ts +32 -0
  356. package/templates/apps/edge-functions/functions/shareLink.serverless.ts +30 -0
  357. package/templates/apps/edge-functions/functions/slackNotify.serverless.ts +40 -0
  358. package/templates/apps/edge-functions/functions/verifySignature.serverless.ts +52 -0
  359. package/templates/apps/edge-functions/package.json +21 -0
  360. package/templates/apps/edge-functions/template.json +6 -0
  361. package/templates/apps/edge-functions/tsconfig.json +10 -0
  362. package/templates/apps/frontend-admin/README.md +40 -0
  363. package/templates/apps/frontend-admin/app.config.ts +37 -0
  364. package/templates/apps/frontend-admin/package.json +30 -0
  365. package/templates/apps/frontend-admin/src/config.ts +8 -0
  366. package/templates/apps/frontend-admin/src/globals.css +76 -0
  367. package/templates/apps/frontend-admin/src/globals.d.ts +6 -0
  368. package/templates/apps/frontend-admin/src/lib/admin.ts +16 -0
  369. package/templates/apps/frontend-admin/src/lib/auth.ts +24 -0
  370. package/templates/apps/frontend-admin/src/locales/de.ts +67 -0
  371. package/templates/apps/frontend-admin/src/locales/en.ts +79 -0
  372. package/templates/apps/frontend-admin/src/locales/index.ts +15 -0
  373. package/templates/apps/frontend-admin/src/pages/(marketing)/index.test.tsx +55 -0
  374. package/templates/apps/frontend-admin/src/pages/(marketing)/index.tsx +32 -0
  375. package/templates/apps/frontend-admin/src/pages/(marketing)/layout.tsx +29 -0
  376. package/templates/apps/frontend-admin/src/pages/(marketing)/login.test.tsx +73 -0
  377. package/templates/apps/frontend-admin/src/pages/(marketing)/login.tsx +35 -0
  378. package/templates/apps/frontend-admin/src/pages/admin/[entity].tsx +121 -0
  379. package/templates/apps/frontend-admin/src/pages/admin/entity.test.tsx +119 -0
  380. package/templates/apps/frontend-admin/src/pages/admin/error.tsx +20 -0
  381. package/templates/apps/frontend-admin/src/pages/admin/fallbacks.test.tsx +68 -0
  382. package/templates/apps/frontend-admin/src/pages/admin/index.test.tsx +88 -0
  383. package/templates/apps/frontend-admin/src/pages/admin/index.tsx +65 -0
  384. package/templates/apps/frontend-admin/src/pages/admin/layout.test.tsx +114 -0
  385. package/templates/apps/frontend-admin/src/pages/admin/layout.tsx +97 -0
  386. package/templates/apps/frontend-admin/src/pages/admin/loading.tsx +15 -0
  387. package/templates/apps/frontend-admin/src/pages/admin/not-found.tsx +15 -0
  388. package/templates/apps/frontend-admin/src/pages/layout.tsx +12 -0
  389. package/templates/apps/frontend-admin/src/pages/layouts.test.tsx +54 -0
  390. package/templates/apps/frontend-admin/template.json +6 -0
  391. package/templates/apps/frontend-admin/tsconfig.json +11 -0
  392. package/templates/apps/frontend-app/README.md +98 -0
  393. package/templates/apps/frontend-app/app.config.ts +43 -0
  394. package/templates/apps/frontend-app/package.json +30 -0
  395. package/templates/apps/frontend-app/src/locales/de.ts +36 -0
  396. package/templates/apps/frontend-app/src/locales/en.ts +43 -0
  397. package/templates/apps/frontend-app/src/locales/index.ts +15 -0
  398. package/templates/apps/frontend-app/src/pages/index.test.tsx +167 -0
  399. package/templates/apps/frontend-app/src/pages/index.tsx +136 -0
  400. package/templates/apps/frontend-app/src/pages/layout.tsx +41 -0
  401. package/templates/apps/frontend-app/src/pages/schema-ui.test.tsx +99 -0
  402. package/templates/apps/frontend-app/src/pages/schema-ui.tsx +74 -0
  403. package/templates/apps/frontend-app/template.json +6 -0
  404. package/templates/apps/frontend-app/tsconfig.json +11 -0
  405. package/templates/apps/frontend-blank/README.md +18 -0
  406. package/templates/apps/frontend-blank/app.config.ts +29 -0
  407. package/templates/apps/frontend-blank/package.json +29 -0
  408. package/templates/apps/frontend-blank/src/locales/de.ts +15 -0
  409. package/templates/apps/frontend-blank/src/locales/en.ts +22 -0
  410. package/templates/apps/frontend-blank/src/locales/index.ts +15 -0
  411. package/templates/apps/frontend-blank/src/pages/index.test.tsx +55 -0
  412. package/templates/apps/frontend-blank/src/pages/index.tsx +27 -0
  413. package/templates/apps/frontend-blank/src/pages/layout.test.tsx +54 -0
  414. package/templates/apps/frontend-blank/src/pages/layout.tsx +35 -0
  415. package/templates/apps/frontend-blank/template.json +6 -0
  416. package/templates/apps/frontend-blank/tsconfig.json +11 -0
  417. package/templates/apps/frontend-contact/README.md +65 -0
  418. package/templates/apps/frontend-contact/app.config.ts +25 -0
  419. package/templates/apps/frontend-contact/functions/sendMessage.serverless.ts +69 -0
  420. package/templates/apps/frontend-contact/package.json +33 -0
  421. package/templates/apps/frontend-contact/src/components/ContactForm.island.test.tsx +142 -0
  422. package/templates/apps/frontend-contact/src/components/ContactForm.island.tsx +104 -0
  423. package/templates/apps/frontend-contact/src/config.ts +12 -0
  424. package/templates/apps/frontend-contact/src/globals.css +84 -0
  425. package/templates/apps/frontend-contact/src/lib/locale.ts +55 -0
  426. package/templates/apps/frontend-contact/src/locales/de.ts +26 -0
  427. package/templates/apps/frontend-contact/src/locales/en.ts +29 -0
  428. package/templates/apps/frontend-contact/src/pages/[locale]/index.tsx +14 -0
  429. package/templates/apps/frontend-contact/src/pages/index.test.tsx +70 -0
  430. package/templates/apps/frontend-contact/src/pages/index.tsx +63 -0
  431. package/templates/apps/frontend-contact/src/pages/layout.tsx +65 -0
  432. package/templates/apps/frontend-contact/template.json +6 -0
  433. package/templates/apps/frontend-contact/tsconfig.json +11 -0
  434. package/templates/apps/frontend-dashboard/README.md +54 -0
  435. package/templates/apps/frontend-dashboard/app.config.ts +39 -0
  436. package/templates/apps/frontend-dashboard/package.json +29 -0
  437. package/templates/apps/frontend-dashboard/src/config.ts +8 -0
  438. package/templates/apps/frontend-dashboard/src/globals.css +72 -0
  439. package/templates/apps/frontend-dashboard/src/globals.d.ts +6 -0
  440. package/templates/apps/frontend-dashboard/src/lib/auth.ts +27 -0
  441. package/templates/apps/frontend-dashboard/src/locales/de.ts +49 -0
  442. package/templates/apps/frontend-dashboard/src/locales/en.ts +60 -0
  443. package/templates/apps/frontend-dashboard/src/locales/index.ts +15 -0
  444. package/templates/apps/frontend-dashboard/src/pages/(marketing)/index.test.tsx +55 -0
  445. package/templates/apps/frontend-dashboard/src/pages/(marketing)/index.tsx +34 -0
  446. package/templates/apps/frontend-dashboard/src/pages/(marketing)/layout.tsx +32 -0
  447. package/templates/apps/frontend-dashboard/src/pages/(marketing)/login.test.tsx +74 -0
  448. package/templates/apps/frontend-dashboard/src/pages/(marketing)/login.tsx +40 -0
  449. package/templates/apps/frontend-dashboard/src/pages/dashboard/error.tsx +21 -0
  450. package/templates/apps/frontend-dashboard/src/pages/dashboard/fallbacks.test.tsx +68 -0
  451. package/templates/apps/frontend-dashboard/src/pages/dashboard/index.test.tsx +55 -0
  452. package/templates/apps/frontend-dashboard/src/pages/dashboard/index.tsx +38 -0
  453. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.test.tsx +88 -0
  454. package/templates/apps/frontend-dashboard/src/pages/dashboard/layout.tsx +69 -0
  455. package/templates/apps/frontend-dashboard/src/pages/dashboard/loading.tsx +21 -0
  456. package/templates/apps/frontend-dashboard/src/pages/dashboard/not-found.tsx +19 -0
  457. package/templates/apps/frontend-dashboard/src/pages/dashboard/settings.test.tsx +69 -0
  458. package/templates/apps/frontend-dashboard/src/pages/dashboard/settings.tsx +35 -0
  459. package/templates/apps/frontend-dashboard/src/pages/layout.tsx +12 -0
  460. package/templates/apps/frontend-dashboard/src/pages/layouts.test.tsx +54 -0
  461. package/templates/apps/frontend-dashboard/template.json +6 -0
  462. package/templates/apps/frontend-dashboard/tsconfig.json +11 -0
  463. package/templates/apps/frontend-docs/README.md +19 -0
  464. package/templates/apps/frontend-docs/app.config.ts +25 -0
  465. package/templates/apps/frontend-docs/package.json +29 -0
  466. package/templates/apps/frontend-docs/src/globals.css +32 -0
  467. package/templates/apps/frontend-docs/src/lib/locale.test.ts +72 -0
  468. package/templates/apps/frontend-docs/src/lib/locale.ts +56 -0
  469. package/templates/apps/frontend-docs/src/locales/de.ts +24 -0
  470. package/templates/apps/frontend-docs/src/locales/en.ts +28 -0
  471. package/templates/apps/frontend-docs/src/pages/[locale]/docs/[...slug].tsx +18 -0
  472. package/templates/apps/frontend-docs/src/pages/[locale]/index.tsx +13 -0
  473. package/templates/apps/frontend-docs/src/pages/[locale]/mirrors.test.tsx +67 -0
  474. package/templates/apps/frontend-docs/src/pages/docs/[...slug].test.tsx +115 -0
  475. package/templates/apps/frontend-docs/src/pages/docs/[...slug].tsx +82 -0
  476. package/templates/apps/frontend-docs/src/pages/index.test.tsx +90 -0
  477. package/templates/apps/frontend-docs/src/pages/index.tsx +45 -0
  478. package/templates/apps/frontend-docs/src/pages/layout.test.tsx +84 -0
  479. package/templates/apps/frontend-docs/src/pages/layout.tsx +66 -0
  480. package/templates/apps/frontend-docs/template.json +6 -0
  481. package/templates/apps/frontend-docs/tsconfig.json +11 -0
  482. package/templates/apps/frontend-i18n/README.md +61 -0
  483. package/templates/apps/frontend-i18n/app.config.ts +33 -0
  484. package/templates/apps/frontend-i18n/package.json +28 -0
  485. package/templates/apps/frontend-i18n/src/globals.css +46 -0
  486. package/templates/apps/frontend-i18n/src/globals.d.ts +6 -0
  487. package/templates/apps/frontend-i18n/src/lib/locale.test.ts +72 -0
  488. package/templates/apps/frontend-i18n/src/lib/locale.ts +55 -0
  489. package/templates/apps/frontend-i18n/src/locales/de.ts +24 -0
  490. package/templates/apps/frontend-i18n/src/locales/en.ts +25 -0
  491. package/templates/apps/frontend-i18n/src/pages/[locale]/about.tsx +11 -0
  492. package/templates/apps/frontend-i18n/src/pages/[locale]/index.tsx +13 -0
  493. package/templates/apps/frontend-i18n/src/pages/[locale]/mirrors.test.tsx +50 -0
  494. package/templates/apps/frontend-i18n/src/pages/about.test.tsx +75 -0
  495. package/templates/apps/frontend-i18n/src/pages/about.tsx +31 -0
  496. package/templates/apps/frontend-i18n/src/pages/index.test.tsx +102 -0
  497. package/templates/apps/frontend-i18n/src/pages/index.tsx +43 -0
  498. package/templates/apps/frontend-i18n/src/pages/layout.test.tsx +86 -0
  499. package/templates/apps/frontend-i18n/src/pages/layout.tsx +70 -0
  500. package/templates/apps/frontend-i18n/template.json +6 -0
  501. package/templates/apps/frontend-i18n/tsconfig.json +11 -0
  502. package/templates/apps/frontend-landing/README.md +17 -0
  503. package/templates/apps/frontend-landing/app.config.ts +25 -0
  504. package/templates/apps/frontend-landing/package.json +29 -0
  505. package/templates/apps/frontend-landing/src/globals.css +23 -0
  506. package/templates/apps/frontend-landing/src/lib/locale.test.ts +72 -0
  507. package/templates/apps/frontend-landing/src/lib/locale.ts +55 -0
  508. package/templates/apps/frontend-landing/src/locales/de.ts +24 -0
  509. package/templates/apps/frontend-landing/src/locales/en.ts +26 -0
  510. package/templates/apps/frontend-landing/src/pages/[locale]/index.tsx +13 -0
  511. package/templates/apps/frontend-landing/src/pages/[locale]/mirrors.test.tsx +37 -0
  512. package/templates/apps/frontend-landing/src/pages/index.test.tsx +110 -0
  513. package/templates/apps/frontend-landing/src/pages/index.tsx +75 -0
  514. package/templates/apps/frontend-landing/src/pages/layout.test.tsx +84 -0
  515. package/templates/apps/frontend-landing/src/pages/layout.tsx +66 -0
  516. package/templates/apps/frontend-landing/template.json +6 -0
  517. package/templates/apps/frontend-landing/tsconfig.json +11 -0
  518. package/templates/apps/frontend-spa/README.md +45 -0
  519. package/templates/apps/frontend-spa/app.config.ts +27 -0
  520. package/templates/apps/frontend-spa/package.json +29 -0
  521. package/templates/apps/frontend-spa/src/globals.css +84 -0
  522. package/templates/apps/frontend-spa/src/locales/de.ts +22 -0
  523. package/templates/apps/frontend-spa/src/locales/en.ts +29 -0
  524. package/templates/apps/frontend-spa/src/locales/index.ts +15 -0
  525. package/templates/apps/frontend-spa/src/pages/index.test.tsx +137 -0
  526. package/templates/apps/frontend-spa/src/pages/index.tsx +123 -0
  527. package/templates/apps/frontend-spa/src/pages/layout.tsx +27 -0
  528. package/templates/apps/frontend-spa/template.json +6 -0
  529. package/templates/apps/frontend-spa/tsconfig.json +11 -0
  530. package/templates/apps/frontend-ssr/README.md +68 -0
  531. package/templates/apps/frontend-ssr/app.config.ts +32 -0
  532. package/templates/apps/frontend-ssr/package.json +29 -0
  533. package/templates/apps/frontend-ssr/src/globals.css +67 -0
  534. package/templates/apps/frontend-ssr/src/locales/de.ts +41 -0
  535. package/templates/apps/frontend-ssr/src/locales/en.ts +54 -0
  536. package/templates/apps/frontend-ssr/src/locales/index.ts +16 -0
  537. package/templates/apps/frontend-ssr/src/pages/feed-swr.test.tsx +69 -0
  538. package/templates/apps/frontend-ssr/src/pages/feed-swr.tsx +54 -0
  539. package/templates/apps/frontend-ssr/src/pages/feed.test.tsx +73 -0
  540. package/templates/apps/frontend-ssr/src/pages/feed.tsx +64 -0
  541. package/templates/apps/frontend-ssr/src/pages/index.test.tsx +89 -0
  542. package/templates/apps/frontend-ssr/src/pages/index.tsx +72 -0
  543. package/templates/apps/frontend-ssr/src/pages/layout.tsx +37 -0
  544. package/templates/apps/frontend-ssr/template.json +6 -0
  545. package/templates/apps/frontend-ssr/tsconfig.json +11 -0
  546. package/templates/apps/frontend-ssr-api/README.md +50 -0
  547. package/templates/apps/frontend-ssr-api/app.config.ts +43 -0
  548. package/templates/apps/frontend-ssr-api/package.json +30 -0
  549. package/templates/apps/frontend-ssr-api/src/globals.css +38 -0
  550. package/templates/apps/frontend-ssr-api/src/globals.d.ts +6 -0
  551. package/templates/apps/frontend-ssr-api/src/locales/de.ts +20 -0
  552. package/templates/apps/frontend-ssr-api/src/locales/en.ts +31 -0
  553. package/templates/apps/frontend-ssr-api/src/locales/index.ts +16 -0
  554. package/templates/apps/frontend-ssr-api/src/pages/index.test.tsx +105 -0
  555. package/templates/apps/frontend-ssr-api/src/pages/index.tsx +83 -0
  556. package/templates/apps/frontend-ssr-api/src/pages/layout.tsx +28 -0
  557. package/templates/apps/frontend-ssr-api/template.json +6 -0
  558. package/templates/apps/frontend-ssr-api/tsconfig.json +11 -0
  559. package/templates/apps/frontend-static-blog/README.md +49 -0
  560. package/templates/apps/frontend-static-blog/app.config.ts +34 -0
  561. package/templates/apps/frontend-static-blog/package.json +28 -0
  562. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.test.tsx +65 -0
  563. package/templates/apps/frontend-static-blog/src/components/ReadingProgress.island.tsx +35 -0
  564. package/templates/apps/frontend-static-blog/src/content/posts.ts +64 -0
  565. package/templates/apps/frontend-static-blog/src/globals.css +75 -0
  566. package/templates/apps/frontend-static-blog/src/lib/locale.test.ts +72 -0
  567. package/templates/apps/frontend-static-blog/src/lib/locale.ts +55 -0
  568. package/templates/apps/frontend-static-blog/src/locales/de.ts +19 -0
  569. package/templates/apps/frontend-static-blog/src/locales/en.ts +26 -0
  570. package/templates/apps/frontend-static-blog/src/pages/[locale]/blog/[slug].tsx +20 -0
  571. package/templates/apps/frontend-static-blog/src/pages/[locale]/index.tsx +13 -0
  572. package/templates/apps/frontend-static-blog/src/pages/[locale]/mirrors.test.tsx +62 -0
  573. package/templates/apps/frontend-static-blog/src/pages/blog/[slug].test.tsx +116 -0
  574. package/templates/apps/frontend-static-blog/src/pages/blog/[slug].tsx +69 -0
  575. package/templates/apps/frontend-static-blog/src/pages/index.test.tsx +100 -0
  576. package/templates/apps/frontend-static-blog/src/pages/index.tsx +58 -0
  577. package/templates/apps/frontend-static-blog/src/pages/layout.tsx +63 -0
  578. package/templates/apps/frontend-static-blog/template.json +6 -0
  579. package/templates/apps/frontend-static-blog/tsconfig.json +11 -0
  580. package/templates/baselines/bare/.env.example +37 -0
  581. package/templates/baselines/bare/README.md +47 -0
  582. package/templates/baselines/bare/baseline.json +31 -0
  583. package/templates/baselines/bare/deploy/README.md +43 -0
  584. package/templates/baselines/bare/deploy/voltro.service.example +36 -0
  585. package/templates/baselines/compose/.env.example +46 -0
  586. package/templates/baselines/compose/README.md +69 -0
  587. package/templates/baselines/compose/baseline.json +51 -0
  588. package/templates/baselines/compose/docker/.dockerignore +38 -0
  589. package/templates/baselines/compose/docker/api.Dockerfile +57 -0
  590. package/templates/baselines/compose/docker/dev.Dockerfile +35 -0
  591. package/templates/baselines/compose/docker/web.Dockerfile +59 -0
  592. package/templates/baselines/compose/docker-compose.dev.yml +89 -0
  593. package/templates/baselines/compose/docker-compose.prod.yml +87 -0
  594. package/templates/baselines/compose/docker-compose.yml +41 -0
  595. package/templates/baselines/compose-mariadb/.env.example +57 -0
  596. package/templates/baselines/compose-mariadb/README.md +78 -0
  597. package/templates/baselines/compose-mariadb/baseline.json +51 -0
  598. package/templates/baselines/compose-mariadb/docker/.dockerignore +38 -0
  599. package/templates/baselines/compose-mariadb/docker/api.Dockerfile +57 -0
  600. package/templates/baselines/compose-mariadb/docker/dev.Dockerfile +35 -0
  601. package/templates/baselines/compose-mariadb/docker/mariadb-init.sql +6 -0
  602. package/templates/baselines/compose-mariadb/docker/web.Dockerfile +59 -0
  603. package/templates/baselines/compose-mariadb/docker-compose.dev.yml +117 -0
  604. package/templates/baselines/compose-mariadb/docker-compose.prod.yml +114 -0
  605. package/templates/baselines/compose-mariadb/docker-compose.yml +79 -0
  606. package/templates/baselines/helm/.env.example +39 -0
  607. package/templates/baselines/helm/README.md +98 -0
  608. package/templates/baselines/helm/baseline.json +53 -0
  609. package/templates/baselines/helm/charts/voltro-app/.helmignore +10 -0
  610. package/templates/baselines/helm/charts/voltro-app/Chart.yaml +10 -0
  611. package/templates/baselines/helm/charts/voltro-app/templates/_helpers.tpl +36 -0
  612. package/templates/baselines/helm/charts/voltro-app/templates/configmap.yaml +13 -0
  613. package/templates/baselines/helm/charts/voltro-app/templates/deployment-api.yaml +120 -0
  614. package/templates/baselines/helm/charts/voltro-app/templates/deployment-web.yaml +45 -0
  615. package/templates/baselines/helm/charts/voltro-app/templates/ingress.yaml +37 -0
  616. package/templates/baselines/helm/charts/voltro-app/templates/postgres-service.yaml +19 -0
  617. package/templates/baselines/helm/charts/voltro-app/templates/postgres-statefulset.yaml +73 -0
  618. package/templates/baselines/helm/charts/voltro-app/templates/secret.yaml +33 -0
  619. package/templates/baselines/helm/charts/voltro-app/templates/service-api.yaml +19 -0
  620. package/templates/baselines/helm/charts/voltro-app/templates/service-web.yaml +19 -0
  621. package/templates/baselines/helm/charts/voltro-app/values-dev.yaml +21 -0
  622. package/templates/baselines/helm/charts/voltro-app/values-prod.yaml +58 -0
  623. package/templates/baselines/helm/charts/voltro-app/values-staging.yaml +25 -0
  624. package/templates/baselines/helm/charts/voltro-app/values.yaml +109 -0
  625. package/templates/baselines/helm/deploy/README.md +94 -0
  626. package/templates/patches/@effect__cluster@0.59.0.patch +262 -0
@@ -0,0 +1,110 @@
1
+ // @vitest-environment jsdom
2
+ //
3
+ // `/` — the bilingual landing template. A statically pre-rendered marketing
4
+ // page with zero framework JS on the wire (`renderMode='static'`,
5
+ // `interactive='none'`), localised per URL locale (Strategy B). Two things
6
+ // worth testing:
7
+ // 1. `meta({ locale })` is localized — it reads the REAL catalog via
8
+ // getCatalog, so we assert en vs de titles/descriptions directly (no mock).
9
+ // 2. the rendered body shows localized copy. The page pulls strings from
10
+ // @voltro/i18n (<T>); we mock it to resolve against the real catalog for a
11
+ // controllable "current locale". The hero <h1> carries a `{{capProjectName}}`
12
+ // scaffold placeholder, so we assert the heading EXISTS, not its text.
13
+
14
+ import { afterEach, describe, expect, test, vi } from 'vitest'
15
+ import { act, createElement, type ReactNode } from 'react'
16
+ import { createRoot, type Root } from 'react-dom/client'
17
+ import en from '../locales/en'
18
+ import de from '../locales/de'
19
+
20
+ // Controllable "active locale" for the i18n mock.
21
+ const catalogs: Record<string, Record<string, string>> = { en, de }
22
+ let currentLocale = 'en'
23
+
24
+ // Minimal ICU-ish interpolation: replace {key} with values[key]. Rich-text
25
+ // tags (`<strong>`, `<code>`) are left inline as text — enough to assert the
26
+ // page rendered the right (localized) copy; react-intl injects real elements.
27
+ const fill = (msg: string, values?: Record<string, unknown>): string =>
28
+ values ? msg.replace(/\{(\w+)\}/g, (_, k: string) => String(values[k] ?? `{${k}}`)) : msg
29
+
30
+ vi.mock('@voltro/i18n', () => ({
31
+ // The locale catalogs call these at module top-level; identity mirrors the
32
+ // real (compile-time-only) implementations so importing them doesn't throw.
33
+ defineCatalog: <T,>(c: T): T => c,
34
+ defineLocale:
35
+ () =>
36
+ <T,>(c: T): T =>
37
+ c,
38
+ T: ({ id, values }: { id: string; values?: Record<string, unknown> }) =>
39
+ fill(catalogs[currentLocale]?.[id] ?? id, values),
40
+ }))
41
+
42
+ const { default: Index, meta, renderMode, interactive } = await import('./index')
43
+
44
+ ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
45
+
46
+ let container: HTMLDivElement
47
+ let root: Root
48
+
49
+ const render = (node: ReactNode): void => {
50
+ container = document.createElement('div')
51
+ document.body.appendChild(container)
52
+ act(() => {
53
+ root = createRoot(container)
54
+ root.render(node)
55
+ })
56
+ }
57
+
58
+ afterEach(() => {
59
+ currentLocale = 'en'
60
+ if (root) act(() => root.unmount())
61
+ container?.remove()
62
+ document.body.innerHTML = ''
63
+ })
64
+
65
+ describe('index — config + localized meta', () => {
66
+ test('is a static page with no interactive JS on the wire', () => {
67
+ expect(renderMode).toBe('static')
68
+ expect(interactive).toBe('none')
69
+ })
70
+
71
+ test('meta() returns the English catalog title/description for locale en', () => {
72
+ const m = meta({ locale: 'en' })
73
+ expect(m.title).toBe('Home')
74
+ expect(m.description).toContain('landing page')
75
+ })
76
+
77
+ test('meta() returns the German catalog title/description for locale de', () => {
78
+ const m = meta({ locale: 'de' })
79
+ expect(m.title).toBe('Start')
80
+ expect(m.description).toContain('Landingpage')
81
+ })
82
+
83
+ test('meta() falls back to the default (en) catalog for an unknown locale', () => {
84
+ expect(meta({ locale: 'zz' }).title).toBe('Home')
85
+ })
86
+ })
87
+
88
+ describe('index — localized render', () => {
89
+ test('renders a hero heading + the English Features section', () => {
90
+ currentLocale = 'en'
91
+ render(createElement(Index))
92
+ expect(container.querySelector('main h1')).toBeTruthy()
93
+ const featureSection = container.querySelector('#features')
94
+ expect(featureSection).toBeTruthy()
95
+ expect(featureSection!.querySelector('h2')!.textContent).toBe('Features')
96
+ const bullets = Array.from(container.querySelectorAll('#features li'))
97
+ expect(bullets).toHaveLength(3)
98
+ expect(container.textContent).toContain('Reactive subscriptions')
99
+ expect(container.querySelector('a[href="#features"]')).toBeTruthy()
100
+ expect(container.textContent).toContain('Ready to start?')
101
+ })
102
+
103
+ test('renders the German copy when the active locale is de', () => {
104
+ currentLocale = 'de'
105
+ render(createElement(Index))
106
+ expect(container.querySelector('#features h2')!.textContent).toBe('Funktionen')
107
+ expect(container.textContent).toContain('Reaktive Subscriptions')
108
+ expect(container.textContent).toContain('Bereit loszulegen?')
109
+ })
110
+ })
@@ -0,0 +1,75 @@
1
+ // Landing page for the {{projectName}} project. Pre-rendered at build time
2
+ // by `voltro build` (renderMode='static'), then served straight from the
3
+ // file system by `voltro start`. `interactive='none'` strips ALL framework
4
+ // JS from the wire — each locale is plain, pre-rendered HTML + CSS.
5
+ //
6
+ // Bilingual (Strategy B): mounted at `/` (default locale) and mirrored at
7
+ // `/de` by src/pages/[locale]/index.tsx. `meta` is a FUNCTION of `{ locale }`
8
+ // so each variant's <title> / <description> is localised in the emitted HTML.
9
+
10
+ import type { ReactNode } from 'react'
11
+ import type { PageMeta } from '@voltro/web'
12
+ import { T } from '@voltro/i18n'
13
+ import { getCatalog } from '../lib/locale'
14
+
15
+ // Pre-render at build time. Removes the runtime dependency entirely
16
+ // for plain-content pages — no rpc client, no react hydration. If you
17
+ // later add a sign-up form or anything interactive, switch to
18
+ // `interactive: 'islands'` and mark the form component as an island.
19
+ export const renderMode = 'static' as const
20
+ export const interactive = 'none' as const
21
+
22
+ export const meta = ({ locale }: { locale: string }): PageMeta => {
23
+ const c = getCatalog(locale)
24
+ return {
25
+ title: c['meta.home.title'],
26
+ description: c['meta.home.description'],
27
+ }
28
+ }
29
+
30
+ // Rich-text tag handlers — each `<tag>` used inside a message needs a
31
+ // matching value function so react-intl injects the real element.
32
+ const strong = (chunks: ReactNode): ReactNode => <strong>{chunks}</strong>
33
+ const code = (chunks: ReactNode): ReactNode => <code>{chunks}</code>
34
+
35
+ export default function Index(): ReactNode {
36
+ return (
37
+ <main>
38
+ <section>
39
+ <h1>{{capProjectName}}</h1>
40
+ <p>
41
+ <T id="hero.tagline" />
42
+ </p>
43
+ <a href="#features">
44
+ <T id="hero.cta" />
45
+ </a>
46
+ </section>
47
+
48
+ <section id="features">
49
+ <h2>
50
+ <T id="features.heading" />
51
+ </h2>
52
+ <ul>
53
+ <li>
54
+ <T id="features.reactive" values={{ strong }} />
55
+ </li>
56
+ <li>
57
+ <T id="features.tenant" values={{ strong }} />
58
+ </li>
59
+ <li>
60
+ <T id="features.conventions" values={{ strong, code }} />
61
+ </li>
62
+ </ul>
63
+ </section>
64
+
65
+ <section>
66
+ <h2>
67
+ <T id="cta.heading" />
68
+ </h2>
69
+ <p>
70
+ <T id="cta.body" values={{ code }} />
71
+ </p>
72
+ </section>
73
+ </main>
74
+ )
75
+ }
@@ -0,0 +1,84 @@
1
+ // @vitest-environment jsdom
2
+ //
3
+ // Root layout — renders the top nav whose Home link + language switcher are
4
+ // locale-prefixed off the CURRENT url (useUrlLocale → useLocation). We mock
5
+ // useLocation (@voltro/web) to drive the active locale, and mock @voltro/i18n so
6
+ // <I18nProvider> is a pass-through and <T> resolves against the real catalogs.
7
+
8
+ import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
9
+ import { act, createElement, type ReactNode } from 'react'
10
+ import { createRoot, type Root } from 'react-dom/client'
11
+ import en from '../locales/en'
12
+ import de from '../locales/de'
13
+
14
+ const location = vi.fn<() => string>()
15
+ vi.mock('@voltro/web', () => ({ useLocation: () => location() }))
16
+
17
+ const catalogs: Record<string, Record<string, string>> = { en, de }
18
+ const localeFor = (path: string): string => (/^\/de(?:\/|$)/.test(path) ? 'de' : 'en')
19
+
20
+ vi.mock('@voltro/i18n', () => ({
21
+ // The locale catalogs call these at module top-level; identity mirrors the
22
+ // real (compile-time-only) implementations so importing them doesn't throw.
23
+ defineCatalog: <T,>(c: T): T => c,
24
+ defineLocale:
25
+ () =>
26
+ <T,>(c: T): T =>
27
+ c,
28
+ I18nProvider: ({ children }: { children?: ReactNode }) => children,
29
+ // The nav uses <T> for link labels; resolve against the catalog of the
30
+ // locale implied by the current path (matches what useUrlLocale computes).
31
+ T: ({ id }: { id: string }) => catalogs[localeFor(location())]?.[id] ?? id,
32
+ }))
33
+
34
+ const { default: Layout } = await import('./layout')
35
+
36
+ ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
37
+
38
+ let container: HTMLDivElement
39
+ let root: Root
40
+
41
+ const render = (node: ReactNode): void => {
42
+ container = document.createElement('div')
43
+ document.body.appendChild(container)
44
+ act(() => {
45
+ root = createRoot(container)
46
+ root.render(node)
47
+ })
48
+ }
49
+
50
+ const hrefs = (): Array<string | null> =>
51
+ Array.from(container.querySelectorAll('a')).map((a) => a.getAttribute('href'))
52
+
53
+ beforeEach(() => location.mockReset())
54
+
55
+ afterEach(() => {
56
+ if (root) act(() => root.unmount())
57
+ container?.remove()
58
+ document.body.innerHTML = ''
59
+ })
60
+
61
+ describe('landing layout — English (bare path)', () => {
62
+ test('renders a bare Home link, an English nav label and the DE switcher target', () => {
63
+ location.mockReturnValue('/')
64
+ render(createElement(Layout, { children: createElement('p', null, 'page') }))
65
+ const h = hrefs()
66
+ expect(h).toContain('/')
67
+ // the language switcher keeps you on the same bare page, re-prefixed per locale
68
+ expect(h).toContain('/de')
69
+ expect(container.textContent).toContain('Home')
70
+ expect(container.textContent).toContain('page')
71
+ })
72
+ })
73
+
74
+ describe('landing layout — German (/de prefix)', () => {
75
+ test('prefixes the home link with /de and renders German labels', () => {
76
+ location.mockReturnValue('/de')
77
+ render(createElement(Layout, { children: null }))
78
+ const h = hrefs()
79
+ expect(h).toContain('/de')
80
+ // switching back to en strips the prefix
81
+ expect(h).toContain('/')
82
+ expect(container.textContent).toContain('Start')
83
+ })
84
+ })
@@ -0,0 +1,66 @@
1
+ // Root layout. Strategy B (URL-prefix i18n): an INNER <I18nProvider> reads
2
+ // the locale FROM THE URL, so the pre-render pipeline resolves the right
3
+ // catalog per locale-prefixed path (and client-side nav swaps it without a
4
+ // full reload). The language switcher is plain <a> links — no JS needed, so
5
+ // this stays compatible with the pages' `interactive: 'none'`.
6
+ //
7
+ // `<html>`/`<head>`/`<body>` are owned by the framework shell — don't render
8
+ // them here. Page <title> + meta come from each page's `meta` export.
9
+
10
+ import type { ReactNode } from 'react'
11
+ import { I18nProvider, T } from '@voltro/i18n'
12
+ import { useLocation } from '@voltro/web'
13
+ import {
14
+ CATALOGS,
15
+ DEFAULT_LOCALE,
16
+ SUPPORTED_LOCALES,
17
+ stripLocalePrefix,
18
+ useUrlLocale,
19
+ withLocalePrefix,
20
+ } from '../lib/locale'
21
+ import '../globals.css'
22
+
23
+ function TopNav(): ReactNode {
24
+ const locale = useUrlLocale()
25
+ // The path WITHOUT its locale prefix — so the language switch keeps you
26
+ // on the same page (e.g. /de → /, then re-prefix per locale).
27
+ const barePath = stripLocalePrefix(useLocation())
28
+
29
+ // Plain <a> (not <Link>): these hrefs are COMPUTED per locale, and
30
+ // <Link to> wants a statically-known `VoltroUrl` literal. Each language
31
+ // is its own crawlable URL, reached by a full navigation.
32
+ return (
33
+ <nav className="topnav">
34
+ <a href={withLocalePrefix('/', locale)}>
35
+ <T id="nav.home" />
36
+ </a>
37
+ <span className="spacer" />
38
+ <span className="lang">
39
+ <span className="label">
40
+ <T id="nav.language" />:
41
+ </span>
42
+ {SUPPORTED_LOCALES.map((code) => (
43
+ <a
44
+ key={code}
45
+ href={withLocalePrefix(barePath, code)}
46
+ aria-current={code === locale ? 'true' : undefined}
47
+ >
48
+ {code.toUpperCase()}
49
+ </a>
50
+ ))}
51
+ </span>
52
+ </nav>
53
+ )
54
+ }
55
+
56
+ export default function Layout({ children }: { readonly children: ReactNode }): ReactNode {
57
+ const locale = useUrlLocale()
58
+ return (
59
+ <I18nProvider locale={locale} messages={CATALOGS[locale]} defaultLocale={DEFAULT_LOCALE}>
60
+ <div className="shell">
61
+ <TopNav />
62
+ {children}
63
+ </div>
64
+ </I18nProvider>
65
+ )
66
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "frontend-landing",
3
+ "kind": "web",
4
+ "summary": "Bilingual (en/de) marketing landing page: hero, features grid, CTA. Static-render mode with zero JS on the wire; URL-prefix i18n (`/` + `/de`) pre-renders one HTML file per locale. Flip interactive: 'islands' for interactive pieces.",
5
+ "tags": ["web", "frontend", "landing", "marketing", "static", "i18n", "intl", "localization"]
6
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "jsx": "react-jsx",
5
+ "lib": ["ES2024", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "moduleResolution": "Bundler"
8
+ },
9
+ "include": ["src/**/*"],
10
+ "exclude": ["node_modules", "dist", ".framework"]
11
+ }
@@ -0,0 +1,45 @@
1
+ # {{projectName}} / {{appName}}
2
+
3
+ Pure SPA (template: **frontend-spa**) — a fully client-rendered tool
4
+ with no backend and no SSR.
5
+
6
+ ## Boot
7
+
8
+ ```bash
9
+ pnpm install
10
+ pnpm --filter @{{projectName}}/{{appName}} dev
11
+ ```
12
+
13
+ ## When to reach for `renderMode: 'spa'`
14
+
15
+ Use it when the page is heavily interactive AND its state lives in the
16
+ browser, so a server-rendered first paint would just be discarded on
17
+ hydration. This template's bill splitter is the canonical case: every
18
+ input is interactive and the last tip % is remembered in `localStorage`
19
+ — there is nothing meaningful for the server to render.
20
+
21
+ For content pages (marketing, blog, docs) prefer `renderMode: 'static'`
22
+ and reach for `island()` when only a few widgets are interactive — see
23
+ the **frontend-static-blog** template. Use `spa` only when the JS *is*
24
+ the page.
25
+
26
+ ## What this template demonstrates
27
+
28
+ | Concept | Where |
29
+ |---|---|
30
+ | `renderMode = 'spa'` (client-render, no pre-render) | `src/pages/index.tsx` |
31
+ | Default `interactive: 'full'` (whole tree hydrates) | `src/pages/index.tsx` |
32
+ | Browser-only state via `localStorage` (read in an effect) | `src/pages/index.tsx` |
33
+ | Zero backend — no rpc client, no loader | the whole app |
34
+
35
+ ## Build + serve
36
+
37
+ ```bash
38
+ pnpm --filter @{{projectName}}/{{appName}} build
39
+ pnpm --filter @{{projectName}}/{{appName}} start
40
+ # or push the static dist/ to a CDN:
41
+ voltro static deploy --host cloudflare-pages --project-name {{appName}} --spa
42
+ ```
43
+
44
+ The `--spa` flag serves `index.html` for unknown routes — the correct
45
+ fallback for a single-page app on a CDN.
@@ -0,0 +1,27 @@
1
+ // Web app for the {{projectName}} project — a pure SPA (single-page app).
2
+ //
3
+ // Pages here set `renderMode = 'spa'`: the framework skips pre-rendering
4
+ // and the client renders on load. That is the right call when the page's
5
+ // state lives entirely in the browser (here: localStorage), so an SSR'd
6
+ // first paint would just be thrown away on hydration.
7
+ import { defineEnv, envVar } from '@voltro/env'
8
+
9
+ export const env = defineEnv({
10
+ VOLTRO_PUBLIC_APP_NAME: envVar.string({ access: 'public', default: '{{capProjectName}}' }),
11
+ })
12
+
13
+ export default {
14
+ type: 'web' as const,
15
+ name: '{{capProjectName}}{{capAppName}}',
16
+ port: {{port}},
17
+ theme: 'system' as const,
18
+ env,
19
+ // Bilingual by default. The framework auto-wires a cookie-driven
20
+ // <I18nProvider> from these codes and loads the matching
21
+ // `src/locales/<code>.ts` catalog — so `<T id="…" />` / `useT()` /
22
+ // `useLocale()` work app-wide with no manual setup. The <LocaleSwitcher>
23
+ // in the layout writes the `voltro:lang` cookie + reloads. Grow the app to
24
+ // more languages by adding a code here + a `src/locales/<code>.ts`.
25
+ locales: ['en', 'de'] as const,
26
+ defaultLocale: 'en' as const,
27
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@{{projectName}}/{{appName}}",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "voltro dev .",
8
+ "build": "voltro build .",
9
+ "start": "voltro start .",
10
+ "test": "voltro test",
11
+ "typecheck": "tsc --noEmit"
12
+ },
13
+ "dependencies": {
14
+ "@voltro/cli": "0.1.0",
15
+ "@voltro/client": "0.1.0",
16
+ "@voltro/env": "0.1.0",
17
+ "@voltro/i18n": "0.1.0",
18
+ "@voltro/ui-shadcn": "0.1.0",
19
+ "@voltro/web": "0.1.0",
20
+ "react": "^19.0.0",
21
+ "react-dom": "^19.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/react": "^19.0.0",
25
+ "@types/react-dom": "^19.0.0",
26
+ "typescript": "^5.7.0",
27
+ "vitest": "^3.0.0"
28
+ }
29
+ }
@@ -0,0 +1,84 @@
1
+ /* Self-contained styles — plain CSS, no Tailwind / kit dependency. */
2
+
3
+ :root {
4
+ --bg: #f4f4f5;
5
+ --card: #ffffff;
6
+ --fg: #18181b;
7
+ --muted: #71717a;
8
+ --accent: #0d9488;
9
+ --border: #e4e4e7;
10
+ }
11
+
12
+ :root.dark {
13
+ --bg: #09090b;
14
+ --card: #18181b;
15
+ --fg: #fafafa;
16
+ --muted: #a1a1aa;
17
+ --accent: #2dd4bf;
18
+ --border: #27272a;
19
+ }
20
+
21
+ * { box-sizing: border-box; }
22
+ html, body { margin: 0; min-height: 100vh; }
23
+
24
+ body {
25
+ background: var(--bg);
26
+ color: var(--fg);
27
+ font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
28
+ display: flex;
29
+ justify-content: center;
30
+ padding: 3rem 1rem;
31
+ }
32
+
33
+ .card {
34
+ background: var(--card);
35
+ border: 1px solid var(--border);
36
+ border-radius: 14px;
37
+ padding: 1.75rem;
38
+ width: 100%;
39
+ max-width: 26rem;
40
+ box-shadow: 0 1px 3px rgb(0 0 0 / 0.06);
41
+ }
42
+
43
+ h1 { font-size: 1.4rem; margin: 0 0 0.25rem; }
44
+ .muted { color: var(--muted); font-size: 0.9rem; margin: 0 0 1.5rem; }
45
+
46
+ label { display: block; font-size: 0.85rem; color: var(--muted); margin: 1rem 0 0.35rem; }
47
+
48
+ input[type="number"], input[type="text"] {
49
+ width: 100%;
50
+ padding: 0.6rem 0.75rem;
51
+ font-size: 1rem;
52
+ color: var(--fg);
53
+ background: var(--bg);
54
+ border: 1px solid var(--border);
55
+ border-radius: 8px;
56
+ }
57
+
58
+ .row { display: flex; gap: 0.75rem; }
59
+ .row > div { flex: 1; }
60
+
61
+ .presets { display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }
62
+ .presets button {
63
+ flex: 1;
64
+ padding: 0.5rem;
65
+ font-size: 0.9rem;
66
+ border: 1px solid var(--border);
67
+ background: var(--bg);
68
+ color: var(--fg);
69
+ border-radius: 8px;
70
+ cursor: pointer;
71
+ }
72
+ .presets button.active { border-color: var(--accent); color: var(--accent); font-weight: 600; }
73
+
74
+ .result {
75
+ margin-top: 1.75rem;
76
+ padding-top: 1.25rem;
77
+ border-top: 1px solid var(--border);
78
+ display: flex;
79
+ justify-content: space-between;
80
+ align-items: baseline;
81
+ }
82
+ .result .big { font-size: 2rem; font-weight: 700; color: var(--accent); }
83
+ .result .line { display: flex; justify-content: space-between; font-size: 0.95rem; }
84
+ .result .col { display: flex; flex-direction: column; gap: 0.4rem; flex: 1; }
@@ -0,0 +1,22 @@
1
+ // German catalog. Mirrors every key in `en.ts` — `defineLocale<typeof en>()`
2
+ // fails the build if a key is missing or misspelled. Translate the prose only;
3
+ // keep ICU placeholders and rich tags identical to `en.ts`.
4
+
5
+ import { defineLocale } from '@voltro/i18n'
6
+ import en from './en'
7
+
8
+ export default defineLocale<typeof en>()({
9
+ 'meta.home.title': 'Rechnungsteiler',
10
+
11
+ 'lang.label': 'Sprache',
12
+
13
+ 'home.heading': 'Rechnungsteiler',
14
+ 'home.subtitle': '100 % im Browser · dein letztes Trinkgeld wird lokal gemerkt',
15
+ 'field.bill': 'Rechnungsbetrag',
16
+ 'field.tip': 'Trinkgeld',
17
+ 'field.custom': 'Eigener %',
18
+ 'field.people': 'Personen',
19
+ 'result.tip': 'Trinkgeld',
20
+ 'result.total': 'Gesamt',
21
+ 'result.perPerson': 'pro Person',
22
+ })
@@ -0,0 +1,29 @@
1
+ // Base catalog — the source of truth for this app's UI strings. Every key here
2
+ // MUST be mirrored in `de.ts` (and any other locale); `defineLocale<typeof en>()`
3
+ // enforces that parity at build time, so a missing translation fails typecheck
4
+ // rather than silently falling back.
5
+ //
6
+ // Messages use ICU syntax: `{name}` placeholders, `{n, plural, …}`, and rich
7
+ // tags like `<code>…</code>` (rendered by passing a matching function to
8
+ // `<T values={{ code: (c) => <code>{c}</code> }} />`).
9
+
10
+ import { defineCatalog } from '@voltro/i18n'
11
+
12
+ export default defineCatalog({
13
+ // Browser tab title — locale-aware via the page's `meta({ locale })`.
14
+ 'meta.home.title': 'Bill splitter',
15
+
16
+ // ---- Layout shell (pages/layout.tsx) ----
17
+ 'lang.label': 'Language',
18
+
19
+ // ---- Bill-splitter page (pages/index.tsx) ----
20
+ 'home.heading': 'Bill splitter',
21
+ 'home.subtitle': '100% client-side · your last tip % is remembered locally',
22
+ 'field.bill': 'Bill amount',
23
+ 'field.tip': 'Tip',
24
+ 'field.custom': 'Custom %',
25
+ 'field.people': 'People',
26
+ 'result.tip': 'Tip',
27
+ 'result.total': 'Total',
28
+ 'result.perPerson': 'per person',
29
+ } as const)
@@ -0,0 +1,15 @@
1
+ // Catalog lookup OUTSIDE React — for a page's `meta({ locale })` locale-aware
2
+ // <title>. This app is cookie-i18n (no `/<locale>` URL prefix), so @voltro/web
3
+ // hands `meta` the active locale from the `voltro:lang` cookie. Inside React,
4
+ // use `<T>` / `useT()` via the framework's auto-wired <I18nProvider> instead.
5
+
6
+ import en from './en'
7
+ import de from './de'
8
+
9
+ // Both catalogs share `en`'s keys (defineLocale enforces the mirror), so a
10
+ // known-key lookup returns `string` — not `string | undefined` — which is what
11
+ // `PageMeta.title` requires under exactOptionalPropertyTypes.
12
+ export type Messages = Record<keyof typeof en, string>
13
+
14
+ export const getCatalog = (locale?: string): Messages =>
15
+ (locale === 'de' ? de : en) as Messages