@aurostack/stacks 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 (601) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/cli/src/extract.mjs +165 -0
  4. package/cli/src/fsx.mjs +197 -0
  5. package/cli/src/generate.mjs +235 -0
  6. package/cli/src/hooks.mjs +55 -0
  7. package/cli/src/manifest.mjs +163 -0
  8. package/cli/src/strip.mjs +208 -0
  9. package/cli/src/tokens.mjs +102 -0
  10. package/cli/stack.mjs +672 -0
  11. package/package.json +37 -0
  12. package/templates/nest-api/files/.bin/db.ts +123 -0
  13. package/templates/nest-api/files/.bin/dc.ts +74 -0
  14. package/templates/nest-api/files/.bin/helpers.ts +49 -0
  15. package/templates/nest-api/files/.bin/secrets.ts +68 -0
  16. package/templates/nest-api/files/.bin/start.ts +47 -0
  17. package/templates/nest-api/files/.dockerignore +7 -0
  18. package/templates/nest-api/files/.env.example +91 -0
  19. package/templates/nest-api/files/.env.test.example +75 -0
  20. package/templates/nest-api/files/.forgejo/workflows/build-and-push.yml +41 -0
  21. package/templates/nest-api/files/.forgejo/workflows/test-e2e.yml +83 -0
  22. package/templates/nest-api/files/.forgejo/workflows/test.yml +53 -0
  23. package/templates/nest-api/files/.npmrc.example +1 -0
  24. package/templates/nest-api/files/.nvmrc +1 -0
  25. package/templates/nest-api/files/.prettierrc +8 -0
  26. package/templates/nest-api/files/.swcrc +15 -0
  27. package/templates/nest-api/files/.watchmanconfig +3 -0
  28. package/templates/nest-api/files/.yarnrc.yml +1 -0
  29. package/templates/nest-api/files/Dockerfile +40 -0
  30. package/templates/nest-api/files/__mocks__/activation-twofa.js +7 -0
  31. package/templates/nest-api/files/__mocks__/activation.js +7 -0
  32. package/templates/nest-api/files/__mocks__/forgot-password.js +7 -0
  33. package/templates/nest-api/files/__mocks__/main-layout.js +7 -0
  34. package/templates/nest-api/files/__mocks__/password-changed.js +7 -0
  35. package/templates/nest-api/files/__mocks__/reset-password.js +7 -0
  36. package/templates/nest-api/files/__mocks__/set-password.js +7 -0
  37. package/templates/nest-api/files/__mocks__/welcome.js +7 -0
  38. package/templates/nest-api/files/_gitignore +62 -0
  39. package/templates/nest-api/files/compose.test.yml +33 -0
  40. package/templates/nest-api/files/compose.yml +39 -0
  41. package/templates/nest-api/files/emails/activation-twofa.tsx +58 -0
  42. package/templates/nest-api/files/emails/activation.tsx +36 -0
  43. package/templates/nest-api/files/emails/forgot-password.tsx +29 -0
  44. package/templates/nest-api/files/emails/main-layout.tsx +134 -0
  45. package/templates/nest-api/files/emails/password-changed.tsx +24 -0
  46. package/templates/nest-api/files/emails/reset-password.tsx +24 -0
  47. package/templates/nest-api/files/emails/set-password.tsx +25 -0
  48. package/templates/nest-api/files/emails/welcome.tsx +39 -0
  49. package/templates/nest-api/files/eslint.config.mjs +28 -0
  50. package/templates/nest-api/files/global.d.ts +5 -0
  51. package/templates/nest-api/files/nest-cli.json +8 -0
  52. package/templates/nest-api/files/package.json +150 -0
  53. package/templates/nest-api/files/prisma/schema/auth.prisma +75 -0
  54. package/templates/nest-api/files/prisma/schema/base.prisma +17 -0
  55. package/templates/nest-api/files/prisma/schema/enum.prisma +17 -0
  56. package/templates/nest-api/files/prisma/schema/notification.prisma +14 -0
  57. package/templates/nest-api/files/prisma.config.ts +13 -0
  58. package/templates/nest-api/files/public/.gitkeep +0 -0
  59. package/templates/nest-api/files/seeders/index.ts +27 -0
  60. package/templates/nest-api/files/seeders/util.ts +88 -0
  61. package/templates/nest-api/files/src/__tests__/app.controller.spec.ts +29 -0
  62. package/templates/nest-api/files/src/app.controller.ts +40 -0
  63. package/templates/nest-api/files/src/app.module.ts +268 -0
  64. package/templates/nest-api/files/src/app.resolver.ts +32 -0
  65. package/templates/nest-api/files/src/app.setup.ts +178 -0
  66. package/templates/nest-api/files/src/common/__tests__/auth.service.spec.ts +31 -0
  67. package/templates/nest-api/files/src/common/__tests__/cache.service.spec.ts +214 -0
  68. package/templates/nest-api/files/src/common/__tests__/config.service.spec.ts +56 -0
  69. package/templates/nest-api/files/src/common/__tests__/generator.service.spec.ts +114 -0
  70. package/templates/nest-api/files/src/common/__tests__/health.controller.spec.ts +72 -0
  71. package/templates/nest-api/files/src/common/__tests__/helpers.spec.ts +124 -0
  72. package/templates/nest-api/files/src/common/__tests__/mail.service.spec.ts +75 -0
  73. package/templates/nest-api/files/src/common/__tests__/prisma.indicator.spec.ts +39 -0
  74. package/templates/nest-api/files/src/common/__tests__/prisma.service.spec.ts +15 -0
  75. package/templates/nest-api/files/src/common/__tests__/records.spec.ts +87 -0
  76. package/templates/nest-api/files/src/common/__tests__/schemas.spec.ts +142 -0
  77. package/templates/nest-api/files/src/common/__tests__/throttler-storage.service.spec.ts +80 -0
  78. package/templates/nest-api/files/src/common/common.module.ts +72 -0
  79. package/templates/nest-api/files/src/common/constants/index.ts +2 -0
  80. package/templates/nest-api/files/src/common/constants/options.ts +52 -0
  81. package/templates/nest-api/files/src/common/constants/pino.ts +24 -0
  82. package/templates/nest-api/files/src/common/controllers/health.controller.ts +54 -0
  83. package/templates/nest-api/files/src/common/controllers/index.ts +2 -0
  84. package/templates/nest-api/files/src/common/controllers/metrics.controller.ts +21 -0
  85. package/templates/nest-api/files/src/common/decorators/index.ts +2 -0
  86. package/templates/nest-api/files/src/common/decorators/misc.decorator.ts +49 -0
  87. package/templates/nest-api/files/src/common/decorators/multi-part.decorator.ts +6 -0
  88. package/templates/nest-api/files/src/common/dto/filters.dto.ts +25 -0
  89. package/templates/nest-api/files/src/common/dto/index.ts +1 -0
  90. package/templates/nest-api/files/src/common/entity/index.ts +2 -0
  91. package/templates/nest-api/files/src/common/entity/ok.entity.ts +11 -0
  92. package/templates/nest-api/files/src/common/entity/pagination.entity.ts +24 -0
  93. package/templates/nest-api/files/src/common/exceptions/index.ts +1 -0
  94. package/templates/nest-api/files/src/common/exceptions/prisma.exception.ts +57 -0
  95. package/templates/nest-api/files/src/common/guards/feature-flag.guard.ts +51 -0
  96. package/templates/nest-api/files/src/common/guards/index.ts +1 -0
  97. package/templates/nest-api/files/src/common/interceptors/index.ts +1 -0
  98. package/templates/nest-api/files/src/common/interceptors/metrics.interceptor.ts +37 -0
  99. package/templates/nest-api/files/src/common/misc/helpers.ts +26 -0
  100. package/templates/nest-api/files/src/common/misc/index.ts +3 -0
  101. package/templates/nest-api/files/src/common/misc/origin-builder.ts +56 -0
  102. package/templates/nest-api/files/src/common/misc/prisma.indicator.ts +24 -0
  103. package/templates/nest-api/files/src/common/modules/index.ts +3 -0
  104. package/templates/nest-api/files/src/common/modules/logger.module.ts +104 -0
  105. package/templates/nest-api/files/src/common/modules/metrics.module.ts +28 -0
  106. package/templates/nest-api/files/src/common/modules/queue.module.ts +23 -0
  107. package/templates/nest-api/files/src/common/processors/index.ts +1 -0
  108. package/templates/nest-api/files/src/common/processors/mail/index.ts +47 -0
  109. package/templates/nest-api/files/src/common/processors/mail/process.ts +225 -0
  110. package/templates/nest-api/files/src/common/schemas/fields.ts +76 -0
  111. package/templates/nest-api/files/src/common/schemas/index.ts +1 -0
  112. package/templates/nest-api/files/src/common/services/auth-rate-limit.storage.ts +79 -0
  113. package/templates/nest-api/files/src/common/services/auth.service.ts +16 -0
  114. package/templates/nest-api/files/src/common/services/cache.service.ts +118 -0
  115. package/templates/nest-api/files/src/common/services/config.service.ts +388 -0
  116. package/templates/nest-api/files/src/common/services/feature-flag.service.ts +117 -0
  117. package/templates/nest-api/files/src/common/services/generator.service.ts +54 -0
  118. package/templates/nest-api/files/src/common/services/index.ts +10 -0
  119. package/templates/nest-api/files/src/common/services/logger.service.ts +14 -0
  120. package/templates/nest-api/files/src/common/services/mail.service.ts +44 -0
  121. package/templates/nest-api/files/src/common/services/prisma.service.ts +106 -0
  122. package/templates/nest-api/files/src/common/services/throttler-storage.service.ts +112 -0
  123. package/templates/nest-api/files/src/common/types/email.ts +55 -0
  124. package/templates/nest-api/files/src/common/types/index.ts +3 -0
  125. package/templates/nest-api/files/src/common/types/misc.ts +20 -0
  126. package/templates/nest-api/files/src/common/types/prisma.ts +18 -0
  127. package/templates/nest-api/files/src/common/utils/enum.ts +39 -0
  128. package/templates/nest-api/files/src/common/utils/helpers.ts +139 -0
  129. package/templates/nest-api/files/src/common/utils/index.ts +5 -0
  130. package/templates/nest-api/files/src/common/utils/ip.ts +22 -0
  131. package/templates/nest-api/files/src/common/utils/records.ts +66 -0
  132. package/templates/nest-api/files/src/common/utils/redis.keys.ts +31 -0
  133. package/templates/nest-api/files/src/lib/__tests__/access.spec.ts +33 -0
  134. package/templates/nest-api/files/src/lib/access.ts +114 -0
  135. package/templates/nest-api/files/src/lib/auth.ts +76 -0
  136. package/templates/nest-api/files/src/lib/rate-limit.ts +20 -0
  137. package/templates/nest-api/files/src/main.ts +28 -0
  138. package/templates/nest-api/files/src/media/__tests__/media.service.spec.ts +60 -0
  139. package/templates/nest-api/files/src/media/__tests__/s3.service.spec.ts +159 -0
  140. package/templates/nest-api/files/src/media/entity/file.entity.ts +7 -0
  141. package/templates/nest-api/files/src/media/entity/index.ts +1 -0
  142. package/templates/nest-api/files/src/media/media.module.ts +20 -0
  143. package/templates/nest-api/files/src/media/processors/index.ts +44 -0
  144. package/templates/nest-api/files/src/media/services/index.ts +2 -0
  145. package/templates/nest-api/files/src/media/services/media.service.ts +29 -0
  146. package/templates/nest-api/files/src/media/services/s3.service.ts +168 -0
  147. package/templates/nest-api/files/src/notifications/controllers/index.ts +1 -0
  148. package/templates/nest-api/files/src/notifications/controllers/notifications.controller.ts +72 -0
  149. package/templates/nest-api/files/src/notifications/dto/index.ts +1 -0
  150. package/templates/nest-api/files/src/notifications/dto/notification.dto.ts +11 -0
  151. package/templates/nest-api/files/src/notifications/entity/index.ts +1 -0
  152. package/templates/nest-api/files/src/notifications/entity/notification.entity.ts +37 -0
  153. package/templates/nest-api/files/src/notifications/notifications.module.ts +11 -0
  154. package/templates/nest-api/files/src/notifications/services/index.ts +1 -0
  155. package/templates/nest-api/files/src/notifications/services/notifications.service.ts +98 -0
  156. package/templates/nest-api/files/src/realtime/__tests__/events.gateway.spec.ts +88 -0
  157. package/templates/nest-api/files/src/realtime/__tests__/rooms.spec.ts +29 -0
  158. package/templates/nest-api/files/src/realtime/__tests__/ws-permissions.guard.spec.ts +54 -0
  159. package/templates/nest-api/files/src/realtime/adapters/redis-io.adapter.ts +57 -0
  160. package/templates/nest-api/files/src/realtime/constants/index.ts +68 -0
  161. package/templates/nest-api/files/src/realtime/decorators/index.ts +1 -0
  162. package/templates/nest-api/files/src/realtime/decorators/ws-permissions.decorator.ts +14 -0
  163. package/templates/nest-api/files/src/realtime/gateways/events.gateway.ts +187 -0
  164. package/templates/nest-api/files/src/realtime/guards/index.ts +2 -0
  165. package/templates/nest-api/files/src/realtime/guards/ws-auth.guard.ts +20 -0
  166. package/templates/nest-api/files/src/realtime/guards/ws-permissions.guard.ts +35 -0
  167. package/templates/nest-api/files/src/realtime/misc/session-from-socket.ts +54 -0
  168. package/templates/nest-api/files/src/realtime/realtime.module.ts +26 -0
  169. package/templates/nest-api/files/src/realtime/services/presence.service.ts +56 -0
  170. package/templates/nest-api/files/src/realtime/services/realtime.service.ts +72 -0
  171. package/templates/nest-api/files/src/users/__tests__/current-user.controller.spec.ts +77 -0
  172. package/templates/nest-api/files/src/users/__tests__/current-user.service.spec.ts +159 -0
  173. package/templates/nest-api/files/src/users/__tests__/user.entity.spec.ts +175 -0
  174. package/templates/nest-api/files/src/users/__tests__/users.controller.spec.ts +89 -0
  175. package/templates/nest-api/files/src/users/__tests__/users.service.spec.ts +398 -0
  176. package/templates/nest-api/files/src/users/controllers/current-user.controller.ts +82 -0
  177. package/templates/nest-api/files/src/users/controllers/index.ts +2 -0
  178. package/templates/nest-api/files/src/users/controllers/users.controller.ts +40 -0
  179. package/templates/nest-api/files/src/users/decorators/index.ts +1 -0
  180. package/templates/nest-api/files/src/users/decorators/permissions.decorator.ts +24 -0
  181. package/templates/nest-api/files/src/users/dto/avatar.dto.ts +13 -0
  182. package/templates/nest-api/files/src/users/dto/filters.dto.ts +8 -0
  183. package/templates/nest-api/files/src/users/dto/index.ts +2 -0
  184. package/templates/nest-api/files/src/users/entity/index.ts +1 -0
  185. package/templates/nest-api/files/src/users/entity/user.entity.ts +53 -0
  186. package/templates/nest-api/files/src/users/services/current-user.service.ts +46 -0
  187. package/templates/nest-api/files/src/users/services/index.ts +2 -0
  188. package/templates/nest-api/files/src/users/services/users.service.ts +88 -0
  189. package/templates/nest-api/files/src/users/users.module.ts +10 -0
  190. package/templates/nest-api/files/test/app.spec.ts +102 -0
  191. package/templates/nest-api/files/test/auth.spec.ts +108 -0
  192. package/templates/nest-api/files/test/current-user.spec.ts +154 -0
  193. package/templates/nest-api/files/test/factory/app.ts +172 -0
  194. package/templates/nest-api/files/test/factory/constants.ts +22 -0
  195. package/templates/nest-api/files/test/factory/dto.ts +27 -0
  196. package/templates/nest-api/files/test/factory/entity.ts +70 -0
  197. package/templates/nest-api/files/test/factory/gen.ts +75 -0
  198. package/templates/nest-api/files/test/factory/util.ts +21 -0
  199. package/templates/nest-api/files/test/notifications.spec.ts +176 -0
  200. package/templates/nest-api/files/test/rate-limit.spec.ts +180 -0
  201. package/templates/nest-api/files/test/setup.ts +1 -0
  202. package/templates/nest-api/files/test/users.spec.ts +437 -0
  203. package/templates/nest-api/files/tsconfig.build.json +13 -0
  204. package/templates/nest-api/files/tsconfig.json +35 -0
  205. package/templates/nest-api/files/vitest.config.ts +53 -0
  206. package/templates/nest-api/template.json +452 -0
  207. package/templates/node-worker/files/.bin/db.ts +123 -0
  208. package/templates/node-worker/files/.bin/helpers.ts +49 -0
  209. package/templates/node-worker/files/.bin/secrets.ts +68 -0
  210. package/templates/node-worker/files/.dockerignore +5 -0
  211. package/templates/node-worker/files/.env.example +21 -0
  212. package/templates/node-worker/files/.forgejo/workflows/build-and-push.yml +41 -0
  213. package/templates/node-worker/files/.nvmrc +1 -0
  214. package/templates/node-worker/files/.prettierignore +4 -0
  215. package/templates/node-worker/files/.prettierrc +8 -0
  216. package/templates/node-worker/files/.yarnrc.yml +5 -0
  217. package/templates/node-worker/files/Dockerfile +63 -0
  218. package/templates/node-worker/files/Dockerfile.dev +59 -0
  219. package/templates/node-worker/files/_gitignore +48 -0
  220. package/templates/node-worker/files/ecosystem.config.cjs +10 -0
  221. package/templates/node-worker/files/eslint.config.js +37 -0
  222. package/templates/node-worker/files/package.json +67 -0
  223. package/templates/node-worker/files/prisma/_gitignore +1 -0
  224. package/templates/node-worker/files/prisma/schema/base.prisma +36 -0
  225. package/templates/node-worker/files/prisma.config.ts +13 -0
  226. package/templates/node-worker/files/src/config.ts +55 -0
  227. package/templates/node-worker/files/src/db.ts +118 -0
  228. package/templates/node-worker/files/src/index.ts +7 -0
  229. package/templates/node-worker/files/src/logger.ts +45 -0
  230. package/templates/node-worker/files/src/types.ts +23 -0
  231. package/templates/node-worker/files/src/utils/browser.ts +16 -0
  232. package/templates/node-worker/files/src/utils/date.ts +68 -0
  233. package/templates/node-worker/files/src/utils/helpers.ts +17 -0
  234. package/templates/node-worker/files/src/utils/number.ts +47 -0
  235. package/templates/node-worker/files/src/utils/worker.ts +29 -0
  236. package/templates/node-worker/files/src/workers/constants.ts +6 -0
  237. package/templates/node-worker/files/src/workers/example/index.ts +27 -0
  238. package/templates/node-worker/files/src/workers/index.ts +1 -0
  239. package/templates/node-worker/files/tsconfig.json +30 -0
  240. package/templates/node-worker/template.json +135 -0
  241. package/templates/py-worker/files/.dockerignore +176 -0
  242. package/templates/py-worker/files/.env.example +20 -0
  243. package/templates/py-worker/files/.forgejo/workflows/build-amd-push.yml +39 -0
  244. package/templates/py-worker/files/Dockerfile +10 -0
  245. package/templates/py-worker/files/README.md +3 -0
  246. package/templates/py-worker/files/_gitignore +176 -0
  247. package/templates/py-worker/files/config.py +89 -0
  248. package/templates/py-worker/files/models/decorators.py +42 -0
  249. package/templates/py-worker/files/models/enums.py +32 -0
  250. package/templates/py-worker/files/models/mixins.py +61 -0
  251. package/templates/py-worker/files/requirements.txt +18 -0
  252. package/templates/py-worker/files/utils/db.py +67 -0
  253. package/templates/py-worker/files/utils/logger.py +97 -0
  254. package/templates/py-worker/files/utils/misc.py +45 -0
  255. package/templates/py-worker/files/utils/worker.py +80 -0
  256. package/templates/py-worker/files/worker.py +41 -0
  257. package/templates/py-worker/files/workers/hello/process.py +22 -0
  258. package/templates/py-worker/template.json +87 -0
  259. package/templates/react-app/README.md +78 -0
  260. package/templates/react-app/derive.sh +128 -0
  261. package/templates/react-app/files/.bin/openapi.js +32 -0
  262. package/templates/react-app/files/.bin/secrets.js +47 -0
  263. package/templates/react-app/files/.dockerignore +16 -0
  264. package/templates/react-app/files/.editorconfig +12 -0
  265. package/templates/react-app/files/.env.example +34 -0
  266. package/templates/react-app/files/.forgejo/workflows/build-and-push.yml +55 -0
  267. package/templates/react-app/files/.forgejo/workflows/ci.yml +39 -0
  268. package/templates/react-app/files/.husky/pre-commit +1 -0
  269. package/templates/react-app/files/.nvmrc +1 -0
  270. package/templates/react-app/files/.prettierignore +6 -0
  271. package/templates/react-app/files/.prettierrc +9 -0
  272. package/templates/react-app/files/.yarnrc.yml +2 -0
  273. package/templates/react-app/files/Dockerfile +52 -0
  274. package/templates/react-app/files/_gitignore +33 -0
  275. package/templates/react-app/files/build.sh +53 -0
  276. package/templates/react-app/files/docker/nginx.conf +134 -0
  277. package/templates/react-app/files/eslint.config.mjs +75 -0
  278. package/templates/react-app/files/index.html +62 -0
  279. package/templates/react-app/files/openapi-ts.config.ts +22 -0
  280. package/templates/react-app/files/package.json +80 -0
  281. package/templates/react-app/files/src/app/nav.tsx +32 -0
  282. package/templates/react-app/files/src/app/providers.tsx +39 -0
  283. package/templates/react-app/files/src/app/router.tsx +142 -0
  284. package/templates/react-app/files/src/app/store.ts +20 -0
  285. package/templates/react-app/files/src/features/auth/components/auth-card.tsx +23 -0
  286. package/templates/react-app/files/src/features/auth/components/checkbox-field.tsx +32 -0
  287. package/templates/react-app/files/src/features/auth/components/google-button.tsx +41 -0
  288. package/templates/react-app/files/src/features/auth/components/or-divider.tsx +9 -0
  289. package/templates/react-app/files/src/features/auth/components/password-field.tsx +70 -0
  290. package/templates/react-app/files/src/features/auth/components/submit-button.tsx +16 -0
  291. package/templates/react-app/files/src/features/auth/lib/auth-actions.ts +68 -0
  292. package/templates/react-app/files/src/features/auth/lib/password-strength.ts +20 -0
  293. package/templates/react-app/files/src/features/auth/lib/redirect.ts +6 -0
  294. package/templates/react-app/files/src/features/auth/lib/schemas.ts +37 -0
  295. package/templates/react-app/files/src/features/seo/routes.ts +65 -0
  296. package/templates/react-app/files/src/lib/env.ts +28 -0
  297. package/templates/react-app/files/src/lib/paths.ts +58 -0
  298. package/templates/react-app/files/src/main.tsx +19 -0
  299. package/templates/react-app/files/src/routes/admin/home.tsx +24 -0
  300. package/templates/react-app/files/src/routes/auth/forgot-password.tsx +93 -0
  301. package/templates/react-app/files/src/routes/auth/login.tsx +87 -0
  302. package/templates/react-app/files/src/routes/auth/reset-password.tsx +83 -0
  303. package/templates/react-app/files/src/routes/auth/signup.tsx +117 -0
  304. package/templates/react-app/files/src/routes/auth/verified.tsx +31 -0
  305. package/templates/react-app/files/src/routes/auth/verify-email.tsx +97 -0
  306. package/templates/react-app/files/src/routes/home.tsx +17 -0
  307. package/templates/react-app/files/src/routes/legal/privacy.tsx +26 -0
  308. package/templates/react-app/files/src/routes/legal/terms.tsx +28 -0
  309. package/templates/react-app/files/src/routes/marketing/home.tsx +18 -0
  310. package/templates/react-app/files/src/routes/settings.tsx +10 -0
  311. package/templates/react-app/files/src/shared/api/base-api.ts +24 -0
  312. package/templates/react-app/files/src/shared/api/base-query.ts +29 -0
  313. package/templates/react-app/files/src/shared/api/config.ts +21 -0
  314. package/templates/react-app/files/src/shared/api/index.ts +15 -0
  315. package/templates/react-app/files/src/shared/api/realtime-events.ts +34 -0
  316. package/templates/react-app/files/src/shared/api/socket.ts +41 -0
  317. package/templates/react-app/files/src/shared/api/store.ts +39 -0
  318. package/templates/react-app/files/src/shared/api/upload-query.ts +115 -0
  319. package/templates/react-app/files/src/shared/auth/client.ts +27 -0
  320. package/templates/react-app/files/src/shared/auth/config.ts +28 -0
  321. package/templates/react-app/files/src/shared/auth/guards.tsx +75 -0
  322. package/templates/react-app/files/src/shared/auth/hooks.ts +13 -0
  323. package/templates/react-app/files/src/shared/auth/index.ts +20 -0
  324. package/templates/react-app/files/src/shared/auth/logout.ts +23 -0
  325. package/templates/react-app/files/src/shared/auth/provider.tsx +52 -0
  326. package/templates/react-app/files/src/shared/auth/redirect.ts +65 -0
  327. package/templates/react-app/files/src/shared/auth/slice.ts +54 -0
  328. package/templates/react-app/files/src/shared/hooks/index.ts +6 -0
  329. package/templates/react-app/files/src/shared/layouts/app-shell/app-shell.tsx +225 -0
  330. package/templates/react-app/files/src/shared/layouts/app-shell/user-menu.tsx +74 -0
  331. package/templates/react-app/files/src/shared/layouts/auth-layout.tsx +137 -0
  332. package/templates/react-app/files/src/shared/layouts/error-boundary.tsx +38 -0
  333. package/templates/react-app/files/src/shared/layouts/index.ts +23 -0
  334. package/templates/react-app/files/src/shared/layouts/marketing/marketing-layout.tsx +29 -0
  335. package/templates/react-app/files/src/shared/layouts/marketing/section-heading.tsx +38 -0
  336. package/templates/react-app/files/src/shared/layouts/marketing/section.tsx +30 -0
  337. package/templates/react-app/files/src/shared/layouts/states/app-shell-skeleton.tsx +47 -0
  338. package/templates/react-app/files/src/shared/layouts/states/empty.tsx +22 -0
  339. package/templates/react-app/files/src/shared/layouts/states/forbidden.tsx +14 -0
  340. package/templates/react-app/files/src/shared/layouts/states/loading.tsx +11 -0
  341. package/templates/react-app/files/src/shared/layouts/states/not-found.tsx +21 -0
  342. package/templates/react-app/files/src/shared/layouts/states/page-skeleton.tsx +39 -0
  343. package/templates/react-app/files/src/shared/layouts/states/route-fallback.tsx +26 -0
  344. package/templates/react-app/files/src/shared/layouts/states/state-screen.tsx +22 -0
  345. package/templates/react-app/files/src/shared/types/README.md +28 -0
  346. package/templates/react-app/files/src/shared/types/api/index.ts +9 -0
  347. package/templates/react-app/files/src/shared/types/api/zod.gen.ts +5 -0
  348. package/templates/react-app/files/src/shared/types/index.ts +4 -0
  349. package/templates/react-app/files/src/shared/ui/components/brand/logo.tsx +51 -0
  350. package/templates/react-app/files/src/shared/ui/components/brand/social-icons.tsx +37 -0
  351. package/templates/react-app/files/src/shared/ui/components/form/form.tsx +120 -0
  352. package/templates/react-app/files/src/shared/ui/components/ui/alert.tsx +25 -0
  353. package/templates/react-app/files/src/shared/ui/components/ui/button.tsx +43 -0
  354. package/templates/react-app/files/src/shared/ui/components/ui/calendar.tsx +78 -0
  355. package/templates/react-app/files/src/shared/ui/components/ui/card.tsx +44 -0
  356. package/templates/react-app/files/src/shared/ui/components/ui/checkbox.tsx +16 -0
  357. package/templates/react-app/files/src/shared/ui/components/ui/date-picker.tsx +76 -0
  358. package/templates/react-app/files/src/shared/ui/components/ui/input.tsx +22 -0
  359. package/templates/react-app/files/src/shared/ui/components/ui/label.tsx +19 -0
  360. package/templates/react-app/files/src/shared/ui/components/ui/modal.tsx +94 -0
  361. package/templates/react-app/files/src/shared/ui/components/ui/popover.tsx +31 -0
  362. package/templates/react-app/files/src/shared/ui/components/ui/progress.tsx +33 -0
  363. package/templates/react-app/files/src/shared/ui/components/ui/search-input.tsx +69 -0
  364. package/templates/react-app/files/src/shared/ui/components/ui/select.tsx +80 -0
  365. package/templates/react-app/files/src/shared/ui/components/ui/skeleton.tsx +12 -0
  366. package/templates/react-app/files/src/shared/ui/components/ui/sonner.tsx +23 -0
  367. package/templates/react-app/files/src/shared/ui/components/ui/spinner.tsx +8 -0
  368. package/templates/react-app/files/src/shared/ui/components/ui/textarea.tsx +22 -0
  369. package/templates/react-app/files/src/shared/ui/index.ts +45 -0
  370. package/templates/react-app/files/src/shared/ui/lib/utils.ts +7 -0
  371. package/templates/react-app/files/src/shared/ui/lib/zod-setup.ts +28 -0
  372. package/templates/react-app/files/src/shared/ui/meta/brand.ts +18 -0
  373. package/templates/react-app/files/src/shared/ui/meta/meta-context.ts +30 -0
  374. package/templates/react-app/files/src/shared/ui/meta/meta-provider.tsx +24 -0
  375. package/templates/react-app/files/src/shared/ui/meta/page-meta.tsx +69 -0
  376. package/templates/react-app/files/src/shared/ui/meta/use-meta-config.ts +11 -0
  377. package/templates/react-app/files/src/shared/ui/styles/globals.css +285 -0
  378. package/templates/react-app/files/src/shared/ui/styles/theme.css +48 -0
  379. package/templates/react-app/files/src/shared/ui/theme/init-script.ts +23 -0
  380. package/templates/react-app/files/src/shared/ui/theme/theme-colors.ts +14 -0
  381. package/templates/react-app/files/src/shared/ui/theme/theme-context.ts +60 -0
  382. package/templates/react-app/files/src/shared/ui/theme/theme-provider.tsx +101 -0
  383. package/templates/react-app/files/src/shared/ui/theme/theme-toggle.tsx +40 -0
  384. package/templates/react-app/files/src/shared/ui/theme/use-theme.ts +11 -0
  385. package/templates/react-app/files/src/vite-env.d.ts +13 -0
  386. package/templates/react-app/files/tsconfig.json +26 -0
  387. package/templates/react-app/files/tsconfig.node.json +25 -0
  388. package/templates/react-app/files/vite.config.ts +344 -0
  389. package/templates/react-app/overrides/src/routes/auth/forgot-password.tsx +93 -0
  390. package/templates/react-app/overrides/src/routes/auth/login.tsx +87 -0
  391. package/templates/react-app/overrides/src/routes/auth/signup.tsx +117 -0
  392. package/templates/react-app/overrides/src/routes/auth/verified.tsx +31 -0
  393. package/templates/react-app/overrides/src/routes/auth/verify-email.tsx +97 -0
  394. package/templates/react-app/overrides/src/shared/auth/config.ts +28 -0
  395. package/templates/react-app/overrides/src/shared/auth/guards.tsx +75 -0
  396. package/templates/react-app/overrides/src/shared/auth/index.ts +20 -0
  397. package/templates/react-app/overrides/src/shared/auth/redirect.ts +65 -0
  398. package/templates/react-app/overrides/src/shared/hooks/index.ts +6 -0
  399. package/templates/react-app/overrides/src/shared/types/README.md +28 -0
  400. package/templates/react-app/template.json +222 -0
  401. package/templates/react-monorepo/files/.dockerignore +19 -0
  402. package/templates/react-monorepo/files/.editorconfig +12 -0
  403. package/templates/react-monorepo/files/.forgejo/workflows/build-and-push.yml +98 -0
  404. package/templates/react-monorepo/files/.forgejo/workflows/ci.yml +35 -0
  405. package/templates/react-monorepo/files/.husky/pre-commit +1 -0
  406. package/templates/react-monorepo/files/.nvmrc +1 -0
  407. package/templates/react-monorepo/files/.prettierignore +6 -0
  408. package/templates/react-monorepo/files/.prettierrc +9 -0
  409. package/templates/react-monorepo/files/.yarnrc.yml +2 -0
  410. package/templates/react-monorepo/files/Dockerfile +90 -0
  411. package/templates/react-monorepo/files/_gitignore +35 -0
  412. package/templates/react-monorepo/files/apps/admin/.bin/secrets.js +57 -0
  413. package/templates/react-monorepo/files/apps/admin/.env.example +16 -0
  414. package/templates/react-monorepo/files/apps/admin/eslint.config.mjs +3 -0
  415. package/templates/react-monorepo/files/apps/admin/index.html +57 -0
  416. package/templates/react-monorepo/files/apps/admin/package.json +33 -0
  417. package/templates/react-monorepo/files/apps/admin/src/App.tsx +3 -0
  418. package/templates/react-monorepo/files/apps/admin/src/app/nav.tsx +14 -0
  419. package/templates/react-monorepo/files/apps/admin/src/app/providers.tsx +42 -0
  420. package/templates/react-monorepo/files/apps/admin/src/app/router.tsx +50 -0
  421. package/templates/react-monorepo/files/apps/admin/src/app/store.ts +15 -0
  422. package/templates/react-monorepo/files/apps/admin/src/lib/env.ts +12 -0
  423. package/templates/react-monorepo/files/apps/admin/src/main.tsx +14 -0
  424. package/templates/react-monorepo/files/apps/admin/src/routes/home.tsx +17 -0
  425. package/templates/react-monorepo/files/apps/admin/src/routes/settings.tsx +10 -0
  426. package/templates/react-monorepo/files/apps/admin/src/vite-env.d.ts +14 -0
  427. package/templates/react-monorepo/files/apps/admin/tsconfig.json +10 -0
  428. package/templates/react-monorepo/files/apps/admin/vite.config.ts +13 -0
  429. package/templates/react-monorepo/files/apps/auth/.bin/secrets.js +57 -0
  430. package/templates/react-monorepo/files/apps/auth/.env.example +16 -0
  431. package/templates/react-monorepo/files/apps/auth/eslint.config.mjs +3 -0
  432. package/templates/react-monorepo/files/apps/auth/index.html +57 -0
  433. package/templates/react-monorepo/files/apps/auth/package.json +32 -0
  434. package/templates/react-monorepo/files/apps/auth/src/App.tsx +3 -0
  435. package/templates/react-monorepo/files/apps/auth/src/app/providers.tsx +42 -0
  436. package/templates/react-monorepo/files/apps/auth/src/app/router.tsx +19 -0
  437. package/templates/react-monorepo/files/apps/auth/src/app/store.ts +15 -0
  438. package/templates/react-monorepo/files/apps/auth/src/components/auth-card.tsx +23 -0
  439. package/templates/react-monorepo/files/apps/auth/src/components/checkbox-field.tsx +32 -0
  440. package/templates/react-monorepo/files/apps/auth/src/components/google-button.tsx +41 -0
  441. package/templates/react-monorepo/files/apps/auth/src/components/or-divider.tsx +9 -0
  442. package/templates/react-monorepo/files/apps/auth/src/components/password-field.tsx +70 -0
  443. package/templates/react-monorepo/files/apps/auth/src/components/submit-button.tsx +16 -0
  444. package/templates/react-monorepo/files/apps/auth/src/lib/auth-actions.ts +68 -0
  445. package/templates/react-monorepo/files/apps/auth/src/lib/env.ts +8 -0
  446. package/templates/react-monorepo/files/apps/auth/src/lib/password-strength.ts +20 -0
  447. package/templates/react-monorepo/files/apps/auth/src/lib/redirect.ts +6 -0
  448. package/templates/react-monorepo/files/apps/auth/src/lib/schemas.ts +37 -0
  449. package/templates/react-monorepo/files/apps/auth/src/main.tsx +14 -0
  450. package/templates/react-monorepo/files/apps/auth/src/routes/forgot-password.tsx +91 -0
  451. package/templates/react-monorepo/files/apps/auth/src/routes/login.tsx +82 -0
  452. package/templates/react-monorepo/files/apps/auth/src/routes/reset-password.tsx +83 -0
  453. package/templates/react-monorepo/files/apps/auth/src/routes/signup.tsx +117 -0
  454. package/templates/react-monorepo/files/apps/auth/src/routes/verified.tsx +30 -0
  455. package/templates/react-monorepo/files/apps/auth/src/routes/verify-email.tsx +96 -0
  456. package/templates/react-monorepo/files/apps/auth/src/vite-env.d.ts +14 -0
  457. package/templates/react-monorepo/files/apps/auth/tsconfig.json +10 -0
  458. package/templates/react-monorepo/files/apps/auth/vite.config.ts +13 -0
  459. package/templates/react-monorepo/files/apps/client/.bin/secrets.js +57 -0
  460. package/templates/react-monorepo/files/apps/client/.env.example +16 -0
  461. package/templates/react-monorepo/files/apps/client/eslint.config.mjs +3 -0
  462. package/templates/react-monorepo/files/apps/client/index.html +57 -0
  463. package/templates/react-monorepo/files/apps/client/package.json +35 -0
  464. package/templates/react-monorepo/files/apps/client/src/App.tsx +3 -0
  465. package/templates/react-monorepo/files/apps/client/src/app/nav.tsx +14 -0
  466. package/templates/react-monorepo/files/apps/client/src/app/providers.tsx +42 -0
  467. package/templates/react-monorepo/files/apps/client/src/app/router.tsx +50 -0
  468. package/templates/react-monorepo/files/apps/client/src/app/store.ts +15 -0
  469. package/templates/react-monorepo/files/apps/client/src/lib/env.ts +12 -0
  470. package/templates/react-monorepo/files/apps/client/src/main.tsx +19 -0
  471. package/templates/react-monorepo/files/apps/client/src/routes/home.tsx +17 -0
  472. package/templates/react-monorepo/files/apps/client/src/routes/settings.tsx +10 -0
  473. package/templates/react-monorepo/files/apps/client/src/vite-env.d.ts +15 -0
  474. package/templates/react-monorepo/files/apps/client/tsconfig.json +10 -0
  475. package/templates/react-monorepo/files/apps/client/vite.config.ts +120 -0
  476. package/templates/react-monorepo/files/apps/landing/.bin/secrets.js +57 -0
  477. package/templates/react-monorepo/files/apps/landing/.env.example +20 -0
  478. package/templates/react-monorepo/files/apps/landing/eslint.config.mjs +3 -0
  479. package/templates/react-monorepo/files/apps/landing/index.html +51 -0
  480. package/templates/react-monorepo/files/apps/landing/package.json +33 -0
  481. package/templates/react-monorepo/files/apps/landing/src/App.tsx +3 -0
  482. package/templates/react-monorepo/files/apps/landing/src/app/providers.tsx +42 -0
  483. package/templates/react-monorepo/files/apps/landing/src/app/router.tsx +21 -0
  484. package/templates/react-monorepo/files/apps/landing/src/app/store.ts +18 -0
  485. package/templates/react-monorepo/files/apps/landing/src/features/seo/routes.ts +65 -0
  486. package/templates/react-monorepo/files/apps/landing/src/lib/env.ts +10 -0
  487. package/templates/react-monorepo/files/apps/landing/src/main.tsx +14 -0
  488. package/templates/react-monorepo/files/apps/landing/src/routes/home.tsx +18 -0
  489. package/templates/react-monorepo/files/apps/landing/src/vite-env.d.ts +15 -0
  490. package/templates/react-monorepo/files/apps/landing/tsconfig.json +10 -0
  491. package/templates/react-monorepo/files/apps/landing/vite.config.ts +169 -0
  492. package/templates/react-monorepo/files/build.sh +61 -0
  493. package/templates/react-monorepo/files/docker/nginx.conf +136 -0
  494. package/templates/react-monorepo/files/package.json +37 -0
  495. package/templates/react-monorepo/files/packages/.gitkeep +0 -0
  496. package/templates/react-monorepo/files/packages/api/eslint.config.mjs +3 -0
  497. package/templates/react-monorepo/files/packages/api/package.json +30 -0
  498. package/templates/react-monorepo/files/packages/api/src/base-api.ts +24 -0
  499. package/templates/react-monorepo/files/packages/api/src/base-query.ts +29 -0
  500. package/templates/react-monorepo/files/packages/api/src/config.ts +21 -0
  501. package/templates/react-monorepo/files/packages/api/src/index.ts +15 -0
  502. package/templates/react-monorepo/files/packages/api/src/realtime-events.ts +34 -0
  503. package/templates/react-monorepo/files/packages/api/src/socket.ts +41 -0
  504. package/templates/react-monorepo/files/packages/api/src/store.ts +39 -0
  505. package/templates/react-monorepo/files/packages/api/src/upload-query.ts +115 -0
  506. package/templates/react-monorepo/files/packages/api/tsconfig.json +4 -0
  507. package/templates/react-monorepo/files/packages/auth/eslint.config.mjs +3 -0
  508. package/templates/react-monorepo/files/packages/auth/package.json +33 -0
  509. package/templates/react-monorepo/files/packages/auth/src/client.ts +27 -0
  510. package/templates/react-monorepo/files/packages/auth/src/config.ts +22 -0
  511. package/templates/react-monorepo/files/packages/auth/src/guards.tsx +61 -0
  512. package/templates/react-monorepo/files/packages/auth/src/hooks.ts +13 -0
  513. package/templates/react-monorepo/files/packages/auth/src/index.ts +20 -0
  514. package/templates/react-monorepo/files/packages/auth/src/logout.ts +23 -0
  515. package/templates/react-monorepo/files/packages/auth/src/provider.tsx +52 -0
  516. package/templates/react-monorepo/files/packages/auth/src/redirect.ts +37 -0
  517. package/templates/react-monorepo/files/packages/auth/src/slice.ts +54 -0
  518. package/templates/react-monorepo/files/packages/auth/tsconfig.json +4 -0
  519. package/templates/react-monorepo/files/packages/config/README.md +47 -0
  520. package/templates/react-monorepo/files/packages/config/eslint/base.mjs +83 -0
  521. package/templates/react-monorepo/files/packages/config/package.json +37 -0
  522. package/templates/react-monorepo/files/packages/config/tailwind/theme.css +48 -0
  523. package/templates/react-monorepo/files/packages/config/tsconfig/base.json +22 -0
  524. package/templates/react-monorepo/files/packages/config/tsconfig/node.json +9 -0
  525. package/templates/react-monorepo/files/packages/config/tsconfig/react.json +9 -0
  526. package/templates/react-monorepo/files/packages/config/vite/index.d.ts +18 -0
  527. package/templates/react-monorepo/files/packages/config/vite/index.mjs +129 -0
  528. package/templates/react-monorepo/files/packages/hooks/eslint.config.mjs +3 -0
  529. package/templates/react-monorepo/files/packages/hooks/package.json +16 -0
  530. package/templates/react-monorepo/files/packages/hooks/src/index.ts +3 -0
  531. package/templates/react-monorepo/files/packages/hooks/tsconfig.json +4 -0
  532. package/templates/react-monorepo/files/packages/layouts/eslint.config.mjs +3 -0
  533. package/templates/react-monorepo/files/packages/layouts/package.json +30 -0
  534. package/templates/react-monorepo/files/packages/layouts/src/app-shell/app-shell.tsx +225 -0
  535. package/templates/react-monorepo/files/packages/layouts/src/app-shell/user-menu.tsx +74 -0
  536. package/templates/react-monorepo/files/packages/layouts/src/auth-layout.tsx +137 -0
  537. package/templates/react-monorepo/files/packages/layouts/src/error-boundary.tsx +38 -0
  538. package/templates/react-monorepo/files/packages/layouts/src/index.ts +23 -0
  539. package/templates/react-monorepo/files/packages/layouts/src/marketing/marketing-layout.tsx +29 -0
  540. package/templates/react-monorepo/files/packages/layouts/src/marketing/section-heading.tsx +38 -0
  541. package/templates/react-monorepo/files/packages/layouts/src/marketing/section.tsx +30 -0
  542. package/templates/react-monorepo/files/packages/layouts/src/states/app-shell-skeleton.tsx +47 -0
  543. package/templates/react-monorepo/files/packages/layouts/src/states/empty.tsx +22 -0
  544. package/templates/react-monorepo/files/packages/layouts/src/states/forbidden.tsx +14 -0
  545. package/templates/react-monorepo/files/packages/layouts/src/states/loading.tsx +11 -0
  546. package/templates/react-monorepo/files/packages/layouts/src/states/not-found.tsx +21 -0
  547. package/templates/react-monorepo/files/packages/layouts/src/states/page-skeleton.tsx +39 -0
  548. package/templates/react-monorepo/files/packages/layouts/src/states/route-fallback.tsx +26 -0
  549. package/templates/react-monorepo/files/packages/layouts/src/states/state-screen.tsx +22 -0
  550. package/templates/react-monorepo/files/packages/layouts/tsconfig.json +4 -0
  551. package/templates/react-monorepo/files/packages/types/.bin/openapi.js +32 -0
  552. package/templates/react-monorepo/files/packages/types/.bin/secrets.js +57 -0
  553. package/templates/react-monorepo/files/packages/types/README.md +28 -0
  554. package/templates/react-monorepo/files/packages/types/eslint.config.mjs +3 -0
  555. package/templates/react-monorepo/files/packages/types/openapi-ts.config.ts +22 -0
  556. package/templates/react-monorepo/files/packages/types/package.json +29 -0
  557. package/templates/react-monorepo/files/packages/types/src/index.ts +4 -0
  558. package/templates/react-monorepo/files/packages/types/src/types/api/index.ts +9 -0
  559. package/templates/react-monorepo/files/packages/types/src/types/api/zod.gen.ts +5 -0
  560. package/templates/react-monorepo/files/packages/types/tsconfig.json +7 -0
  561. package/templates/react-monorepo/files/packages/ui/components.json +21 -0
  562. package/templates/react-monorepo/files/packages/ui/eslint.config.mjs +13 -0
  563. package/templates/react-monorepo/files/packages/ui/package.json +44 -0
  564. package/templates/react-monorepo/files/packages/ui/src/components/brand/logo.tsx +51 -0
  565. package/templates/react-monorepo/files/packages/ui/src/components/brand/social-icons.tsx +37 -0
  566. package/templates/react-monorepo/files/packages/ui/src/components/form/form.tsx +120 -0
  567. package/templates/react-monorepo/files/packages/ui/src/components/ui/alert.tsx +25 -0
  568. package/templates/react-monorepo/files/packages/ui/src/components/ui/button.tsx +43 -0
  569. package/templates/react-monorepo/files/packages/ui/src/components/ui/calendar.tsx +78 -0
  570. package/templates/react-monorepo/files/packages/ui/src/components/ui/card.tsx +44 -0
  571. package/templates/react-monorepo/files/packages/ui/src/components/ui/checkbox.tsx +16 -0
  572. package/templates/react-monorepo/files/packages/ui/src/components/ui/date-picker.tsx +76 -0
  573. package/templates/react-monorepo/files/packages/ui/src/components/ui/input.tsx +22 -0
  574. package/templates/react-monorepo/files/packages/ui/src/components/ui/label.tsx +19 -0
  575. package/templates/react-monorepo/files/packages/ui/src/components/ui/modal.tsx +94 -0
  576. package/templates/react-monorepo/files/packages/ui/src/components/ui/popover.tsx +31 -0
  577. package/templates/react-monorepo/files/packages/ui/src/components/ui/progress.tsx +33 -0
  578. package/templates/react-monorepo/files/packages/ui/src/components/ui/search-input.tsx +69 -0
  579. package/templates/react-monorepo/files/packages/ui/src/components/ui/select.tsx +80 -0
  580. package/templates/react-monorepo/files/packages/ui/src/components/ui/skeleton.tsx +12 -0
  581. package/templates/react-monorepo/files/packages/ui/src/components/ui/sonner.tsx +23 -0
  582. package/templates/react-monorepo/files/packages/ui/src/components/ui/spinner.tsx +8 -0
  583. package/templates/react-monorepo/files/packages/ui/src/components/ui/textarea.tsx +22 -0
  584. package/templates/react-monorepo/files/packages/ui/src/index.ts +45 -0
  585. package/templates/react-monorepo/files/packages/ui/src/lib/utils.ts +7 -0
  586. package/templates/react-monorepo/files/packages/ui/src/lib/zod-setup.ts +28 -0
  587. package/templates/react-monorepo/files/packages/ui/src/meta/brand.ts +18 -0
  588. package/templates/react-monorepo/files/packages/ui/src/meta/meta-context.ts +30 -0
  589. package/templates/react-monorepo/files/packages/ui/src/meta/meta-provider.tsx +24 -0
  590. package/templates/react-monorepo/files/packages/ui/src/meta/page-meta.tsx +69 -0
  591. package/templates/react-monorepo/files/packages/ui/src/meta/use-meta-config.ts +11 -0
  592. package/templates/react-monorepo/files/packages/ui/src/styles/globals.css +285 -0
  593. package/templates/react-monorepo/files/packages/ui/src/theme/init-script.ts +23 -0
  594. package/templates/react-monorepo/files/packages/ui/src/theme/theme-colors.ts +14 -0
  595. package/templates/react-monorepo/files/packages/ui/src/theme/theme-context.ts +60 -0
  596. package/templates/react-monorepo/files/packages/ui/src/theme/theme-provider.tsx +101 -0
  597. package/templates/react-monorepo/files/packages/ui/src/theme/theme-toggle.tsx +40 -0
  598. package/templates/react-monorepo/files/packages/ui/src/theme/use-theme.ts +11 -0
  599. package/templates/react-monorepo/files/packages/ui/tsconfig.json +9 -0
  600. package/templates/react-monorepo/files/turbo.json +24 -0
  601. package/templates/react-monorepo/template.json +230 -0
@@ -0,0 +1,52 @@
1
+ # Static build of the app, served by nginx.
2
+ #
3
+ # docker build --build-arg VITE_APP_API_URL=https://api.example.com -t app .
4
+ #
5
+ # IMPORTANT: Vite inlines `VITE_*` values into the JS bundle at BUILD time, so a
6
+ # built image is pinned to one environment. These are build args, not runtime
7
+ # env — setting them in compose does nothing. Build one image per environment,
8
+ # or move to runtime config.
9
+
10
+ # ---------- deps ----------
11
+ # Manifests only, so `yarn install` re-runs solely when a dependency changes.
12
+ FROM node:24-alpine AS deps
13
+ WORKDIR /app
14
+
15
+ COPY package.json yarn.lock .yarnrc.yml ./
16
+ RUN corepack enable && yarn install --immutable
17
+
18
+ # ---------- build ----------
19
+ FROM node:24-alpine AS build
20
+ WORKDIR /app
21
+ ENV NODE_ENV=production
22
+ # Each stage is a fresh image, so corepack has to be enabled again here —
23
+ # without it `yarn` is the bundled 1.x and refuses the packageManager field.
24
+ RUN corepack enable
25
+
26
+ COPY --from=deps /app/node_modules ./node_modules
27
+ COPY . .
28
+
29
+ # Build args become env vars so Vite's define step picks them up. Process env
30
+ # takes precedence over a committed .env, so a stale checked-in .env cannot leak
31
+ # into the image as long as the arg is supplied.
32
+ ARG VITE_APP_API_URL
33
+ ARG VITE_APP_SITE_URL
34
+ ARG VITE_APP_SUPPORT_EMAIL
35
+ ENV VITE_APP_API_URL=$VITE_APP_API_URL \
36
+ VITE_APP_SITE_URL=$VITE_APP_SITE_URL \
37
+ VITE_APP_SUPPORT_EMAIL=$VITE_APP_SUPPORT_EMAIL
38
+
39
+ # Fail loudly rather than silently producing a bundle with `undefined` URLs baked
40
+ # in — that failure is invisible until the app 404s at runtime.
41
+ RUN test -n "$VITE_APP_API_URL" || (echo "ERROR: --build-arg VITE_APP_API_URL is required" && exit 1)
42
+
43
+ RUN yarn build
44
+
45
+ # ---------- runtime ----------
46
+ FROM nginx:stable-alpine AS runtime
47
+ COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
48
+ COPY --from=build /app/dist /usr/share/nginx/html
49
+
50
+ EXPOSE 80
51
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
52
+ CMD wget -qO- http://127.0.0.1/healthz || exit 1
@@ -0,0 +1,33 @@
1
+ # dependencies
2
+ node_modules/
3
+
4
+ # yarn (berry, node-modules linker)
5
+ .yarn/*
6
+ !.yarn/patches
7
+ !.yarn/plugins
8
+ !.yarn/releases
9
+ !.yarn/sdks
10
+ !.yarn/versions
11
+ .pnp.*
12
+ yarn-error.log
13
+
14
+ # build output
15
+ dist/
16
+ dev-dist/
17
+ *.tsbuildinfo
18
+
19
+ # env
20
+ .env
21
+ .env.local
22
+ .env.*.local
23
+ .env.test
24
+ .env.production
25
+
26
+ # editor / os
27
+ .DS_Store
28
+ *.log
29
+
30
+ # generated OpenAPI schema dump. The types generated FROM it are committed —
31
+ # they are the contract this app compiles against — but the dump itself is a
32
+ # build artefact of whatever backend happened to be running.
33
+ openapi.json
@@ -0,0 +1,53 @@
1
+ #!/bin/sh
2
+ # Build + push the app image.
3
+ #
4
+ # ./build.sh [env] [tag]
5
+ #
6
+ # ./build.sh # uses .env -> :latest
7
+ # ./build.sh prod # uses .env.production
8
+ # ./build.sh prod 26_07_26_1
9
+ #
10
+ # The VITE_* URLs are compiled INTO the bundle, so the image is specific to the
11
+ # environment it was built for. That is why the env name is an argument: the same
12
+ # image cannot be promoted from staging to prod. Pull the env file first with
13
+ # yarn secrets -e <env>
14
+ set -eu
15
+
16
+ ENV_NAME="${1:-dev}"
17
+ TAG="${2:-latest}"
18
+ REGISTRY="${REGISTRY:-registry.example.com/acme}"
19
+ IMAGE="${IMAGE:-web}"
20
+ PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
21
+
22
+ case "$ENV_NAME" in
23
+ dev) ENV_FILE=".env" ;;
24
+ test) ENV_FILE=".env.test" ;;
25
+ staging) ENV_FILE=".env.staging" ;;
26
+ prod | production) ENV_FILE=".env.production" ;;
27
+ *) echo "unknown env '$ENV_NAME' (dev|test|staging|prod)" >&2; exit 1 ;;
28
+ esac
29
+
30
+ [ -f "$ENV_FILE" ] || {
31
+ echo "missing $ENV_FILE — run: yarn secrets -e $ENV_NAME" >&2
32
+ exit 1
33
+ }
34
+
35
+ # Read a var out of the env file, tolerating the quoted style these files use.
36
+ read_var() {
37
+ sed -n "s/^$1=['\"]\{0,1\}\([^'\"]*\)['\"]\{0,1\}$/\1/p" "$ENV_FILE" | tail -1
38
+ }
39
+
40
+ BUILD_ARGS=""
41
+ for VAR in VITE_APP_API_URL VITE_APP_SITE_URL VITE_APP_SUPPORT_EMAIL; do
42
+ VALUE="$(read_var "$VAR")"
43
+ [ -n "$VALUE" ] && BUILD_ARGS="$BUILD_ARGS --build-arg $VAR=$VALUE"
44
+ done
45
+
46
+ echo "Building for '$ENV_NAME' -> $REGISTRY/$IMAGE:$TAG"
47
+ echo " (URLs baked in from $ENV_FILE)"
48
+
49
+ # shellcheck disable=SC2086
50
+ docker buildx build --push --platform "$PLATFORMS" \
51
+ $BUILD_ARGS \
52
+ -t "$REGISTRY/$IMAGE:$TAG" \
53
+ .
@@ -0,0 +1,134 @@
1
+ # Static host for the built Vite SPA.
2
+ #
3
+ # The cache rules are load-bearing, not cosmetic: get them wrong and returning
4
+ # users are pinned to a stale build. Rule of thumb — anything with a content
5
+ # hash in its name is immutable forever; anything with a stable name must be
6
+ # revalidated every time.
7
+
8
+ server {
9
+ listen 80;
10
+ server_name _;
11
+ root /usr/share/nginx/html;
12
+ index index.html;
13
+
14
+ # Compose/orchestrator health probe. Must not be logged or it floods access.log.
15
+ location = /healthz {
16
+ access_log off;
17
+ add_header Content-Type text/plain;
18
+ return 200 "ok\n";
19
+ }
20
+
21
+ gzip on;
22
+ gzip_vary on;
23
+ gzip_min_length 1024;
24
+ gzip_proxied any;
25
+ gzip_types text/plain text/css application/javascript application/json
26
+ image/svg+xml application/manifest+json;
27
+
28
+ # Vite emits content-hashed filenames here, so the content can never change
29
+ # under a given URL — safe to cache for a year.
30
+ # NB: no `expires` directive. `expires` emits its own Cache-Control, so
31
+ # combining it with add_header sends the header twice and clients disagree on
32
+ # which wins — `immutable` can be dropped. One explicit header instead.
33
+ location /assets/ {
34
+ add_header Cache-Control "public, max-age=31536000, immutable" always;
35
+ try_files $uri =404;
36
+ }
37
+
38
+ # The service worker and its Workbox runtime keep STABLE names across builds.
39
+ # If these are cached the browser keeps running the old worker, which keeps
40
+ # serving the old precached app shell — users get stuck on a previous version
41
+ # with no way out but a hard reload. Only a PWA build ships them; the rule is
42
+ # harmless otherwise.
43
+ location ~* ^/(sw\.js|registerSW\.js|workbox-[^/]+\.js)$ {
44
+ add_header Cache-Control "no-cache, must-revalidate" always;
45
+ expires off;
46
+ try_files $uri =404;
47
+ }
48
+
49
+ # Re-checked on every load so a deploy is picked up immediately, and so the
50
+ # manifest's start_url/icons stay in step with the installed PWA.
51
+ location ~* ^/(manifest\.webmanifest|manifest\.json)$ {
52
+ add_header Cache-Control "no-cache, must-revalidate" always;
53
+ expires off;
54
+ try_files $uri =404;
55
+ }
56
+
57
+ # Long-lived but not immutable: stable names, so they must stay revalidatable,
58
+ # but they rarely change.
59
+ location ~* \.(png|jpg|jpeg|gif|svg|ico|webp|woff2?)$ {
60
+ add_header Cache-Control "public, max-age=604800" always;
61
+ try_files $uri =404;
62
+ }
63
+
64
+ # SPA fallback. index.html is never cached — it references the hashed bundles,
65
+ # so a cached copy would keep pointing at assets from the previous deploy.
66
+ #
67
+ # `$uri/index.html` comes BEFORE `$uri/` deliberately. If you add a prerender
68
+ # pass that emits `about/index.html`, matching `$uri/` on a directory makes
69
+ # nginx 301 to the trailing-slash form — verified: `/about` redirected to
70
+ # `/about/`. That fights the canonical tag and the sitemap, which both use the
71
+ # slashless `/about`, and adds a hop for every crawler. Serving the file
72
+ # directly returns 200 at the canonical URL. Harmless for a pure SPA: it ships
73
+ # no such directories, so the extra probe never matches.
74
+ location / {
75
+ try_files $uri $uri/index.html $uri/ @fallback;
76
+ add_header Cache-Control "no-cache, must-revalidate" always;
77
+ expires off;
78
+ }
79
+
80
+ # What an unknown path gets, decided by what the build actually emitted rather
81
+ # than by a config flag that can disagree with it.
82
+ #
83
+ # A pure SPA ships no `404.html`, so this falls through to `index.html` and the
84
+ # router renders its own not-found page. Answering a real 404 here instead
85
+ # would break every client-side route.
86
+ #
87
+ # If you add a prerender pass, emit `404.html` and this starts answering 404
88
+ # automatically. That matters: without one, a prerendered homepage means every
89
+ # typo'd or stale URL returns 200 with a full copy of `/`, and a soft 404 with
90
+ # a body is worse than one without — there is something for a crawler to
91
+ # index.
92
+ #
93
+ # `if` is limited here to `return` and `rewrite ... last`, the two directives
94
+ # documented as safe inside a location.
95
+ location @fallback {
96
+ error_page 404 /404.html;
97
+ if (-f $document_root/404.html) {
98
+ return 404;
99
+ }
100
+ rewrite ^ /index.html last;
101
+ }
102
+
103
+ # Reachable only through error_page, so the page cannot also be served as a
104
+ # regular 200 at /404.html and be indexed on its own.
105
+ location = /404.html {
106
+ internal;
107
+ add_header Cache-Control "no-cache, must-revalidate" always;
108
+ expires off;
109
+ }
110
+
111
+ # Modest hardening. Deliberately NO Content-Security-Policy header: the apps
112
+ # ship an inline <script> in index.html that applies the saved theme before
113
+ # first paint, and a default CSP without 'unsafe-inline' would block it and
114
+ # reintroduce the light-mode flash. Add CSP only with a nonce/hash for that
115
+ # script. HSTS belongs on the TLS-terminating proxy in front of this, not here.
116
+ add_header X-Content-Type-Options "nosniff" always;
117
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
118
+ add_header X-Frame-Options "SAMEORIGIN" always;
119
+
120
+ # RFC 9116 puts security.txt under /.well-known/, which the deny below would
121
+ # otherwise 403 — that is the whole point of this block. `^~` is what makes the
122
+ # exception stick: it tells nginx that once this prefix matches, regex
123
+ # locations are skipped entirely, so `location ~ /\.` never gets a look at it.
124
+ # Deliberately adds no headers of its own, because `add_header` in a location
125
+ # REPLACES the inherited set rather than extending it — the server-level
126
+ # hardening headers above would silently stop applying here.
127
+ location ^~ /.well-known/ {
128
+ try_files $uri =404;
129
+ }
130
+
131
+ location ~ /\. {
132
+ deny all;
133
+ }
134
+ }
@@ -0,0 +1,75 @@
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import reactHooks from 'eslint-plugin-react-hooks';
4
+ import reactRefresh from 'eslint-plugin-react-refresh';
5
+ import tseslint from 'typescript-eslint';
6
+
7
+ /**
8
+ * Flat ESLint config for a React 19 + TypeScript app.
9
+ */
10
+ export default tseslint.config(
11
+ // `dev-dist` is vite-plugin-pwa's dev output (Workbox sources). Generated and
12
+ // gitignored — linting it only produces "rule not found" noise that makes
13
+ // `yarn lint` fail permanently, hiding real findings. `src/shared/types/api`
14
+ // is generated from the OpenAPI schema and formatted by its own pipeline.
15
+ { ignores: ['dist', 'dev-dist', 'node_modules', 'src/shared/types/api'] },
16
+ {
17
+ files: ['**/*.{ts,tsx}'],
18
+ extends: [
19
+ js.configs.recommended,
20
+ tseslint.configs.recommended,
21
+ reactHooks.configs.flat.recommended,
22
+ reactRefresh.configs.vite
23
+ ],
24
+ languageOptions: {
25
+ ecmaVersion: 2023,
26
+ globals: globals.browser
27
+ },
28
+ rules: {
29
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
30
+ '@typescript-eslint/no-empty-object-type': 'off',
31
+
32
+ // The shadcn primitives export their cva variants next to the component
33
+ // (`buttonVariants`), which is what `allowConstantExport` exists for.
34
+ // Left as a warning rather than an error: a fast-refresh hint should not
35
+ // be able to fail CI on a file that works.
36
+ 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
37
+
38
+ // iOS auto-zooms a focused text control whose font-size is under 16px and
39
+ // never restores the zoom on blur, so one tap leaves the user zoomed for
40
+ // the session — in the installed PWA too. `text-sm` is 14px.
41
+ //
42
+ // The lookbehind lets `sm:text-sm` through: `text-base sm:text-sm` is the
43
+ // correct fix (16px on mobile, the intended density from `sm` up).
44
+ //
45
+ // Only catches literal className strings on raw `<input>`/`<textarea>`/
46
+ // `<select>` — that is exactly how this regresses. Prefer `SearchInput` /
47
+ // `Input` from `@/shared/ui`, which already handle it.
48
+ 'no-restricted-syntax': [
49
+ 'error',
50
+ {
51
+ selector:
52
+ "JSXOpeningElement[name.name=/^(input|textarea|select)$/] JSXAttribute[name.name='className'] Literal[value=/(?<![:-])(text-xs|text-sm)(?![a-zA-Z0-9-])/]",
53
+ message:
54
+ 'A text input under 16px makes iOS zoom in on focus and never zoom back out. Use `text-base sm:text-sm`, or the SearchInput / Input components from @/shared/ui.'
55
+ }
56
+ ]
57
+ }
58
+ },
59
+ {
60
+ // `router.tsx` exports the router object alongside the shell components it
61
+ // mounts. Splitting them would mean a second file existing only to satisfy a
62
+ // heuristic — the router is not a component and is never hot-swapped.
63
+ files: ['**/app/router.tsx'],
64
+ rules: { 'react-refresh/only-export-components': 'off' }
65
+ },
66
+ {
67
+ // The shadcn primitives export their cva variants beside the component
68
+ // (`buttonVariants`, `alertVariants`) — that is how the upstream components
69
+ // are written, and it is why consumers can compose them. `allowConstantExport`
70
+ // does not cover a `cva()` call, so without this the rule warns permanently on
71
+ // unmodified upstream code, which is how a lint report stops being read.
72
+ files: ['**/components/ui/**'],
73
+ rules: { 'react-refresh/only-export-components': 'off' }
74
+ }
75
+ );
@@ -0,0 +1,62 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
7
+ <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
8
+ <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
9
+ <link rel="icon" href="/favicon.ico" sizes="any" />
10
+ <link rel="manifest" href="/site.webmanifest" />
11
+ <meta name="theme-color" content="%THEME_LIGHT%" />
12
+ <!--
13
+ Applies the saved (or system) theme before first paint, so the app never
14
+ flashes light then flips to dark. Mirrors `themeInitScript` in
15
+ src/shared/ui — inlined because it must run before any module loads. Keep
16
+ the two in sync. %THEME_LIGHT/DARK% come from THEME_COLORS via vite.config.
17
+ -->
18
+ <script>
19
+ (function () {
20
+ try {
21
+ var m = localStorage.getItem('acme-theme');
22
+ var d =
23
+ m === 'dark' || ((m === null || m === 'system') && matchMedia('(prefers-color-scheme: dark)').matches);
24
+ var r = document.documentElement;
25
+ r.classList.toggle('dark', d);
26
+ r.style.colorScheme = d ? 'dark' : 'light';
27
+ var t = document.querySelector('meta[name="theme-color"]');
28
+ if (t) t.setAttribute('content', d ? '%THEME_DARK%' : '%THEME_LIGHT%');
29
+ } catch (e) {}
30
+ })();
31
+ </script>
32
+ <!--
33
+ globals.css only styles `body`, so without this the UA canvas paints white
34
+ for the moment before the stylesheet lands — a white flash on a dark load.
35
+ -->
36
+ <style>
37
+ html {
38
+ background: %THEME_LIGHT%;
39
+ }
40
+ html.dark {
41
+ background: %THEME_DARK%;
42
+ }
43
+ </style>
44
+ <meta name="description" content="Acme Corp." />
45
+ <!--
46
+ Every route this app serves is private, so nothing here should be indexed.
47
+ `robots.txt` only discourages crawling, while `noindex` prevents listing,
48
+ so both belong in a deployment. This app's routes include password-reset
49
+ and email-verify URLs.
50
+
51
+ With the marketing site included this tag goes away: indexing is then
52
+ decided per route by `PageMeta`, and the build emits a `noindex` of its own
53
+ on any non-production origin. See vite.config.ts.
54
+ -->
55
+ <meta name="robots" content="noindex, nofollow" /> <!-- @feature !marketing -->
56
+ <title>%APP_TITLE%</title>
57
+ </head>
58
+ <body>
59
+ <div id="root"></div>
60
+ <script type="module" src="/src/main.tsx"></script>
61
+ </body>
62
+ </html>
@@ -0,0 +1,22 @@
1
+ import { defineConfig } from '@hey-api/openapi-ts';
2
+
3
+ export default defineConfig({
4
+ input: 'openapi.json',
5
+ output: {
6
+ format: 'prettier',
7
+ path: 'src/shared/types/api',
8
+ lint: 'eslint'
9
+ },
10
+ exportCore: false,
11
+ client: '@hey-api/client-fetch',
12
+ experimentalParser: true,
13
+ plugins: [
14
+ {
15
+ name: 'zod'
16
+ },
17
+ {
18
+ name: '@hey-api/typescript',
19
+ enums: 'typescript'
20
+ }
21
+ ]
22
+ });
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "acme-app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "packageManager": "yarn@4.5.3",
7
+ "engines": {
8
+ "node": ">=24"
9
+ },
10
+ "scripts": {
11
+ "dev": "vite",
12
+ "build": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.node.json && vite build",
13
+ "preview": "vite preview",
14
+ "lint": "eslint .",
15
+ "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.node.json",
16
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,mjs,json,md,css}\"",
17
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mjs,json,md,css}\"",
18
+ "prepare": "husky",
19
+ "secrets": "node .bin/secrets.js",
20
+ "gen:schema": "node .bin/openapi.js",
21
+ "gen:types": "openapi-ts",
22
+ "gen": "node .bin/openapi.js && openapi-ts"
23
+ },
24
+ "lint-staged": {
25
+ "*.{ts,tsx,js,jsx,mjs,json,md,css}": "prettier --write"
26
+ },
27
+ "dependencies": {
28
+ "@fontsource-variable/inter": "^5.3.0",
29
+ "@radix-ui/react-label": "^2.1.7",
30
+ "@radix-ui/react-popover": "^1.1.21",
31
+ "@radix-ui/react-select": "^2.3.4",
32
+ "@radix-ui/react-slot": "^1.2.5",
33
+ "@reduxjs/toolkit": "^2.12.0",
34
+ "apexcharts": "^6.5.0",
35
+ "better-auth": "^1.6.2",
36
+ "class-variance-authority": "^0.7.1",
37
+ "clsx": "^2.1.1",
38
+ "date-fns": "^3",
39
+ "formik": "^2.4.9",
40
+ "lucide-react": "^1.17.0",
41
+ "react": "^19.2.6",
42
+ "react-apexcharts": "^2.1.1",
43
+ "react-day-picker": "^9",
44
+ "react-dom": "^19.2.6",
45
+ "react-redux": "^9.3.0",
46
+ "react-router": "^8.2.0",
47
+ "socket.io-client": "^4.8.1",
48
+ "sonner": "^2.0.7",
49
+ "tailwind-merge": "^3.6.0",
50
+ "zod": "^4.4.3",
51
+ "zod-formik-adapter": "^2.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@eslint/js": "^10.0.1",
55
+ "@hey-api/client-fetch": "^0.5.2",
56
+ "@hey-api/openapi-ts": "^0.59.1",
57
+ "@tailwindcss/vite": "^4.3.0",
58
+ "@types/node": "^24.10.1",
59
+ "@types/react": "^19.2.14",
60
+ "@types/react-dom": "^19.2.3",
61
+ "@vitejs/plugin-react": "^6.0.1",
62
+ "axios": "^1.7.9",
63
+ "dotenv": "^16.4.7",
64
+ "eslint": "^10.3.0",
65
+ "eslint-plugin-react-hooks": "^7.1.1",
66
+ "eslint-plugin-react-refresh": "^0.5.2",
67
+ "globals": "^17.6.0",
68
+ "husky": "^9.1.7",
69
+ "lint-staged": "^15.3.0",
70
+ "prettier": "^3.4.2",
71
+ "tiny-invariant": "^1.3.3",
72
+ "typescript": "~6.0.2",
73
+ "typescript-eslint": "^8.59.2",
74
+ "vite": "^8.0.12",
75
+ "vite-plugin-pwa": "^1.3.0"
76
+ },
77
+ "resolutions": {
78
+ "typescript": "~6.0.2"
79
+ }
80
+ }
@@ -0,0 +1,32 @@
1
+ import { Home, Settings } from 'lucide-react';
2
+ import { ShieldCheck } from 'lucide-react'; // @feature admin
3
+ import type { NavItem } from '@/shared/layouts';
4
+ import { appPath } from '@/lib/paths';
5
+ import { ADMIN_BASE } from '@/lib/paths'; // @feature admin
6
+
7
+ /**
8
+ * Drives the app shell's navigation. Keep it in step with `router.tsx` — the
9
+ * shell derives the sidebar from this list, not from the router, so a route
10
+ * added in one place and not the other is simply unreachable or dead.
11
+ *
12
+ * Paths come from `appPath` rather than being written out, because the app's
13
+ * mount point moves when the marketing site is included. `icon` is a rendered
14
+ * element, not a component reference.
15
+ */
16
+ export const NAV_ITEMS: NavItem[] = [
17
+ { to: appPath(), label: 'Home', icon: <Home className="size-4" />, end: true },
18
+ { to: appPath('settings'), label: 'Settings', icon: <Settings className="size-4" /> }
19
+ ];
20
+
21
+ // @feature:start admin
22
+ /**
23
+ * The console's own nav. Separate from `NAV_ITEMS` on purpose: the admin section
24
+ * is a different branch of the router behind a different guard, and mixing an
25
+ * admin link into the member sidebar would render it for members too — a link
26
+ * that 403s is a worse answer than no link.
27
+ */
28
+ export const ADMIN_NAV_ITEMS: NavItem[] = [
29
+ { to: ADMIN_BASE, label: 'Overview', icon: <ShieldCheck className="size-4" />, end: true },
30
+ { to: appPath(), label: 'Back to app', icon: <Home className="size-4" /> }
31
+ ];
32
+ // @feature:end
@@ -0,0 +1,39 @@
1
+ import type { ReactNode } from 'react';
2
+ import { Provider } from 'react-redux';
3
+ import { configureApi } from '@/shared/api';
4
+ import { AuthProvider, configureAuth, redirectToLogin } from '@/shared/auth';
5
+ import { MetaProvider, ThemeProvider, Toaster, installZodErrorMap } from '@/shared/ui';
6
+ import { API_URL } from '@/lib/env';
7
+ import { appPath } from '@/lib/paths';
8
+ import { store } from './store';
9
+
10
+ // Wired at module scope, before anything renders. The first thing this app does
11
+ // is ask the backend who the user is, and doing this in an effect would put that
12
+ // request behind a render pass for no gain.
13
+ configureApi({ baseUrl: API_URL, onUnauthorized: () => redirectToLogin() });
14
+ configureAuth({
15
+ authApiBaseUrl: `${API_URL}/auth`,
16
+ // `trustedOrigins` is left to its default of this app's own origin — one
17
+ // deployment, one origin. Add to it only for a deliberate hand-off elsewhere;
18
+ // every entry is a URL an attacker may put in `?redirect=`.
19
+ defaultRedirect: appPath()
20
+ });
21
+ installZodErrorMap();
22
+
23
+ export function Providers({ children }: { children: ReactNode }) {
24
+ return (
25
+ // ThemeProvider above the Redux Provider: it only touches the document
26
+ // (`dark` class, color-scheme, theme-color meta) and must not re-render
27
+ // through the store.
28
+ <ThemeProvider>
29
+ <MetaProvider>
30
+ <Provider store={store}>
31
+ <AuthProvider>
32
+ {children}
33
+ <Toaster />
34
+ </AuthProvider>
35
+ </Provider>
36
+ </MetaProvider>
37
+ </ThemeProvider>
38
+ );
39
+ }