@nextsparkjs/core 0.1.0-beta.188 → 0.1.0-beta.189

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 (412) hide show
  1. package/dist/components/api/keys/ApiKeyDisplay.js +19 -19
  2. package/dist/components/api/keys/CreateApiKeyDialog.js +21 -21
  3. package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
  4. package/dist/components/app/layouts/PublicNavbar.js +34 -16
  5. package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
  6. package/dist/components/app/misc/ThemeToggle.js +3 -4
  7. package/dist/components/auth/SessionCookieRefresher.d.ts +5 -0
  8. package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -1
  9. package/dist/components/auth/SessionCookieRefresher.js +7 -1
  10. package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
  11. package/dist/components/auth/forms/LoginForm.js +49 -12
  12. package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
  13. package/dist/components/auth/forms/SignupForm.js +4 -3
  14. package/dist/components/dashboard/block-editor/block-settings-panel.js +1 -1
  15. package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
  16. package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
  17. package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
  18. package/dist/components/dashboard/layouts/Sidebar.js +8 -6
  19. package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
  20. package/dist/components/dashboard/layouts/TopNavbar.js +51 -54
  21. package/dist/components/dashboard/misc/NotificationsDropdown.d.ts.map +1 -1
  22. package/dist/components/dashboard/misc/NotificationsDropdown.js +17 -15
  23. package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
  24. package/dist/components/dashboard/misc/SearchDropdown.js +19 -22
  25. package/dist/components/dashboard/mobile/MobileBottomNav.js +1 -1
  26. package/dist/components/dashboard/mobile/MobileTopBar.js +2 -2
  27. package/dist/components/dashboard/navigation/DynamicNavigation.js +5 -5
  28. package/dist/components/devtools/BlockDetailViewer.js +1 -1
  29. package/dist/components/devtools/BlocksViewer.js +1 -1
  30. package/dist/components/entities/EntityChildManager.js +5 -5
  31. package/dist/components/entities/EntityDetailPage.d.ts.map +1 -1
  32. package/dist/components/entities/EntityDetailPage.js +16 -15
  33. package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
  34. package/dist/components/entities/EntityFieldRenderer.js +12 -7
  35. package/dist/components/entities/EntityPageHeader.js +5 -5
  36. package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
  37. package/dist/components/entities/ErrorBoundary.js +20 -21
  38. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -5
  39. package/dist/components/entities/wrappers/EntityFormWrapper.js +2 -2
  40. package/dist/components/entities/wrappers/EntityListWrapper.js +3 -3
  41. package/dist/components/permissions/NoPermission.js +10 -10
  42. package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
  43. package/dist/components/public/pageBuilder/PageRenderer.js +2 -1
  44. package/dist/components/settings/SettingsPageSkeleton.js +4 -4
  45. package/dist/components/settings/layouts/SettingsSidebar.js +6 -6
  46. package/dist/components/shared/MultiSelectFilter.d.ts +3 -1
  47. package/dist/components/shared/MultiSelectFilter.d.ts.map +1 -1
  48. package/dist/components/shared/MultiSelectFilter.js +7 -3
  49. package/dist/components/shared/SearchInput.d.ts +2 -0
  50. package/dist/components/shared/SearchInput.d.ts.map +1 -1
  51. package/dist/components/shared/SearchInput.js +64 -6
  52. package/dist/components/ui/address-input.js +18 -18
  53. package/dist/components/ui/audio-upload.js +9 -9
  54. package/dist/components/ui/combobox.d.ts.map +1 -1
  55. package/dist/components/ui/combobox.js +4 -4
  56. package/dist/components/ui/country-select.d.ts.map +1 -1
  57. package/dist/components/ui/country-select.js +3 -3
  58. package/dist/components/ui/currency-select.d.ts.map +1 -1
  59. package/dist/components/ui/currency-select.js +3 -3
  60. package/dist/components/ui/dynamic-icon.d.ts.map +1 -1
  61. package/dist/components/ui/dynamic-icon.js +3 -2
  62. package/dist/components/ui/file-upload.js +7 -7
  63. package/dist/components/ui/image-upload.js +8 -8
  64. package/dist/components/ui/multi-select.d.ts +2 -1
  65. package/dist/components/ui/multi-select.d.ts.map +1 -1
  66. package/dist/components/ui/multi-select.js +4 -3
  67. package/dist/components/ui/phone-input.d.ts.map +1 -1
  68. package/dist/components/ui/phone-input.js +3 -3
  69. package/dist/components/ui/relation-display.js +1 -1
  70. package/dist/components/ui/simple-relation-select.d.ts +2 -1
  71. package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
  72. package/dist/components/ui/simple-relation-select.js +7 -6
  73. package/dist/components/ui/tags-input.d.ts.map +1 -1
  74. package/dist/components/ui/tags-input.js +1 -1
  75. package/dist/components/ui/timezone-select.d.ts.map +1 -1
  76. package/dist/components/ui/timezone-select.js +3 -3
  77. package/dist/components/ui/user-display.js +4 -4
  78. package/dist/components/ui/user-select.d.ts.map +1 -1
  79. package/dist/components/ui/user-select.js +9 -9
  80. package/dist/components/ui/video-upload.js +9 -9
  81. package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
  82. package/dist/contexts/SubscriptionContext.js +5 -1
  83. package/dist/contexts/TeamContext.d.ts.map +1 -1
  84. package/dist/contexts/TeamContext.js +83 -26
  85. package/dist/emails/otp-verification.d.ts.map +1 -1
  86. package/dist/emails/otp-verification.js +3 -2
  87. package/dist/hooks/useAccountPreferencesSync.d.ts +13 -0
  88. package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -0
  89. package/dist/hooks/useAccountPreferencesSync.js +95 -0
  90. package/dist/hooks/useAuth.d.ts +202 -15
  91. package/dist/hooks/useAuth.d.ts.map +1 -1
  92. package/dist/hooks/useAuth.js +49 -13
  93. package/dist/hooks/useEntityConfig.js +2 -2
  94. package/dist/hooks/useEntitySearch.js +10 -10
  95. package/dist/hooks/useNotifications.js +12 -12
  96. package/dist/hooks/usePrefetch.d.ts.map +1 -1
  97. package/dist/hooks/usePrefetch.js +6 -2
  98. package/dist/hooks/useSearch.js +15 -15
  99. package/dist/hooks/useSessionCookieRefresh.d.ts +18 -1
  100. package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -1
  101. package/dist/hooks/useSessionCookieRefresh.js +17 -4
  102. package/dist/hooks/useSessionHint.d.ts +12 -0
  103. package/dist/hooks/useSessionHint.d.ts.map +1 -0
  104. package/dist/hooks/useSessionHint.js +15 -0
  105. package/dist/hooks/useTranslationPreload.js +6 -6
  106. package/dist/i18n.d.ts +13 -0
  107. package/dist/i18n.d.ts.map +1 -1
  108. package/dist/i18n.js +2 -27
  109. package/dist/lib/actions/entity.actions.d.ts.map +1 -1
  110. package/dist/lib/actions/entity.actions.js +3 -2
  111. package/dist/lib/api/auth/dual-auth.d.ts +4 -1
  112. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  113. package/dist/lib/api/auth/dual-auth.js +5 -16
  114. package/dist/lib/api/entities.js +33 -33
  115. package/dist/lib/api/keys.d.ts +27 -27
  116. package/dist/lib/api/keys.js +27 -27
  117. package/dist/lib/auth/callback-url.d.ts +11 -0
  118. package/dist/lib/auth/callback-url.d.ts.map +1 -0
  119. package/dist/lib/auth/callback-url.js +14 -0
  120. package/dist/lib/auth/otp-config.d.ts +55 -0
  121. package/dist/lib/auth/otp-config.d.ts.map +1 -0
  122. package/dist/lib/auth/otp-config.js +48 -0
  123. package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
  124. package/dist/lib/auth/registration-helpers.js +3 -1
  125. package/dist/lib/auth/session-hint.d.ts +31 -0
  126. package/dist/lib/auth/session-hint.d.ts.map +1 -0
  127. package/dist/lib/auth/session-hint.js +37 -0
  128. package/dist/lib/auth.d.ts.map +1 -1
  129. package/dist/lib/auth.js +6 -4
  130. package/dist/lib/blocks/loader.d.ts +3 -11
  131. package/dist/lib/blocks/loader.d.ts.map +1 -1
  132. package/dist/lib/blocks/loader.js +1 -9
  133. package/dist/lib/blocks/loader.server.d.ts +18 -0
  134. package/dist/lib/blocks/loader.server.d.ts.map +1 -0
  135. package/dist/lib/blocks/loader.server.js +11 -0
  136. package/dist/lib/blocks/sanitize-html.d.ts +31 -0
  137. package/dist/lib/blocks/sanitize-html.d.ts.map +1 -0
  138. package/dist/lib/blocks/sanitize-html.js +60 -0
  139. package/dist/lib/config/config-sync.d.ts +1 -0
  140. package/dist/lib/config/config-sync.d.ts.map +1 -1
  141. package/dist/lib/config/config-sync.js +4 -1
  142. package/dist/lib/config/types.d.ts +48 -0
  143. package/dist/lib/config/types.d.ts.map +1 -1
  144. package/dist/lib/email/types.d.ts +6 -0
  145. package/dist/lib/email/types.d.ts.map +1 -1
  146. package/dist/lib/entities/serialization.d.ts.map +1 -1
  147. package/dist/lib/entities/serialization.js +3 -6
  148. package/dist/lib/icons.d.ts +12 -0
  149. package/dist/lib/icons.d.ts.map +1 -0
  150. package/dist/lib/icons.js +30 -0
  151. package/dist/lib/locale.d.ts +25 -1
  152. package/dist/lib/locale.d.ts.map +1 -1
  153. package/dist/lib/locale.js +49 -35
  154. package/dist/lib/mcp/engine.js +1 -1
  155. package/dist/lib/mcp/errors.js +17 -17
  156. package/dist/lib/mcp/schema-builder.js +16 -16
  157. package/dist/lib/mcp/tool-generator.js +18 -18
  158. package/dist/lib/search-highlighting.d.ts +7 -0
  159. package/dist/lib/search-highlighting.d.ts.map +1 -1
  160. package/dist/lib/search-highlighting.js +6 -2
  161. package/dist/lib/selectors/core-selectors.d.ts +2 -0
  162. package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
  163. package/dist/lib/selectors/domains/auth.selectors.d.ts +1 -0
  164. package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
  165. package/dist/lib/selectors/domains/auth.selectors.js +1 -0
  166. package/dist/lib/selectors/domains/entities.selectors.d.ts +2 -0
  167. package/dist/lib/selectors/domains/entities.selectors.d.ts.map +1 -1
  168. package/dist/lib/selectors/domains/entities.selectors.js +2 -0
  169. package/dist/lib/selectors/selectors.d.ts +4 -0
  170. package/dist/lib/selectors/selectors.d.ts.map +1 -1
  171. package/dist/lib/services/block.service.js +1 -1
  172. package/dist/lib/teams/active-team-cookie.d.ts +24 -0
  173. package/dist/lib/teams/active-team-cookie.d.ts.map +1 -0
  174. package/dist/lib/teams/active-team-cookie.js +17 -0
  175. package/dist/lib/teams/dashboard-team.d.ts +20 -0
  176. package/dist/lib/teams/dashboard-team.d.ts.map +1 -0
  177. package/dist/lib/teams/dashboard-team.js +38 -0
  178. package/dist/lib/teams/schema.d.ts.map +1 -1
  179. package/dist/lib/teams/schema.js +1 -1
  180. package/dist/lib/template-resolver.d.ts.map +1 -1
  181. package/dist/lib/template-resolver.js +0 -1
  182. package/dist/lib/theme/get-default-theme-mode.d.ts +7 -4
  183. package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
  184. package/dist/lib/theme/get-default-theme-mode.js +2 -44
  185. package/dist/messages/de/auth.json +4 -2
  186. package/dist/messages/de/common.json +83 -3
  187. package/dist/messages/de/email.json +1 -1
  188. package/dist/messages/de/index.d.ts +87 -0
  189. package/dist/messages/de/index.d.ts.map +1 -1
  190. package/dist/messages/de/settings.json +5 -0
  191. package/dist/messages/en/auth.json +4 -2
  192. package/dist/messages/en/common.json +83 -3
  193. package/dist/messages/en/email.json +1 -1
  194. package/dist/messages/en/index.d.ts +86 -0
  195. package/dist/messages/en/index.d.ts.map +1 -1
  196. package/dist/messages/en/settings.json +4 -0
  197. package/dist/messages/es/auth.json +4 -2
  198. package/dist/messages/es/common.json +83 -3
  199. package/dist/messages/es/email.json +1 -1
  200. package/dist/messages/es/index.d.ts +86 -0
  201. package/dist/messages/es/index.d.ts.map +1 -1
  202. package/dist/messages/es/settings.json +4 -0
  203. package/dist/messages/fr/auth.json +4 -2
  204. package/dist/messages/fr/common.json +83 -3
  205. package/dist/messages/fr/email.json +1 -1
  206. package/dist/messages/fr/index.d.ts +87 -0
  207. package/dist/messages/fr/index.d.ts.map +1 -1
  208. package/dist/messages/fr/settings.json +5 -0
  209. package/dist/messages/it/auth.json +4 -2
  210. package/dist/messages/it/common.json +83 -3
  211. package/dist/messages/it/email.json +1 -1
  212. package/dist/messages/it/index.d.ts +87 -0
  213. package/dist/messages/it/index.d.ts.map +1 -1
  214. package/dist/messages/it/settings.json +5 -0
  215. package/dist/messages/pt/auth.json +4 -2
  216. package/dist/messages/pt/common.json +83 -3
  217. package/dist/messages/pt/email.json +1 -1
  218. package/dist/messages/pt/index.d.ts +87 -0
  219. package/dist/messages/pt/index.d.ts.map +1 -1
  220. package/dist/messages/pt/settings.json +5 -0
  221. package/dist/nextspark-registries.d.ts +54 -0
  222. package/dist/providers/DashboardProviders.d.ts +13 -10
  223. package/dist/providers/DashboardProviders.d.ts.map +1 -1
  224. package/dist/providers/DashboardProviders.js +7 -1
  225. package/dist/templates/app/(auth)/forgot-password/page.tsx +2 -2
  226. package/dist/templates/app/(auth)/reset-password/page.tsx +6 -6
  227. package/dist/templates/app/403/page.tsx +6 -6
  228. package/dist/templates/app/api/v1/teams/switch/route.ts +24 -5
  229. package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
  230. package/dist/templates/app/dashboard/(main)/layout.tsx +4 -3
  231. package/dist/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
  232. package/dist/templates/app/dashboard/settings/profile/page.tsx +7 -6
  233. package/dist/templates/app/dashboard/settings/security/page.tsx +5 -4
  234. package/dist/templates/app/layout.ppr.tsx +8 -8
  235. package/dist/templates/app/layout.tsx +12 -17
  236. package/dist/templates/blocks/cta-section/component.tsx +5 -2
  237. package/dist/templates/blocks/cta-section/config.ts +3 -2
  238. package/dist/templates/blocks/cta-section/fields.ts +2 -2
  239. package/dist/templates/blocks/cta-section/schema.ts +2 -2
  240. package/dist/templates/blocks/features-grid/component.tsx +10 -2
  241. package/dist/templates/blocks/features-grid/config.ts +3 -2
  242. package/dist/templates/blocks/features-grid/fields.ts +2 -2
  243. package/dist/templates/blocks/features-grid/schema.ts +2 -2
  244. package/dist/templates/blocks/hero/component.tsx +6 -3
  245. package/dist/templates/blocks/hero/config.ts +3 -2
  246. package/dist/templates/blocks/hero/fields.ts +2 -2
  247. package/dist/templates/blocks/hero/schema.ts +2 -2
  248. package/dist/templates/blocks/testimonials/component.tsx +6 -3
  249. package/dist/templates/blocks/testimonials/config.ts +3 -2
  250. package/dist/templates/blocks/testimonials/fields.ts +2 -2
  251. package/dist/templates/blocks/testimonials/schema.ts +2 -2
  252. package/dist/templates/blocks/text-content/component.tsx +7 -3
  253. package/dist/templates/blocks/text-content/config.ts +3 -2
  254. package/dist/templates/blocks/text-content/fields.ts +2 -2
  255. package/dist/templates/blocks/text-content/schema.ts +2 -2
  256. package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
  257. package/dist/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
  258. package/dist/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
  259. package/dist/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
  260. package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
  261. package/dist/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
  262. package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
  263. package/dist/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
  264. package/dist/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
  265. package/dist/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
  266. package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
  267. package/dist/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
  268. package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
  269. package/dist/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
  270. package/dist/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
  271. package/dist/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
  272. package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
  273. package/dist/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
  274. package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
  275. package/dist/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
  276. package/dist/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
  277. package/dist/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
  278. package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
  279. package/dist/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
  280. package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
  281. package/dist/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
  282. package/dist/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
  283. package/dist/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
  284. package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
  285. package/dist/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
  286. package/dist/templates/contents/themes/starter/config/app.config.ts +8 -0
  287. package/dist/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
  288. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
  289. package/dist/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
  290. package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
  291. package/dist/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
  292. package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
  293. package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
  294. package/dist/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
  295. package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
  296. package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
  297. package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
  298. package/dist/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
  299. package/dist/templates/features/blog/blocks/post-content/component.tsx +5 -1
  300. package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
  301. package/dist/templates/features/pages/blocks/hero/component.tsx +3 -0
  302. package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
  303. package/dist/templates/proxy.ts +138 -53
  304. package/dist/types/blocks.d.ts.map +1 -1
  305. package/dist/types/blocks.js +1 -1
  306. package/dist/types/task.types.d.ts +1 -1
  307. package/dist/types/task.types.js +7 -7
  308. package/dist/utils/dev/TranslationDebugger.js +2 -2
  309. package/package.json +14 -5
  310. package/scripts/build/registry/__tests__/block-registry.test.mjs +73 -0
  311. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +130 -0
  312. package/scripts/build/registry/__tests__/identifier.test.mjs +65 -0
  313. package/scripts/build/registry/__tests__/page-generator.test.mjs +430 -0
  314. package/scripts/build/registry/__tests__/scheduled-actions-registry.test.mjs +41 -0
  315. package/scripts/build/registry/__tests__/template-registry.test.mjs +89 -0
  316. package/scripts/build/registry/discovery/icons.mjs +275 -0
  317. package/scripts/build/registry/discovery/index.mjs +1 -0
  318. package/scripts/build/registry/generators/block-registry.mjs +203 -55
  319. package/scripts/build/registry/generators/feature-registry.mjs +9 -2
  320. package/scripts/build/registry/generators/icon-registry.mjs +56 -0
  321. package/scripts/build/registry/generators/identifier.mjs +28 -0
  322. package/scripts/build/registry/generators/index.mjs +1 -0
  323. package/scripts/build/registry/generators/plugin-registry.mjs +4 -3
  324. package/scripts/build/registry/generators/scheduled-actions-registry.mjs +4 -2
  325. package/scripts/build/registry/generators/template-registry.mjs +49 -41
  326. package/scripts/build/registry/generators/theme-registry.mjs +6 -7
  327. package/scripts/build/registry/post-build/page-generator.mjs +380 -59
  328. package/scripts/build/registry.mjs +9 -1
  329. package/templates/app/(auth)/forgot-password/page.tsx +2 -2
  330. package/templates/app/(auth)/reset-password/page.tsx +6 -6
  331. package/templates/app/403/page.tsx +6 -6
  332. package/templates/app/api/v1/teams/switch/route.ts +24 -5
  333. package/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
  334. package/templates/app/dashboard/(main)/layout.tsx +4 -3
  335. package/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
  336. package/templates/app/dashboard/settings/profile/page.tsx +7 -6
  337. package/templates/app/dashboard/settings/security/page.tsx +5 -4
  338. package/templates/app/layout.ppr.tsx +8 -8
  339. package/templates/app/layout.tsx +12 -17
  340. package/templates/blocks/cta-section/component.tsx +5 -2
  341. package/templates/blocks/cta-section/config.ts +3 -2
  342. package/templates/blocks/cta-section/fields.ts +2 -2
  343. package/templates/blocks/cta-section/schema.ts +2 -2
  344. package/templates/blocks/features-grid/component.tsx +10 -2
  345. package/templates/blocks/features-grid/config.ts +3 -2
  346. package/templates/blocks/features-grid/fields.ts +2 -2
  347. package/templates/blocks/features-grid/schema.ts +2 -2
  348. package/templates/blocks/hero/component.tsx +6 -3
  349. package/templates/blocks/hero/config.ts +3 -2
  350. package/templates/blocks/hero/fields.ts +2 -2
  351. package/templates/blocks/hero/schema.ts +2 -2
  352. package/templates/blocks/testimonials/component.tsx +6 -3
  353. package/templates/blocks/testimonials/config.ts +3 -2
  354. package/templates/blocks/testimonials/fields.ts +2 -2
  355. package/templates/blocks/testimonials/schema.ts +2 -2
  356. package/templates/blocks/text-content/component.tsx +7 -3
  357. package/templates/blocks/text-content/config.ts +3 -2
  358. package/templates/blocks/text-content/fields.ts +2 -2
  359. package/templates/blocks/text-content/schema.ts +2 -2
  360. package/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
  361. package/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
  362. package/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
  363. package/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
  364. package/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
  365. package/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
  366. package/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
  367. package/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
  368. package/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
  369. package/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
  370. package/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
  371. package/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
  372. package/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
  373. package/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
  374. package/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
  375. package/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
  376. package/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
  377. package/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
  378. package/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
  379. package/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
  380. package/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
  381. package/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
  382. package/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
  383. package/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
  384. package/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
  385. package/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
  386. package/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
  387. package/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
  388. package/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
  389. package/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
  390. package/templates/contents/themes/starter/config/app.config.ts +8 -0
  391. package/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
  392. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
  393. package/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
  394. package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
  395. package/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
  396. package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
  397. package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
  398. package/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
  399. package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
  400. package/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
  401. package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
  402. package/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
  403. package/templates/features/blog/blocks/post-content/component.tsx +5 -1
  404. package/templates/features/blog/blocks/post-content/schema.ts +1 -1
  405. package/templates/features/pages/blocks/hero/component.tsx +3 -0
  406. package/templates/features/pages/blocks/hero/schema.ts +1 -1
  407. package/templates/proxy.ts +138 -53
  408. package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.client.ts +9 -0
  409. package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.lazy.ts +5 -0
  410. package/tests/jest/__mocks__/@nextsparkjs/registries/icon-registry.ts +42 -0
  411. package/tests/jest/__mocks__/next-intl-server.js +85 -5
  412. package/tests/jest/__mocks__/next-server.js +32 -0
@@ -79,13 +79,13 @@ class EntityApiClient {
79
79
  });
80
80
  if (!response.ok) {
81
81
  const errorData = await response.json().catch(() => ({}));
82
- let userMessage = `Error al cargar ${entityType}`;
82
+ let userMessage = `Failed to load ${entityType}`;
83
83
  if (response.status === 401) {
84
- userMessage = "No tienes permisos para acceder a estos datos. Por favor, inicia sesi\xF3n nuevamente.";
84
+ userMessage = "You do not have permission to access this data. Please sign in again.";
85
85
  } else if (response.status === 403) {
86
- userMessage = "No tienes los permisos necesarios para realizar esta acci\xF3n.";
86
+ userMessage = "You do not have the necessary permissions to perform this action.";
87
87
  } else if (response.status === 404) {
88
- userMessage = "Los datos solicitados no fueron encontrados.";
88
+ userMessage = "The requested data was not found.";
89
89
  } else if (response.status === 400 && errorData.code === "TEAM_CONTEXT_REQUIRED") {
90
90
  console.warn("[EntityApiClient] Team context not ready yet, returning empty list");
91
91
  return {
@@ -102,7 +102,7 @@ class EntityApiClient {
102
102
  }
103
103
  };
104
104
  } else if (response.status >= 500) {
105
- userMessage = "Error interno del servidor. Por favor, intenta m\xE1s tarde.";
105
+ userMessage = "Internal server error. Please try again later.";
106
106
  } else if (errorData.message && !errorData.message.includes("API key")) {
107
107
  userMessage = errorData.message;
108
108
  }
@@ -127,15 +127,15 @@ class EntityApiClient {
127
127
  });
128
128
  if (!response.ok) {
129
129
  const errorData = await response.json().catch(() => ({}));
130
- let userMessage = `Error al cargar ${entityType}`;
130
+ let userMessage = `Failed to load ${entityType}`;
131
131
  if (response.status === 401) {
132
- userMessage = "No tienes permisos para acceder a estos datos. Por favor, inicia sesi\xF3n nuevamente.";
132
+ userMessage = "You do not have permission to access this data. Please sign in again.";
133
133
  } else if (response.status === 403) {
134
- userMessage = "No tienes los permisos necesarios para realizar esta acci\xF3n.";
134
+ userMessage = "You do not have the necessary permissions to perform this action.";
135
135
  } else if (response.status === 404) {
136
- userMessage = "El elemento solicitado no fue encontrado.";
136
+ userMessage = "The requested item was not found.";
137
137
  } else if (response.status >= 500) {
138
- userMessage = "Error interno del servidor. Por favor, intenta m\xE1s tarde.";
138
+ userMessage = "Internal server error. Please try again later.";
139
139
  } else if (errorData.message && !errorData.message.includes("API key")) {
140
140
  userMessage = errorData.message;
141
141
  }
@@ -158,15 +158,15 @@ class EntityApiClient {
158
158
  });
159
159
  if (!response.ok) {
160
160
  const errorData = await response.json().catch(() => ({}));
161
- let userMessage = `Error al crear ${entityType}`;
161
+ let userMessage = `Failed to create ${entityType}`;
162
162
  if (response.status === 401) {
163
- userMessage = "No tienes permisos para crear este elemento. Por favor, inicia sesi\xF3n nuevamente.";
163
+ userMessage = "You do not have permission to create this item. Please sign in again.";
164
164
  } else if (response.status === 403) {
165
- userMessage = "No tienes los permisos necesarios para crear este elemento.";
165
+ userMessage = "You do not have the necessary permissions to create this item.";
166
166
  } else if (response.status === 400) {
167
- userMessage = "Los datos proporcionados no son v\xE1lidos. Por favor, revisa el formulario.";
167
+ userMessage = "The provided data is not valid. Please review the form.";
168
168
  } else if (response.status >= 500) {
169
- userMessage = "Error interno del servidor. Por favor, intenta m\xE1s tarde.";
169
+ userMessage = "Internal server error. Please try again later.";
170
170
  } else if (errorData.message && !errorData.message.includes("API key")) {
171
171
  userMessage = errorData.message;
172
172
  }
@@ -189,17 +189,17 @@ class EntityApiClient {
189
189
  });
190
190
  if (!response.ok) {
191
191
  const errorData = await response.json().catch(() => ({}));
192
- let userMessage = `Error al actualizar ${entityType}`;
192
+ let userMessage = `Failed to update ${entityType}`;
193
193
  if (response.status === 401) {
194
- userMessage = "No tienes permisos para actualizar este elemento. Por favor, inicia sesi\xF3n nuevamente.";
194
+ userMessage = "You do not have permission to update this item. Please sign in again.";
195
195
  } else if (response.status === 403) {
196
- userMessage = "No tienes los permisos necesarios para actualizar este elemento.";
196
+ userMessage = "You do not have the necessary permissions to update this item.";
197
197
  } else if (response.status === 404) {
198
- userMessage = "El elemento que intentas actualizar no fue encontrado.";
198
+ userMessage = "The item you are trying to update was not found.";
199
199
  } else if (response.status === 400) {
200
- userMessage = "Los datos proporcionados no son v\xE1lidos. Por favor, revisa el formulario.";
200
+ userMessage = "The provided data is not valid. Please review the form.";
201
201
  } else if (response.status >= 500) {
202
- userMessage = "Error interno del servidor. Por favor, intenta m\xE1s tarde.";
202
+ userMessage = "Internal server error. Please try again later.";
203
203
  } else if (errorData.message && !errorData.message.includes("API key")) {
204
204
  userMessage = errorData.message;
205
205
  }
@@ -221,15 +221,15 @@ class EntityApiClient {
221
221
  });
222
222
  if (!response.ok) {
223
223
  const errorData = await response.json().catch(() => ({}));
224
- let userMessage = `Error al eliminar ${entityType}`;
224
+ let userMessage = `Failed to delete ${entityType}`;
225
225
  if (response.status === 401) {
226
- userMessage = "No tienes permisos para eliminar este elemento. Por favor, inicia sesi\xF3n nuevamente.";
226
+ userMessage = "You do not have permission to delete this item. Please sign in again.";
227
227
  } else if (response.status === 403) {
228
- userMessage = "No tienes los permisos necesarios para eliminar este elemento.";
228
+ userMessage = "You do not have the necessary permissions to delete this item.";
229
229
  } else if (response.status === 404) {
230
- userMessage = "El elemento que intentas eliminar no fue encontrado.";
230
+ userMessage = "The item you are trying to delete was not found.";
231
231
  } else if (response.status >= 500) {
232
- userMessage = "Error interno del servidor. Por favor, intenta m\xE1s tarde.";
232
+ userMessage = "Internal server error. Please try again later.";
233
233
  } else if (errorData.message && !errorData.message.includes("API key")) {
234
234
  userMessage = errorData.message;
235
235
  }
@@ -333,8 +333,8 @@ class EntityApiClient {
333
333
  if (entityConfig.features.canDelete) {
334
334
  operations.push({
335
335
  id: "bulk-delete",
336
- name: "Eliminar Seleccionados",
337
- description: "Eliminar m\xFAltiples elementos a la vez",
336
+ name: "Delete Selected",
337
+ description: "Delete multiple items at once",
338
338
  icon: "trash",
339
339
  requiresConfirmation: true
340
340
  });
@@ -342,15 +342,15 @@ class EntityApiClient {
342
342
  if (entityConfig.features.canEdit) {
343
343
  operations.push({
344
344
  id: "bulk-edit",
345
- name: "Editar Seleccionados",
346
- description: "Actualizar m\xFAltiples elementos a la vez",
345
+ name: "Edit Selected",
346
+ description: "Update multiple items at once",
347
347
  icon: "edit"
348
348
  });
349
349
  }
350
350
  operations.push({
351
351
  id: "bulk-export",
352
- name: "Exportar",
353
- description: "Exportar datos seleccionados",
352
+ name: "Export",
353
+ description: "Export selected data",
354
354
  icon: "download"
355
355
  });
356
356
  return operations;
@@ -376,7 +376,7 @@ class EntityApiClient {
376
376
  });
377
377
  if (!response.ok) {
378
378
  const errorData = await response.json().catch(() => ({}));
379
- throw new Error(errorData.message || `Error ejecutando operaci\xF3n ${operationId}`);
379
+ throw new Error(errorData.message || `Error executing operation ${operationId}`);
380
380
  }
381
381
  const result = await response.json();
382
382
  return result.data;
@@ -39,24 +39,24 @@ export declare class ApiKeyManager {
39
39
  * Definición de scopes disponibles para API keys
40
40
  */
41
41
  export declare const API_SCOPES: {
42
- readonly 'users:read': "Leer información de usuarios";
43
- readonly 'users:write': "Crear y actualizar usuarios";
44
- readonly 'users:delete': "Eliminar usuarios";
45
- readonly 'tasks:read': "Leer tasks";
46
- readonly 'tasks:write': "Crear y actualizar tasks";
47
- readonly 'tasks:delete': "Eliminar tasks";
48
- readonly 'media:read': "Leer información de archivos y media";
49
- readonly 'media:write': "Subir y actualizar archivos";
50
- readonly 'media:delete': "Eliminar archivos";
51
- readonly 'teams:read': "Leer equipos, miembros e invitaciones";
52
- readonly 'teams:write': "Crear y actualizar equipos, miembros e invitaciones";
53
- readonly 'teams:delete': "Eliminar equipos";
54
- readonly 'billing:read': "Leer suscripciones, facturas y uso";
55
- readonly 'billing:write': "Gestionar suscripciones, checkout, cambios de plan y uso";
56
- readonly 'admin:api-keys': "Gestionar API keys";
57
- readonly 'admin:users': "Administración completa de usuarios";
58
- readonly 'admin:devtools': "Acceso a las APIs de DevTools (registries, testing, scheduled actions)";
59
- readonly '*': "Acceso completo (solo superadmin)";
42
+ readonly 'users:read': "Read user information";
43
+ readonly 'users:write': "Create and update users";
44
+ readonly 'users:delete': "Delete users";
45
+ readonly 'tasks:read': "Read tasks";
46
+ readonly 'tasks:write': "Create and update tasks";
47
+ readonly 'tasks:delete': "Delete tasks";
48
+ readonly 'media:read': "Read file and media information";
49
+ readonly 'media:write': "Upload and update files";
50
+ readonly 'media:delete': "Delete files";
51
+ readonly 'teams:read': "Read teams, members and invitations";
52
+ readonly 'teams:write': "Create and update teams, members and invitations";
53
+ readonly 'teams:delete': "Delete teams";
54
+ readonly 'billing:read': "Read subscriptions, invoices and usage";
55
+ readonly 'billing:write': "Manage subscriptions, checkout, plan changes and usage";
56
+ readonly 'admin:api-keys': "Manage API keys";
57
+ readonly 'admin:users': "Full user administration";
58
+ readonly 'admin:devtools': "Access to DevTools APIs (registries, testing, scheduled actions)";
59
+ readonly '*': "Full access (superadmin only)";
60
60
  };
61
61
  export type ApiScope = keyof typeof API_SCOPES;
62
62
  /**
@@ -79,33 +79,33 @@ export declare function getAppApiScopes(): Record<string, string>;
79
79
  */
80
80
  export declare const SCOPE_CATEGORIES: {
81
81
  readonly users: {
82
- readonly name: "Usuarios";
83
- readonly description: "Gestión de usuarios del sistema";
82
+ readonly name: "Users";
83
+ readonly description: "System user management";
84
84
  readonly scopes: ApiScope[];
85
85
  };
86
86
  readonly tasks: {
87
87
  readonly name: "Tasks";
88
- readonly description: "Gestión de tareas y TODOs";
88
+ readonly description: "Task and TODO management";
89
89
  readonly scopes: ApiScope[];
90
90
  };
91
91
  readonly teams: {
92
92
  readonly name: "Teams";
93
- readonly description: "Equipos, miembros e invitaciones";
93
+ readonly description: "Teams, members and invitations";
94
94
  readonly scopes: ApiScope[];
95
95
  };
96
96
  readonly billing: {
97
97
  readonly name: "Billing";
98
- readonly description: "Suscripciones, facturas, uso y planes";
98
+ readonly description: "Subscriptions, invoices, usage and plans";
99
99
  readonly scopes: ApiScope[];
100
100
  };
101
101
  readonly admin: {
102
- readonly name: "Administración";
103
- readonly description: "Funciones administrativas";
102
+ readonly name: "Administration";
103
+ readonly description: "Administrative functions";
104
104
  readonly scopes: ApiScope[];
105
105
  };
106
106
  readonly system: {
107
- readonly name: "Sistema";
108
- readonly description: "Acceso completo al sistema";
107
+ readonly name: "System";
108
+ readonly description: "Full system access";
109
109
  readonly scopes: ApiScope[];
110
110
  };
111
111
  };
@@ -70,30 +70,30 @@ class ApiKeyManager {
70
70
  }
71
71
  const API_SCOPES = {
72
72
  // Usuarios
73
- "users:read": "Leer informaci\xF3n de usuarios",
74
- "users:write": "Crear y actualizar usuarios",
75
- "users:delete": "Eliminar usuarios",
73
+ "users:read": "Read user information",
74
+ "users:write": "Create and update users",
75
+ "users:delete": "Delete users",
76
76
  // Tasks
77
- "tasks:read": "Leer tasks",
78
- "tasks:write": "Crear y actualizar tasks",
79
- "tasks:delete": "Eliminar tasks",
77
+ "tasks:read": "Read tasks",
78
+ "tasks:write": "Create and update tasks",
79
+ "tasks:delete": "Delete tasks",
80
80
  // Media (archivos, imágenes, videos)
81
- "media:read": "Leer informaci\xF3n de archivos y media",
82
- "media:write": "Subir y actualizar archivos",
83
- "media:delete": "Eliminar archivos",
81
+ "media:read": "Read file and media information",
82
+ "media:write": "Upload and update files",
83
+ "media:delete": "Delete files",
84
84
  // Teams (equipos, miembros e invitaciones)
85
- "teams:read": "Leer equipos, miembros e invitaciones",
86
- "teams:write": "Crear y actualizar equipos, miembros e invitaciones",
87
- "teams:delete": "Eliminar equipos",
85
+ "teams:read": "Read teams, members and invitations",
86
+ "teams:write": "Create and update teams, members and invitations",
87
+ "teams:delete": "Delete teams",
88
88
  // Billing (suscripciones, facturas, uso y planes)
89
- "billing:read": "Leer suscripciones, facturas y uso",
90
- "billing:write": "Gestionar suscripciones, checkout, cambios de plan y uso",
89
+ "billing:read": "Read subscriptions, invoices and usage",
90
+ "billing:write": "Manage subscriptions, checkout, plan changes and usage",
91
91
  // Administración
92
- "admin:api-keys": "Gestionar API keys",
93
- "admin:users": "Administraci\xF3n completa de usuarios",
94
- "admin:devtools": "Acceso a las APIs de DevTools (registries, testing, scheduled actions)",
92
+ "admin:api-keys": "Manage API keys",
93
+ "admin:users": "Full user administration",
94
+ "admin:devtools": "Access to DevTools APIs (registries, testing, scheduled actions)",
95
95
  // Comodín (solo para superadmins)
96
- "*": "Acceso completo (solo superadmin)"
96
+ "*": "Full access (superadmin only)"
97
97
  };
98
98
  function getApiScopes() {
99
99
  var _a;
@@ -108,33 +108,33 @@ function getAppApiScopes() {
108
108
  }
109
109
  const SCOPE_CATEGORIES = {
110
110
  users: {
111
- name: "Usuarios",
112
- description: "Gesti\xF3n de usuarios del sistema",
111
+ name: "Users",
112
+ description: "System user management",
113
113
  scopes: ["users:read", "users:write", "users:delete"]
114
114
  },
115
115
  tasks: {
116
116
  name: "Tasks",
117
- description: "Gesti\xF3n de tareas y TODOs",
117
+ description: "Task and TODO management",
118
118
  scopes: ["tasks:read", "tasks:write", "tasks:delete"]
119
119
  },
120
120
  teams: {
121
121
  name: "Teams",
122
- description: "Equipos, miembros e invitaciones",
122
+ description: "Teams, members and invitations",
123
123
  scopes: ["teams:read", "teams:write", "teams:delete"]
124
124
  },
125
125
  billing: {
126
126
  name: "Billing",
127
- description: "Suscripciones, facturas, uso y planes",
127
+ description: "Subscriptions, invoices, usage and plans",
128
128
  scopes: ["billing:read", "billing:write"]
129
129
  },
130
130
  admin: {
131
- name: "Administraci\xF3n",
132
- description: "Funciones administrativas",
131
+ name: "Administration",
132
+ description: "Administrative functions",
133
133
  scopes: ["admin:api-keys", "admin:users", "admin:devtools"]
134
134
  },
135
135
  system: {
136
- name: "Sistema",
137
- description: "Acceso completo al sistema",
136
+ name: "System",
137
+ description: "Full system access",
138
138
  scopes: ["*"]
139
139
  }
140
140
  };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Callback URL
3
+ *
4
+ * Where sign-in sends the user afterwards. `callbackUrl` arrives in the login
5
+ * URL, where anyone can write it, so only a path on this app counts: `//host`,
6
+ * `/\host` or an absolute URL would take the user to another site right after
7
+ * they authenticate.
8
+ */
9
+ /** The path, query and hash of an in-app callback, or null for anything else. */
10
+ export declare function safeCallbackPath(value: string | null | undefined): string | null;
11
+ //# sourceMappingURL=callback-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-url.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/callback-url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAWhF"}
@@ -0,0 +1,14 @@
1
+ const PLACEHOLDER_ORIGIN = "http://callback.invalid";
2
+ function safeCallbackPath(value) {
3
+ if (!value || !value.startsWith("/")) return null;
4
+ try {
5
+ const url = new URL(value, PLACEHOLDER_ORIGIN);
6
+ const path = `${url.pathname}${url.search}${url.hash}`;
7
+ return url.origin === PLACEHOLDER_ORIGIN && !path.startsWith("//") ? path : null;
8
+ } catch {
9
+ return null;
10
+ }
11
+ }
12
+ export {
13
+ safeCallbackPath
14
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Email OTP Config Resolution
3
+ *
4
+ * Turns the (optional, partially specified) `auth.otp` block of the merged app
5
+ * config into the concrete values handed to Better Auth's emailOTP plugin. Pure
6
+ * function — no side effects besides a `console.warn` on invalid input — so it
7
+ * is safe to import from client code too.
8
+ *
9
+ * Both numbers are read by the server (the plugin) and by the login form (the
10
+ * notice that counts the code down, and the length the input accepts). They
11
+ * live here so the two agree by construction: a duplicated literal is how the
12
+ * UI ends up promising five minutes for a code that lasts two.
13
+ *
14
+ * Resolution rules:
15
+ * - Every field falls back to the core default when missing.
16
+ * - Non-positive / non-finite values are rejected (warning) → default.
17
+ * - `otpLength` is additionally bounded to what Better Auth can generate.
18
+ */
19
+ import type { AuthConfig } from '../config/types';
20
+ export interface ResolvedOtpConfig {
21
+ /** Lifetime of an emailed code, in seconds. */
22
+ expiresIn: number;
23
+ /** Number of digits in an emailed code. */
24
+ otpLength: number;
25
+ }
26
+ export declare const DEFAULT_OTP_CONFIG: ResolvedOtpConfig;
27
+ /**
28
+ * Resolve the email-OTP configuration the app runs with.
29
+ *
30
+ * @param authConfig - The merged `auth` config (core defaults + theme overrides).
31
+ * Only its `otp` block is read; `undefined`/`null` is
32
+ * allowed and yields the defaults.
33
+ */
34
+ export declare function resolveOtpConfig(authConfig?: Pick<AuthConfig, 'otp'> | null): ResolvedOtpConfig;
35
+ /**
36
+ * Seconds left before a code sent at `sentAt` expires, between 0 and the code's
37
+ * lifetime: a clock set back after the request would otherwise count more time
38
+ * than the server gives the code.
39
+ *
40
+ * @param sentAt - Epoch milliseconds of the moment the code was requested.
41
+ * @param expiresIn - Code lifetime in seconds.
42
+ * @param now - Epoch milliseconds to measure against (injectable for tests).
43
+ */
44
+ export declare function getOtpSecondsRemaining(sentAt: number, expiresIn: number, now?: number): number;
45
+ /**
46
+ * Format a remaining-seconds count as `m:ss`, always with both parts so the
47
+ * value reads as a duration on its own (a bare "45" needs a unit the
48
+ * surrounding sentence does not supply).
49
+ *
50
+ * Digits and a colon read the same in every locale this ships with, so the
51
+ * value can be interpolated into a translated sentence without each locale
52
+ * owning a time format.
53
+ */
54
+ export declare function formatOtpCountdown(secondsRemaining: number): string;
55
+ //# sourceMappingURL=otp-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp-config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/otp-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,iBAAiB,CAAA;AAEhE,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,eAAO,MAAM,kBAAkB,EAAE,iBAGhC,CAAA;AA2BD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,IAAI,GAC1C,iBAAiB,CAcnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,MAAmB,GACvB,MAAM,CAGR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAKnE"}
@@ -0,0 +1,48 @@
1
+ const DEFAULT_OTP_CONFIG = {
2
+ expiresIn: 60 * 5,
3
+ // 5 minutes
4
+ otpLength: 6
5
+ };
6
+ const MIN_OTP_LENGTH = 4;
7
+ const MAX_OTP_LENGTH = 10;
8
+ function isPositiveNumber(value) {
9
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
10
+ }
11
+ function resolveNumber(value, fallback, field) {
12
+ if (value === void 0) return fallback;
13
+ if (!isPositiveNumber(value) || Math.floor(value) < 1) {
14
+ console.warn(
15
+ `[Auth] Ignoring invalid auth.otp.${field} (${String(value)}); using default ${fallback}`
16
+ );
17
+ return fallback;
18
+ }
19
+ return Math.floor(value);
20
+ }
21
+ function resolveOtpConfig(authConfig) {
22
+ const cfg = (authConfig == null ? void 0 : authConfig.otp) ?? {};
23
+ const expiresIn = resolveNumber(cfg.expiresIn, DEFAULT_OTP_CONFIG.expiresIn, "expiresIn");
24
+ let otpLength = resolveNumber(cfg.otpLength, DEFAULT_OTP_CONFIG.otpLength, "otpLength");
25
+ if (otpLength < MIN_OTP_LENGTH || otpLength > MAX_OTP_LENGTH) {
26
+ console.warn(
27
+ `[Auth] auth.otp.otpLength (${otpLength}) is outside ${MIN_OTP_LENGTH}-${MAX_OTP_LENGTH}; using default ${DEFAULT_OTP_CONFIG.otpLength}`
28
+ );
29
+ otpLength = DEFAULT_OTP_CONFIG.otpLength;
30
+ }
31
+ return { expiresIn, otpLength };
32
+ }
33
+ function getOtpSecondsRemaining(sentAt, expiresIn, now = Date.now()) {
34
+ const elapsed = Math.floor((now - sentAt) / 1e3);
35
+ return Math.min(expiresIn, Math.max(0, expiresIn - elapsed));
36
+ }
37
+ function formatOtpCountdown(secondsRemaining) {
38
+ const total = Math.max(0, Math.floor(secondsRemaining));
39
+ const minutes = Math.floor(total / 60);
40
+ const seconds = total % 60;
41
+ return `${minutes}:${String(seconds).padStart(2, "0")}`;
42
+ }
43
+ export {
44
+ DEFAULT_OTP_CONFIG,
45
+ formatOtpCountdown,
46
+ getOtpSecondsRemaining,
47
+ resolveOtpConfig
48
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"registration-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/registration-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGrF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAElE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAShF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKnE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKzE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAGT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAY5E"}
1
+ {"version":3,"file":"registration-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/registration-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAIrF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAElE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAShF;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKnE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAKzE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEpE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAGT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAa5E"}
@@ -1,4 +1,5 @@
1
1
  import { resolveAuthMethods } from "./auth-methods.js";
2
+ import { resolveOtpConfig } from "./otp-config.js";
2
3
  function isRegistrationOpen(mode) {
3
4
  return mode === "open" || mode === "domain-open";
4
5
  }
@@ -41,7 +42,8 @@ function getPublicAuthConfig(authConfig) {
41
42
  enabled: isGoogleAuthEnabled(authConfig)
42
43
  }
43
44
  },
44
- methods: resolveAuthMethods(authConfig)
45
+ methods: resolveAuthMethods(authConfig),
46
+ otp: resolveOtpConfig(authConfig)
45
47
  };
46
48
  }
47
49
  export {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Session Hint
3
+ *
4
+ * Better Auth's session cookie is httpOnly, so client code cannot tell whether a
5
+ * visitor is signed in without asking the server. This readable cookie records
6
+ * whether the browser carries a session, and public pages ask for the session
7
+ * only when it says so: an anonymous visitor makes no session request. The proxy
8
+ * keeps it in line with the session cookie on every request, and client code
9
+ * updates it on sign-in, sign-out and each session it reads. It is a hint, never
10
+ * proof of anything: a stale one costs a single request that finds no session.
11
+ */
12
+ export declare const SESSION_HINT_COOKIE = "nextspark.signed_in";
13
+ /** As long as browsers keep a cookie: longer than any session. */
14
+ export declare const SESSION_HINT_MAX_AGE: number;
15
+ /**
16
+ * Whether a Cookie header carries Better Auth's session cookie. It says nothing
17
+ * about whether that session is still valid, only that there may be one to read.
18
+ */
19
+ export declare function hasSessionCookie(cookieHeader: string | null | undefined): boolean;
20
+ /** Whether this browser was signed in when client code last looked. */
21
+ export declare function hasSessionHint(): boolean;
22
+ /** Record whether this browser is signed in. */
23
+ export declare function setSessionHint(signedIn: boolean): void;
24
+ /**
25
+ * Call `onChange` whenever the hint may have changed: client code set it (a
26
+ * sign-in or sign-out on this page), or the tab comes back into view, after
27
+ * responses the proxy answered may have set it. Returns the function that stops
28
+ * listening. Its shape fits React's useSyncExternalStore.
29
+ */
30
+ export declare function subscribeSessionHint(onChange: () => void): () => void;
31
+ //# sourceMappingURL=session-hint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-hint.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/session-hint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAExD,kEAAkE;AAClE,eAAO,MAAM,oBAAoB,QAAqB,CAAA;AAKtD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEjF;AAED,uEAAuE;AACvE,wBAAgB,cAAc,IAAI,OAAO,CAGxC;AAKD,gDAAgD;AAChD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAOtD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAUrE"}
@@ -0,0 +1,37 @@
1
+ const SESSION_HINT_COOKIE = "nextspark.signed_in";
2
+ const SESSION_HINT_MAX_AGE = 60 * 60 * 24 * 400;
3
+ const SESSION_COOKIE = /(?:^|;\s*)(?:__Secure-)?better-auth[.-]session_token=[^;\s]/;
4
+ function hasSessionCookie(cookieHeader) {
5
+ return SESSION_COOKIE.test(cookieHeader ?? "");
6
+ }
7
+ function hasSessionHint() {
8
+ if (typeof document === "undefined") return false;
9
+ return document.cookie.split(";").some((part) => part.trim() === `${SESSION_HINT_COOKIE}=1`);
10
+ }
11
+ const SESSION_HINT_CHANGE_EVENT = "nextspark:session-hint-change";
12
+ function setSessionHint(signedIn) {
13
+ if (typeof document === "undefined" || hasSessionHint() === signedIn) return;
14
+ const secure = typeof location !== "undefined" && location.protocol === "https:" ? "; Secure" : "";
15
+ document.cookie = signedIn ? `${SESSION_HINT_COOKIE}=1; Max-Age=${SESSION_HINT_MAX_AGE}; Path=/; SameSite=Lax${secure}` : `${SESSION_HINT_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax${secure}`;
16
+ window.dispatchEvent(new Event(SESSION_HINT_CHANGE_EVENT));
17
+ }
18
+ function subscribeSessionHint(onChange) {
19
+ if (typeof window === "undefined") return () => {
20
+ };
21
+ window.addEventListener(SESSION_HINT_CHANGE_EVENT, onChange);
22
+ window.addEventListener("focus", onChange);
23
+ document.addEventListener("visibilitychange", onChange);
24
+ return () => {
25
+ window.removeEventListener(SESSION_HINT_CHANGE_EVENT, onChange);
26
+ window.removeEventListener("focus", onChange);
27
+ document.removeEventListener("visibilitychange", onChange);
28
+ };
29
+ }
30
+ export {
31
+ SESSION_HINT_COOKIE,
32
+ SESSION_HINT_MAX_AGE,
33
+ hasSessionCookie,
34
+ hasSessionHint,
35
+ setSessionHint,
36
+ subscribeSessionHint
37
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAevH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+GD,eAAO,MAAM,IAAI,qEAoWf,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,kBAAkB,EAAE,QAAQ,EAAE,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAUA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAgBvH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlF;AAED;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEnF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAoHD,eAAO,MAAM,IAAI,qEAqWf,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,kBAAkB,EAAE,QAAQ,EAAE,CAAC;CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B"}
package/dist/lib/auth.js CHANGED
@@ -16,6 +16,7 @@ import { shouldSkipTeamCreation, getSignupContext } from "./auth-context.js";
16
16
  import { isDomainAllowed } from "./auth/registration-helpers.js";
17
17
  import { registrationGuardPlugin } from "./auth/registration-guard-plugin.js";
18
18
  import { resolveSessionConfig } from "./auth/session-config.js";
19
+ import { resolveOtpConfig } from "./auth/otp-config.js";
19
20
  import { isPasswordLoginEnabled } from "./auth/auth-methods.js";
20
21
  import { getCorsOrigins, isPrivateLanOrigin, normalizeCorsEnvironment } from "./utils/cors.js";
21
22
  async function hasPendingInvitationForEmail(email) {
@@ -45,6 +46,7 @@ const pool = new Pool({
45
46
  max: 20
46
47
  });
47
48
  const sessionConfig = resolveSessionConfig(AUTH_CONFIG);
49
+ const otpConfig = resolveOtpConfig(AUTH_CONFIG);
48
50
  function resolveNonOwnerSignupRole() {
49
51
  var _a, _b, _c, _d;
50
52
  const cfg = AUTH_CONFIG.signupIntent;
@@ -220,13 +222,13 @@ const auth = betterAuth({
220
222
  email,
221
223
  otp,
222
224
  type,
223
- appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App"
225
+ appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App",
226
+ expiresIn: otpConfig.expiresIn
224
227
  }, I18N_CONFIG.defaultLocale);
225
228
  await emailService.send({ to: email, ...template });
226
229
  },
227
- otpLength: 6,
228
- expiresIn: 300,
229
- // 5 minutes
230
+ otpLength: otpConfig.otpLength,
231
+ expiresIn: otpConfig.expiresIn,
230
232
  sendVerificationOnSignUp: false,
231
233
  disableSignUp: false
232
234
  // auto-create user on first OTP sign-in