@nextsparkjs/core 0.1.0-beta.185 → 0.1.0-beta.186

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 (386) hide show
  1. package/dist/components/app/guards/DeveloperGuard.d.ts.map +1 -1
  2. package/dist/components/app/guards/SuperAdminGuard.d.ts.map +1 -1
  3. package/dist/components/app/layouts/PublicFooter.d.ts.map +1 -1
  4. package/dist/components/app/layouts/PublicFooter.js +2 -2
  5. package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
  6. package/dist/components/app/layouts/PublicNavbar.js +2 -2
  7. package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
  8. package/dist/components/app/misc/ThemeToggle.js +4 -1
  9. package/dist/components/auth/DevKeyring.d.ts.map +1 -1
  10. package/dist/components/auth/DevKeyring.js +10 -2
  11. package/dist/components/auth/SessionCookieRefresher.d.ts +21 -0
  12. package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -0
  13. package/dist/components/auth/SessionCookieRefresher.js +11 -0
  14. package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
  15. package/dist/components/auth/forms/LoginForm.js +300 -6
  16. package/dist/components/auth/index.d.ts +1 -0
  17. package/dist/components/auth/index.d.ts.map +1 -1
  18. package/dist/components/auth/index.js +2 -0
  19. package/dist/components/billing/InvoicesTable.d.ts.map +1 -1
  20. package/dist/components/billing/InvoicesTable.js +4 -3
  21. package/dist/components/dashboard/block-editor/dynamic-form.d.ts.map +1 -1
  22. package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
  23. package/dist/components/dashboard/layouts/AuthGuard.js +2 -2
  24. package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
  25. package/dist/components/dashboard/layouts/DashboardAuthLayout.js +2 -2
  26. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +17 -0
  27. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts.map +1 -0
  28. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.js +52 -0
  29. package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
  30. package/dist/components/dashboard/layouts/Sidebar.js +2 -3
  31. package/dist/components/dashboard/layouts/TopNavbar.js +2 -2
  32. package/dist/components/dashboard/layouts/index.d.ts +1 -0
  33. package/dist/components/dashboard/layouts/index.d.ts.map +1 -1
  34. package/dist/components/dashboard/layouts/index.js +2 -0
  35. package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
  36. package/dist/components/entities/EntityFieldRenderer.js +3 -0
  37. package/dist/components/entities/EntityTable.d.ts.map +1 -1
  38. package/dist/components/entities/EntityTable.js +2 -1
  39. package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
  40. package/dist/components/entities/wrappers/EntityFormWrapper.js +7 -2
  41. package/dist/components/ui/combobox.d.ts +8 -1
  42. package/dist/components/ui/combobox.d.ts.map +1 -1
  43. package/dist/components/ui/combobox.js +37 -44
  44. package/dist/components/ui/country-select.d.ts +3 -1
  45. package/dist/components/ui/country-select.d.ts.map +1 -1
  46. package/dist/components/ui/country-select.js +3 -1
  47. package/dist/components/ui/currency-select.d.ts +3 -1
  48. package/dist/components/ui/currency-select.d.ts.map +1 -1
  49. package/dist/components/ui/currency-select.js +3 -1
  50. package/dist/components/ui/sheet.d.ts +5 -0
  51. package/dist/components/ui/sheet.d.ts.map +1 -1
  52. package/dist/components/ui/sheet.js +46 -26
  53. package/dist/components/ui/timezone-select.d.ts +3 -1
  54. package/dist/components/ui/timezone-select.d.ts.map +1 -1
  55. package/dist/components/ui/timezone-select.js +3 -1
  56. package/dist/contexts/TeamContext.d.ts +6 -0
  57. package/dist/contexts/TeamContext.d.ts.map +1 -1
  58. package/dist/contexts/TeamContext.js +8 -1
  59. package/dist/emails/otp-verification.d.ts.map +1 -1
  60. package/dist/emails/reset-password.d.ts.map +1 -1
  61. package/dist/emails/team-invitation.d.ts.map +1 -1
  62. package/dist/emails/team-invitation.js +3 -2
  63. package/dist/emails/verify-email.d.ts.map +1 -1
  64. package/dist/hooks/index.d.ts +1 -0
  65. package/dist/hooks/index.d.ts.map +1 -1
  66. package/dist/hooks/index.js +1 -0
  67. package/dist/hooks/useAuth.d.ts +29 -0
  68. package/dist/hooks/useAuth.d.ts.map +1 -1
  69. package/dist/hooks/useAuth.js +24 -0
  70. package/dist/hooks/useEnsureUserMetadata.d.ts +22 -0
  71. package/dist/hooks/useEnsureUserMetadata.d.ts.map +1 -1
  72. package/dist/hooks/useEnsureUserMetadata.js +18 -5
  73. package/dist/hooks/useSessionCookieRefresh.d.ts +35 -0
  74. package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -0
  75. package/dist/hooks/useSessionCookieRefresh.js +49 -0
  76. package/dist/lib/api/api-error.d.ts +3 -1
  77. package/dist/lib/api/api-error.d.ts.map +1 -1
  78. package/dist/lib/api/api-error.js +4 -2
  79. package/dist/lib/api/auth/dual-auth.d.ts +38 -3
  80. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  81. package/dist/lib/api/auth/dual-auth.js +42 -7
  82. package/dist/lib/api/auth/permissions.d.ts +7 -2
  83. package/dist/lib/api/auth/permissions.d.ts.map +1 -1
  84. package/dist/lib/api/auth/permissions.js +2 -2
  85. package/dist/lib/api/auth/scope-policy.d.ts +71 -0
  86. package/dist/lib/api/auth/scope-policy.d.ts.map +1 -0
  87. package/dist/lib/api/auth/scope-policy.js +53 -0
  88. package/dist/lib/api/auth.d.ts +15 -0
  89. package/dist/lib/api/auth.d.ts.map +1 -1
  90. package/dist/lib/api/auth.js +17 -4
  91. package/dist/lib/api/entity/audit-log.d.ts +35 -0
  92. package/dist/lib/api/entity/audit-log.d.ts.map +1 -0
  93. package/dist/lib/api/entity/audit-log.js +35 -0
  94. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  95. package/dist/lib/api/entity/generic-handler.js +315 -134
  96. package/dist/lib/api/helpers.d.ts +29 -4
  97. package/dist/lib/api/helpers.d.ts.map +1 -1
  98. package/dist/lib/api/helpers.js +30 -6
  99. package/dist/lib/api/keys.d.ts +16 -0
  100. package/dist/lib/api/keys.d.ts.map +1 -1
  101. package/dist/lib/api/keys.js +19 -1
  102. package/dist/lib/api/routes/patterns-usages.d.ts.map +1 -1
  103. package/dist/lib/api/routes/patterns-usages.js +3 -11
  104. package/dist/lib/auth/auth-methods.d.ts +52 -0
  105. package/dist/lib/auth/auth-methods.d.ts.map +1 -0
  106. package/dist/lib/auth/auth-methods.js +63 -0
  107. package/dist/lib/auth/registration-guard-plugin.d.ts.map +1 -1
  108. package/dist/lib/auth/registration-helpers.d.ts +9 -0
  109. package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
  110. package/dist/lib/auth/registration-helpers.js +8 -2
  111. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +52 -0
  112. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -0
  113. package/dist/lib/auth/security-notifications/device-fingerprint.js +42 -0
  114. package/dist/lib/auth/security-notifications/dispatcher.d.ts +37 -0
  115. package/dist/lib/auth/security-notifications/dispatcher.d.ts.map +1 -0
  116. package/dist/lib/auth/security-notifications/dispatcher.js +157 -0
  117. package/dist/lib/auth/security-notifications/index.d.ts +20 -0
  118. package/dist/lib/auth/security-notifications/index.d.ts.map +1 -0
  119. package/dist/lib/auth/security-notifications/index.js +22 -0
  120. package/dist/lib/auth/security-notifications/registry.d.ts +36 -0
  121. package/dist/lib/auth/security-notifications/registry.d.ts.map +1 -0
  122. package/dist/lib/auth/security-notifications/registry.js +26 -0
  123. package/dist/lib/auth/security-notifications/templates/email-changed.d.ts +12 -0
  124. package/dist/lib/auth/security-notifications/templates/email-changed.d.ts.map +1 -0
  125. package/dist/lib/auth/security-notifications/templates/email-changed.js +43 -0
  126. package/dist/lib/auth/security-notifications/templates/new-device-login.d.ts +7 -0
  127. package/dist/lib/auth/security-notifications/templates/new-device-login.d.ts.map +1 -0
  128. package/dist/lib/auth/security-notifications/templates/new-device-login.js +46 -0
  129. package/dist/lib/auth/security-notifications/templates/password-changed.d.ts +7 -0
  130. package/dist/lib/auth/security-notifications/templates/password-changed.d.ts.map +1 -0
  131. package/dist/lib/auth/security-notifications/templates/password-changed.js +35 -0
  132. package/dist/lib/auth/security-notifications/templates/shared.d.ts +36 -0
  133. package/dist/lib/auth/security-notifications/templates/shared.d.ts.map +1 -0
  134. package/dist/lib/auth/security-notifications/templates/shared.js +68 -0
  135. package/dist/lib/auth/security-notifications/types.d.ts +74 -0
  136. package/dist/lib/auth/security-notifications/types.d.ts.map +1 -0
  137. package/dist/lib/auth/security-notifications/types.js +0 -0
  138. package/dist/lib/auth/session-config.d.ts +37 -0
  139. package/dist/lib/auth/session-config.d.ts.map +1 -0
  140. package/dist/lib/auth/session-config.js +59 -0
  141. package/dist/lib/auth/session-refresh.d.ts +46 -0
  142. package/dist/lib/auth/session-refresh.d.ts.map +1 -0
  143. package/dist/lib/auth/session-refresh.js +11 -0
  144. package/dist/lib/auth-client.d.ts +1639 -0
  145. package/dist/lib/auth-client.d.ts.map +1 -0
  146. package/dist/lib/auth-client.js +4 -0
  147. package/dist/lib/auth.d.ts.map +1 -1
  148. package/dist/lib/auth.js +21 -8
  149. package/dist/lib/billing/gateways/factory.d.ts +8 -3
  150. package/dist/lib/billing/gateways/factory.d.ts.map +1 -1
  151. package/dist/lib/billing/gateways/factory.js +37 -23
  152. package/dist/lib/billing/stripe-webhook.d.ts.map +1 -1
  153. package/dist/lib/billing/stripe-webhook.js +2 -1
  154. package/dist/lib/config/app.config.d.ts.map +1 -1
  155. package/dist/lib/config/app.config.js +71 -0
  156. package/dist/lib/config/config-sync.d.ts +1 -4
  157. package/dist/lib/config/config-sync.d.ts.map +1 -1
  158. package/dist/lib/config/config-sync.js +6 -2
  159. package/dist/lib/config/types.d.ts +130 -0
  160. package/dist/lib/config/types.d.ts.map +1 -1
  161. package/dist/lib/entities/entity-hooks.d.ts +9 -1
  162. package/dist/lib/entities/entity-hooks.d.ts.map +1 -1
  163. package/dist/lib/entities/entity-hooks.js +77 -4
  164. package/dist/lib/entities/schema-generator.d.ts.map +1 -1
  165. package/dist/lib/entities/schema-generator.js +20 -4
  166. package/dist/lib/entities/serialization.d.ts +2 -2
  167. package/dist/lib/entities/serialization.d.ts.map +1 -1
  168. package/dist/lib/entities/serialization.js +3 -2
  169. package/dist/lib/entities/types.d.ts +8 -0
  170. package/dist/lib/entities/types.d.ts.map +1 -1
  171. package/dist/lib/locale.d.ts.map +1 -1
  172. package/dist/lib/locale.js +4 -1
  173. package/dist/lib/mcp/audit.d.ts +8 -4
  174. package/dist/lib/mcp/audit.d.ts.map +1 -1
  175. package/dist/lib/plugins/hook-system.d.ts +13 -0
  176. package/dist/lib/plugins/hook-system.d.ts.map +1 -1
  177. package/dist/lib/plugins/hook-system.js +32 -2
  178. package/dist/lib/scheduled-actions/handlers/index.d.ts +1 -0
  179. package/dist/lib/scheduled-actions/handlers/index.d.ts.map +1 -1
  180. package/dist/lib/scheduled-actions/handlers/index.js +3 -1
  181. package/dist/lib/scheduled-actions/handlers/security-notification.d.ts +26 -0
  182. package/dist/lib/scheduled-actions/handlers/security-notification.d.ts.map +1 -0
  183. package/dist/lib/scheduled-actions/handlers/security-notification.js +54 -0
  184. package/dist/lib/selectors/core-selectors.d.ts +12 -0
  185. package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
  186. package/dist/lib/selectors/domains/auth.selectors.d.ts +12 -0
  187. package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
  188. package/dist/lib/selectors/domains/auth.selectors.js +14 -1
  189. package/dist/lib/selectors/selectors.d.ts +24 -0
  190. package/dist/lib/selectors/selectors.d.ts.map +1 -1
  191. package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
  192. package/dist/lib/services/generic-entity.service.js +16 -32
  193. package/dist/lib/services/membership.service.d.ts +10 -2
  194. package/dist/lib/services/membership.service.d.ts.map +1 -1
  195. package/dist/lib/services/membership.service.js +37 -16
  196. package/dist/lib/services/subscription.service.d.ts.map +1 -1
  197. package/dist/lib/services/subscription.service.js +2 -1
  198. package/dist/lib/services/team-member.service.d.ts +15 -3
  199. package/dist/lib/services/team-member.service.d.ts.map +1 -1
  200. package/dist/lib/services/team-member.service.js +27 -6
  201. package/dist/lib/services/team.service.d.ts.map +1 -1
  202. package/dist/lib/teams/permissions.d.ts +3 -1
  203. package/dist/lib/teams/permissions.d.ts.map +1 -1
  204. package/dist/lib/teams/permissions.js +6 -0
  205. package/dist/lib/teams/schema.d.ts.map +1 -1
  206. package/dist/lib/teams/schema.js +3 -0
  207. package/dist/lib/theme/forced-theme.d.ts +34 -0
  208. package/dist/lib/theme/forced-theme.d.ts.map +1 -0
  209. package/dist/lib/theme/forced-theme.js +27 -0
  210. package/dist/lib/theme/get-default-theme-mode.d.ts +3 -0
  211. package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
  212. package/dist/lib/theme/get-default-theme-mode.js +5 -3
  213. package/dist/messages/de/auth.json +25 -2
  214. package/dist/messages/de/index.d.ts +81 -0
  215. package/dist/messages/de/index.d.ts.map +1 -1
  216. package/dist/messages/de/index.js +2 -0
  217. package/dist/messages/de/index.ts +2 -0
  218. package/dist/messages/en/auth.json +25 -2
  219. package/dist/messages/en/index.d.ts +81 -0
  220. package/dist/messages/en/index.d.ts.map +1 -1
  221. package/dist/messages/en/index.js +2 -0
  222. package/dist/messages/en/index.ts +2 -0
  223. package/dist/messages/es/auth.json +25 -2
  224. package/dist/messages/es/index.d.ts +81 -0
  225. package/dist/messages/es/index.d.ts.map +1 -1
  226. package/dist/messages/es/index.js +2 -0
  227. package/dist/messages/es/index.ts +2 -0
  228. package/dist/messages/fr/auth.json +25 -2
  229. package/dist/messages/fr/index.d.ts +81 -0
  230. package/dist/messages/fr/index.d.ts.map +1 -1
  231. package/dist/messages/fr/index.js +2 -0
  232. package/dist/messages/fr/index.ts +2 -0
  233. package/dist/messages/it/auth.json +25 -2
  234. package/dist/messages/it/index.d.ts +81 -0
  235. package/dist/messages/it/index.d.ts.map +1 -1
  236. package/dist/messages/it/index.js +2 -0
  237. package/dist/messages/it/index.ts +2 -0
  238. package/dist/messages/pt/auth.json +25 -2
  239. package/dist/messages/pt/index.d.ts +81 -0
  240. package/dist/messages/pt/index.d.ts.map +1 -1
  241. package/dist/messages/pt/index.js +2 -0
  242. package/dist/messages/pt/index.ts +2 -0
  243. package/dist/migrations/005_api_audit_log.sql +2 -1
  244. package/dist/migrations/025_api_audit_log_nullable_api_key.sql +12 -0
  245. package/dist/migrations/026_login_events.sql +91 -0
  246. package/dist/migrations/027_rls_bypass_developer_and_system_admin_team.sql +197 -0
  247. package/dist/providers/DashboardProviders.d.ts +12 -3
  248. package/dist/providers/DashboardProviders.d.ts.map +1 -1
  249. package/dist/providers/DashboardProviders.js +6 -2
  250. package/dist/providers/theme-provider.d.ts +19 -2
  251. package/dist/providers/theme-provider.d.ts.map +1 -1
  252. package/dist/providers/theme-provider.js +6 -2
  253. package/dist/templates/app/(auth)/signup/page.tsx +8 -0
  254. package/dist/templates/app/(public)/[...slug]/page.tsx +9 -14
  255. package/dist/templates/app/api/auth/[...all]/route.ts +23 -1
  256. package/dist/templates/app/api/health/route.ts +4 -2
  257. package/dist/templates/app/api/internal/user-metadata/route.ts +5 -3
  258. package/dist/templates/app/api/mcp/route.ts +4 -1
  259. package/dist/templates/app/api/superadmin/subscriptions/route.ts +2 -1
  260. package/dist/templates/app/api/superadmin/teams/[teamId]/route.ts +4 -3
  261. package/dist/templates/app/api/superadmin/users/[userId]/route.ts +10 -3
  262. package/dist/templates/app/api/v1/api-keys/[id]/route.ts +50 -71
  263. package/dist/templates/app/api/v1/api-keys/route.ts +21 -43
  264. package/dist/templates/app/api/v1/auth/signup-with-invite/route.ts +14 -14
  265. package/dist/templates/app/api/v1/billing/cancel/route.ts +7 -6
  266. package/dist/templates/app/api/v1/billing/change-plan/route.ts +5 -4
  267. package/dist/templates/app/api/v1/billing/check-action/route.ts +6 -4
  268. package/dist/templates/app/api/v1/billing/checkout/route.ts +7 -5
  269. package/dist/templates/app/api/v1/billing/plans/route.ts +8 -12
  270. package/dist/templates/app/api/v1/billing/portal/route.ts +7 -5
  271. package/dist/templates/app/api/v1/billing/webhooks/polar/route.ts +1 -1
  272. package/dist/templates/app/api/v1/devtools/blocks/route.ts +5 -4
  273. package/dist/templates/app/api/v1/devtools/features/route.ts +5 -4
  274. package/dist/templates/app/api/v1/devtools/flows/route.ts +5 -4
  275. package/dist/templates/app/api/v1/devtools/scheduled-actions/route.ts +9 -7
  276. package/dist/templates/app/api/v1/devtools/scheduled-actions/run/route.ts +5 -4
  277. package/dist/templates/app/api/v1/devtools/testing/route.ts +5 -4
  278. package/dist/templates/app/api/v1/media/[id]/route.ts +13 -25
  279. package/dist/templates/app/api/v1/media/[id]/tags/route.ts +17 -25
  280. package/dist/templates/app/api/v1/media/check-duplicates/route.ts +5 -7
  281. package/dist/templates/app/api/v1/media/route.ts +5 -9
  282. package/dist/templates/app/api/v1/media/upload/route.ts +9 -21
  283. package/dist/templates/app/api/v1/media-tags/route.ts +9 -13
  284. package/dist/templates/app/api/v1/patterns/[id]/usages/route.ts +11 -19
  285. package/dist/templates/app/api/v1/post-categories/[id]/route.ts +9 -7
  286. package/dist/templates/app/api/v1/post-categories/route.ts +5 -4
  287. package/dist/templates/app/api/v1/team-invitations/[token]/accept/route.ts +16 -18
  288. package/dist/templates/app/api/v1/team-invitations/[token]/decline/route.ts +15 -17
  289. package/dist/templates/app/api/v1/team-invitations/[token]/route.ts +8 -8
  290. package/dist/templates/app/api/v1/team-invitations/route.ts +9 -11
  291. package/dist/templates/app/api/v1/teams/[teamId]/invitations/route.ts +41 -32
  292. package/dist/templates/app/api/v1/teams/[teamId]/invoices/[invoiceNumber]/route.ts +15 -16
  293. package/dist/templates/app/api/v1/teams/[teamId]/invoices/route.ts +14 -15
  294. package/dist/templates/app/api/v1/teams/[teamId]/members/[memberId]/route.ts +32 -36
  295. package/dist/templates/app/api/v1/teams/[teamId]/members/route.ts +33 -33
  296. package/dist/templates/app/api/v1/teams/[teamId]/route.ts +35 -41
  297. package/dist/templates/app/api/v1/teams/[teamId]/subscription/route.ts +5 -3
  298. package/dist/templates/app/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts +10 -6
  299. package/dist/templates/app/api/v1/teams/route.ts +33 -27
  300. package/dist/templates/app/api/v1/teams/switch/route.ts +11 -13
  301. package/dist/templates/app/api/v1/theme/[...path]/route.ts +23 -2
  302. package/dist/templates/app/api/v1/users/[id]/meta/[key]/route.ts +32 -77
  303. package/dist/templates/app/api/v1/users/[id]/route.ts +35 -68
  304. package/dist/templates/app/api/v1/users/route.ts +21 -25
  305. package/dist/templates/app/dashboard/layout.tsx +2 -6
  306. package/dist/templates/app/layout.ppr.tsx +9 -14
  307. package/dist/templates/app/layout.tsx +37 -20
  308. package/dist/templates/contents/themes/starter/config/app.config.ts +19 -0
  309. package/dist/templates/contents/themes/starter/config/theme.config.ts +6 -0
  310. package/dist/templates/contents/themes/starter/styles/globals.css +6 -2
  311. package/dist/templates/proxy.ts +46 -10
  312. package/dist/templates/tsconfig.json +4 -0
  313. package/dist/types/theme.d.ts +9 -0
  314. package/dist/types/theme.d.ts.map +1 -1
  315. package/migrations/005_api_audit_log.sql +2 -1
  316. package/migrations/025_api_audit_log_nullable_api_key.sql +12 -0
  317. package/migrations/026_login_events.sql +91 -0
  318. package/migrations/027_rls_bypass_developer_and_system_admin_team.sql +197 -0
  319. package/package.json +14 -11
  320. package/scripts/build/registry/__tests__/scope-registry.test.mjs +18 -0
  321. package/scripts/build/registry/generators/scope-registry.mjs +9 -2
  322. package/templates/app/(auth)/signup/page.tsx +8 -0
  323. package/templates/app/(public)/[...slug]/page.tsx +9 -14
  324. package/templates/app/api/auth/[...all]/route.ts +23 -1
  325. package/templates/app/api/health/route.ts +4 -2
  326. package/templates/app/api/internal/user-metadata/route.ts +5 -3
  327. package/templates/app/api/mcp/route.ts +4 -1
  328. package/templates/app/api/superadmin/subscriptions/route.ts +2 -1
  329. package/templates/app/api/superadmin/teams/[teamId]/route.ts +4 -3
  330. package/templates/app/api/superadmin/users/[userId]/route.ts +10 -3
  331. package/templates/app/api/v1/api-keys/[id]/route.ts +50 -71
  332. package/templates/app/api/v1/api-keys/route.ts +21 -43
  333. package/templates/app/api/v1/auth/signup-with-invite/route.ts +14 -14
  334. package/templates/app/api/v1/billing/cancel/route.ts +7 -6
  335. package/templates/app/api/v1/billing/change-plan/route.ts +5 -4
  336. package/templates/app/api/v1/billing/check-action/route.ts +6 -4
  337. package/templates/app/api/v1/billing/checkout/route.ts +7 -5
  338. package/templates/app/api/v1/billing/plans/route.ts +8 -12
  339. package/templates/app/api/v1/billing/portal/route.ts +7 -5
  340. package/templates/app/api/v1/billing/webhooks/polar/route.ts +1 -1
  341. package/templates/app/api/v1/devtools/blocks/route.ts +5 -4
  342. package/templates/app/api/v1/devtools/features/route.ts +5 -4
  343. package/templates/app/api/v1/devtools/flows/route.ts +5 -4
  344. package/templates/app/api/v1/devtools/scheduled-actions/route.ts +9 -7
  345. package/templates/app/api/v1/devtools/scheduled-actions/run/route.ts +5 -4
  346. package/templates/app/api/v1/devtools/testing/route.ts +5 -4
  347. package/templates/app/api/v1/media/[id]/route.ts +13 -25
  348. package/templates/app/api/v1/media/[id]/tags/route.ts +17 -25
  349. package/templates/app/api/v1/media/check-duplicates/route.ts +5 -7
  350. package/templates/app/api/v1/media/route.ts +5 -9
  351. package/templates/app/api/v1/media/upload/route.ts +9 -21
  352. package/templates/app/api/v1/media-tags/route.ts +9 -13
  353. package/templates/app/api/v1/patterns/[id]/usages/route.ts +11 -19
  354. package/templates/app/api/v1/post-categories/[id]/route.ts +9 -7
  355. package/templates/app/api/v1/post-categories/route.ts +5 -4
  356. package/templates/app/api/v1/team-invitations/[token]/accept/route.ts +16 -18
  357. package/templates/app/api/v1/team-invitations/[token]/decline/route.ts +15 -17
  358. package/templates/app/api/v1/team-invitations/[token]/route.ts +8 -8
  359. package/templates/app/api/v1/team-invitations/route.ts +9 -11
  360. package/templates/app/api/v1/teams/[teamId]/invitations/route.ts +41 -32
  361. package/templates/app/api/v1/teams/[teamId]/invoices/[invoiceNumber]/route.ts +15 -16
  362. package/templates/app/api/v1/teams/[teamId]/invoices/route.ts +14 -15
  363. package/templates/app/api/v1/teams/[teamId]/members/[memberId]/route.ts +32 -36
  364. package/templates/app/api/v1/teams/[teamId]/members/route.ts +33 -33
  365. package/templates/app/api/v1/teams/[teamId]/route.ts +35 -41
  366. package/templates/app/api/v1/teams/[teamId]/subscription/route.ts +5 -3
  367. package/templates/app/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts +10 -6
  368. package/templates/app/api/v1/teams/route.ts +33 -27
  369. package/templates/app/api/v1/teams/switch/route.ts +11 -13
  370. package/templates/app/api/v1/theme/[...path]/route.ts +23 -2
  371. package/templates/app/api/v1/users/[id]/meta/[key]/route.ts +32 -77
  372. package/templates/app/api/v1/users/[id]/route.ts +35 -68
  373. package/templates/app/api/v1/users/route.ts +21 -25
  374. package/templates/app/dashboard/layout.tsx +2 -6
  375. package/templates/app/layout.ppr.tsx +9 -14
  376. package/templates/app/layout.tsx +37 -20
  377. package/templates/contents/themes/starter/config/app.config.ts +19 -0
  378. package/templates/contents/themes/starter/config/theme.config.ts +6 -0
  379. package/templates/contents/themes/starter/styles/globals.css +6 -2
  380. package/templates/proxy.ts +46 -10
  381. package/templates/tsconfig.json +4 -0
  382. package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +23 -0
  383. package/tests/jest/__mocks__/next-server.js +24 -0
  384. package/dist/styles/classes.json +0 -1093
  385. package/dist/styles/ui.css +0 -2
  386. package/scripts/build/build-ui-css.mjs +0 -351
@@ -22,7 +22,20 @@ const AUTH_SELECTORS = {
22
22
  // Misc
23
23
  inviteBanner: "login-invite-banner",
24
24
  errorAlert: "login-error-alert",
25
- rememberCheckbox: "login-remember-checkbox"
25
+ rememberCheckbox: "login-remember-checkbox",
26
+ // Passwordless (email one-time code)
27
+ useOtp: "login-use-otp",
28
+ usePassword: "login-use-password",
29
+ otpForm: "login-otp-form",
30
+ otpEmailInput: "login-otp-email-input",
31
+ otpEmailError: "login-otp-email-error",
32
+ otpSend: "login-otp-send",
33
+ otpSentNotice: "login-otp-sent-notice",
34
+ otpCodeInput: "login-otp-code-input",
35
+ otpCodeError: "login-otp-code-error",
36
+ otpSubmit: "login-otp-submit",
37
+ otpResend: "login-otp-resend",
38
+ otpChangeEmail: "login-otp-change-email"
26
39
  },
27
40
  signup: {
28
41
  form: "signup-form",
@@ -59,6 +59,18 @@ export declare const SELECTORS: {
59
59
  readonly inviteBanner: "login-invite-banner";
60
60
  readonly errorAlert: "login-error-alert";
61
61
  readonly rememberCheckbox: "login-remember-checkbox";
62
+ readonly useOtp: "login-use-otp";
63
+ readonly usePassword: "login-use-password";
64
+ readonly otpForm: "login-otp-form";
65
+ readonly otpEmailInput: "login-otp-email-input";
66
+ readonly otpEmailError: "login-otp-email-error";
67
+ readonly otpSend: "login-otp-send";
68
+ readonly otpSentNotice: "login-otp-sent-notice";
69
+ readonly otpCodeInput: "login-otp-code-input";
70
+ readonly otpCodeError: "login-otp-code-error";
71
+ readonly otpSubmit: "login-otp-submit";
72
+ readonly otpResend: "login-otp-resend";
73
+ readonly otpChangeEmail: "login-otp-change-email";
62
74
  };
63
75
  readonly signup: {
64
76
  readonly form: "signup-form";
@@ -1643,6 +1655,18 @@ declare const _default: {
1643
1655
  readonly inviteBanner: "login-invite-banner";
1644
1656
  readonly errorAlert: "login-error-alert";
1645
1657
  readonly rememberCheckbox: "login-remember-checkbox";
1658
+ readonly useOtp: "login-use-otp";
1659
+ readonly usePassword: "login-use-password";
1660
+ readonly otpForm: "login-otp-form";
1661
+ readonly otpEmailInput: "login-otp-email-input";
1662
+ readonly otpEmailError: "login-otp-email-error";
1663
+ readonly otpSend: "login-otp-send";
1664
+ readonly otpSentNotice: "login-otp-sent-notice";
1665
+ readonly otpCodeInput: "login-otp-code-input";
1666
+ readonly otpCodeError: "login-otp-code-error";
1667
+ readonly otpSubmit: "login-otp-submit";
1668
+ readonly otpResend: "login-otp-resend";
1669
+ readonly otpChangeEmail: "login-otp-change-email";
1646
1670
  };
1647
1671
  readonly signup: {
1648
1672
  readonly form: "signup-form";
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/lib/selectors/selectors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/lib/selectors/selectors.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"generic-entity.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/generic-entity.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generic-entity.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/generic-entity.service.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,13 @@
1
1
  import { queryWithRLS, queryOneWithRLS, mutateWithRLS } from "../db.js";
2
2
  import { entityRegistry } from "../entities/registry.js";
3
- import { executeBeforeHooks, executeAfterHooks } from "../entities/hooks.js";
3
+ import {
4
+ beforeEntityCreate,
5
+ afterEntityCreate,
6
+ beforeEntityUpdate,
7
+ afterEntityUpdate,
8
+ beforeEntityDelete,
9
+ afterEntityDelete
10
+ } from "../entities/entity-hooks.js";
4
11
  const SYSTEM_FIELDS = ["id", "userId", "teamId", "createdAt", "updatedAt"];
5
12
  const DEFAULT_LIMIT = 20;
6
13
  const DEFAULT_ORDER_BY = "createdAt";
@@ -173,15 +180,6 @@ function validateEntityData(entityConfig, data, isUpdate = false) {
173
180
  }
174
181
  return { valid: errors.length === 0, errors };
175
182
  }
176
- function createHookContext(entitySlug, operation, userId, data, previousData, role = "member") {
177
- return {
178
- entityName: entitySlug,
179
- operation,
180
- data,
181
- previousData,
182
- user: { id: userId, role }
183
- };
184
- }
185
183
  class GenericEntityService {
186
184
  /**
187
185
  * Get entity by ID
@@ -307,12 +305,7 @@ class GenericEntityService {
307
305
  if (!entityConfig) {
308
306
  throw new Error(`Entity "${entitySlug}" not found in registry`);
309
307
  }
310
- const beforeContext = createHookContext(entitySlug, "create", userId, data);
311
- const beforeResult = await executeBeforeHooks(entitySlug, "create", beforeContext);
312
- if (!beforeResult.continue) {
313
- throw new Error(beforeResult.error || "Operation cancelled by hook");
314
- }
315
- const finalData = beforeResult.data ?? data;
308
+ const finalData = await beforeEntityCreate(entitySlug, data, userId);
316
309
  const validation = validateEntityData(entityConfig, finalData, false);
317
310
  if (!validation.valid) {
318
311
  throw new Error(`Validation failed: ${validation.errors.join(", ")}`);
@@ -344,8 +337,7 @@ class GenericEntityService {
344
337
  throw new Error("Failed to create entity");
345
338
  }
346
339
  const createdEntity = mapRowToEntity(result.rows[0]);
347
- const afterContext = createHookContext(entitySlug, "create", userId, createdEntity);
348
- executeAfterHooks(entitySlug, "create", afterContext).catch((err) => {
340
+ afterEntityCreate(entitySlug, createdEntity, userId).catch((err) => {
349
341
  console.error(`[GenericEntityService] afterCreate hook error for ${entitySlug}:`, err);
350
342
  });
351
343
  return createdEntity;
@@ -384,12 +376,7 @@ class GenericEntityService {
384
376
  if (!currentEntity) {
385
377
  throw new Error("Entity not found or not authorized");
386
378
  }
387
- const beforeContext = createHookContext(entitySlug, "update", userId, data, currentEntity);
388
- const beforeResult = await executeBeforeHooks(entitySlug, "update", beforeContext);
389
- if (!beforeResult.continue) {
390
- throw new Error(beforeResult.error || "Operation cancelled by hook");
391
- }
392
- const finalData = beforeResult.data ?? data;
379
+ const finalData = await beforeEntityUpdate(entitySlug, id, data, userId);
393
380
  const validation = validateEntityData(entityConfig, finalData, true);
394
381
  if (!validation.valid) {
395
382
  throw new Error(`Validation failed: ${validation.errors.join(", ")}`);
@@ -428,8 +415,7 @@ class GenericEntityService {
428
415
  throw new Error("Update failed");
429
416
  }
430
417
  const updatedEntity = mapRowToEntity(result.rows[0]);
431
- const afterContext = createHookContext(entitySlug, "update", userId, updatedEntity, currentEntity);
432
- executeAfterHooks(entitySlug, "update", afterContext).catch((err) => {
418
+ afterEntityUpdate(entitySlug, id, updatedEntity, data, userId).catch((err) => {
433
419
  console.error(`[GenericEntityService] afterUpdate hook error for ${entitySlug}:`, err);
434
420
  });
435
421
  return updatedEntity;
@@ -467,10 +453,9 @@ class GenericEntityService {
467
453
  if (!entityToDelete) {
468
454
  return false;
469
455
  }
470
- const beforeContext = createHookContext(entitySlug, "delete", userId, void 0, entityToDelete);
471
- const beforeResult = await executeBeforeHooks(entitySlug, "delete", beforeContext);
472
- if (!beforeResult.continue) {
473
- throw new Error(beforeResult.error || "Operation cancelled by hook");
456
+ const allowDelete = await beforeEntityDelete(entitySlug, id, userId);
457
+ if (!allowDelete) {
458
+ throw new Error("Operation cancelled by hook");
474
459
  }
475
460
  const result = await mutateWithRLS(
476
461
  `DELETE FROM ${tableName} ${whereClause}`,
@@ -479,8 +464,7 @@ class GenericEntityService {
479
464
  );
480
465
  const deleted = result.rowCount > 0;
481
466
  if (deleted) {
482
- const afterContext = createHookContext(entitySlug, "delete", userId, void 0, entityToDelete);
483
- executeAfterHooks(entitySlug, "delete", afterContext).catch((err) => {
467
+ afterEntityDelete(entitySlug, id, userId).catch((err) => {
484
468
  console.error(`[GenericEntityService] afterDelete hook error for ${entitySlug}:`, err);
485
469
  });
486
470
  }
@@ -113,12 +113,20 @@ export declare class TeamMembership implements TeamMembershipData {
113
113
  * 4. Quota is available
114
114
  * 5. Subscription is active
115
115
  *
116
- * @param action - Action slug to check
116
+ * The action id IS the permission id as registered in the permissions
117
+ * registry (e.g. 'team.members.update_role', 'customers.create',
118
+ * 'page-builder.access'). Ids may have any number of dot-separated segments.
119
+ *
120
+ * Fails closed: an action whose id is not a registered permission is denied
121
+ * (and logged) instead of silently allowed, so a typo or a renamed permission
122
+ * surfaces as a visible 403 rather than an unguarded endpoint (issue #89).
123
+ *
124
+ * @param action - Action slug to check (must be a registered permission id)
117
125
  * @param options - Options for quota increment
118
126
  * @returns ActionResult with allowed status and details
119
127
  *
120
128
  * @example
121
- * const result = membership.canPerformAction('projects.create')
129
+ * const result = membership.canPerformAction('team.members.update_role')
122
130
  * if (!result.allowed) {
123
131
  * console.log(result.message, result.reason)
124
132
  * }
@@ -1 +1 @@
1
- {"version":3,"file":"membership.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/membership.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EACnB,MAAM,sBAAsB,CAAA;AAM7B;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,kBAAkB;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,sBAAsB,GAAG,IAAI,CAAA;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;gBAE/B,IAAI,EAAE,kBAAkB;IAWpC;;;;;;;;;;OAUG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IAKpC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAI9C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIpC;;;;;;;;;;;;OAYG;IACH,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAU,GACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAmB1C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACpC,YAAY;CA0EhB;AAMD,qBAAa,iBAAiB;IAC5B;;;;;;;;;;;;;;;;;;OAkBG;WACU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkEzE;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAiBlC;;;;;;;;OAQG;mBACkB,cAAc;CAyCpC"}
1
+ {"version":3,"file":"membership.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/membership.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,kBAAkB,EACnB,MAAM,sBAAsB,CAAA;AAM7B;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,kBAAkB;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,UAAU,EAAE,CAAA;IAClC,QAAQ,CAAC,YAAY,EAAE,sBAAsB,GAAG,IAAI,CAAA;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;gBAE/B,IAAI,EAAE,kBAAkB;IAWpC;;;;;;;;;;OAUG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIvC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO;IAKpC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAI9C;;;;;;;;;;OAUG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIpC;;;;;;;;;;;;OAYG;IACH,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAU,GACpB;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAmB1C;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,gBAAgB,CACd,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GACpC,YAAY;CA4FhB;AAMD,qBAAa,iBAAiB;IAC5B;;;;;;;;;;;;;;;;;;OAkBG;WACU,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkEzE;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAiBlC;;;;;;;;OAQG;mBACkB,cAAc;CAyCpC"}
@@ -131,12 +131,20 @@ class TeamMembership {
131
131
  * 4. Quota is available
132
132
  * 5. Subscription is active
133
133
  *
134
- * @param action - Action slug to check
134
+ * The action id IS the permission id as registered in the permissions
135
+ * registry (e.g. 'team.members.update_role', 'customers.create',
136
+ * 'page-builder.access'). Ids may have any number of dot-separated segments.
137
+ *
138
+ * Fails closed: an action whose id is not a registered permission is denied
139
+ * (and logged) instead of silently allowed, so a typo or a renamed permission
140
+ * surfaces as a visible 403 rather than an unguarded endpoint (issue #89).
141
+ *
142
+ * @param action - Action slug to check (must be a registered permission id)
135
143
  * @param options - Options for quota increment
136
144
  * @returns ActionResult with allowed status and details
137
145
  *
138
146
  * @example
139
- * const result = membership.canPerformAction('projects.create')
147
+ * const result = membership.canPerformAction('team.members.update_role')
140
148
  * if (!result.allowed) {
141
149
  * console.log(result.message, result.reason)
142
150
  * }
@@ -160,25 +168,38 @@ class TeamMembership {
160
168
  }
161
169
  };
162
170
  }
163
- const [entity, actionType] = action.split(".");
164
- const permission = `${entity}.${actionType}`;
165
- if (PermissionService.isValid(permission)) {
166
- if (!this.hasPermission(permission)) {
167
- return {
168
- allowed: false,
169
- reason: "permission_denied",
170
- message: `You do not have permission: ${permission}`,
171
- meta: {
172
- requiredPermission: permission,
173
- userRole: this.role
174
- }
175
- };
176
- }
171
+ const permission = action;
172
+ if (!PermissionService.isValid(permission)) {
173
+ console.warn(
174
+ `[MembershipService] canPerformAction('${action}') denied: '${permission}' is not a registered permission id`
175
+ );
176
+ return {
177
+ allowed: false,
178
+ reason: "permission_denied",
179
+ message: `Unknown permission: ${permission}`,
180
+ meta: {
181
+ requiredPermission: permission,
182
+ userRole: this.role,
183
+ unregistered: true
184
+ }
185
+ };
186
+ }
187
+ if (!this.hasPermission(permission)) {
188
+ return {
189
+ allowed: false,
190
+ reason: "permission_denied",
191
+ message: `You do not have permission: ${permission}`,
192
+ meta: {
193
+ requiredPermission: permission,
194
+ userRole: this.role
195
+ }
196
+ };
177
197
  }
178
198
  const requiredFeature = (_b = (_a = BILLING_REGISTRY.actionMappings) == null ? void 0 : _a.features) == null ? void 0 : _b[action];
179
199
  if (requiredFeature && !this.hasFeature(requiredFeature)) {
180
200
  return {
181
201
  allowed: false,
202
+ // @ts-expect-error — pre-existing type error, tracked in https://github.com/NextSpark-js/nextspark/issues/131
182
203
  reason: "feature_not_in_plan",
183
204
  message: `Your plan does not include the required feature: ${requiredFeature}`,
184
205
  meta: {
@@ -1 +1 @@
1
- {"version":3,"file":"subscription.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/subscription.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subscription.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/subscription.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAcH,OAAO,KAAK,EAEV,YAAY,EACZ,oBAAoB,EACpB,kBAAkB,EAClB,SAAS,EAET,sBAAsB,EACtB,eAAe,EACf,eAAe,EAChB,MAAM,kBAAkB,CAAA;AAMzB,MAAM,WAAW,yBAAyB;IACxC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAMD,qBAAa,mBAAmB;IAK9B;;;;;;;;OAQG;WACU,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAW9D;;;;;;;;;OASG;WACU,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA6B7F;;;;;OAKG;WACU,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAI9E;;;;;;;;;OASG;WACU,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAgC9E;;;;;;;;;;OAUG;WACU,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,YAAY,CAAC;IA+ExB;;;;;;;;OAQG;WACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAejE;;;;;;;;;OASG;WACU,YAAY,CACvB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,CAAC;IA0CxB;;;;;;;;OAQG;WACU,MAAM,CACjB,cAAc,EAAE,MAAM,EACtB,iBAAiB,GAAE,OAAc,GAChC,OAAO,CAAC,YAAY,CAAC;IA4DxB;;;;;;;;;;;;;OAaG;WACU,UAAU,CACrB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,eAAe,GAAE,eAA2B,EAC5C,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC;IAoI5B;;;;;;;;OAQG;WACU,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAcjE;;;;;;;;OAQG;WACU,MAAM,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAclE;;;;;;;;;;OAUG;WACU,YAAY,CACvB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChD,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAoBlC;;;;;;;;OAQG;WACU,gBAAgB,CAAC,IAAI,GAAE,MAAU,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAsBhF;;;;;;;;;;OAUG;WACU,UAAU,CACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAC7E,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA8BlC;;;;;;;;OAQG;WACU,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAsBtF;;;;;;;;;OASG;WACU,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IA+BrF;;;;;;;;OAQG;WACU,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IA4BxE;;;;;;;;;OASG;WACU,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB/F;;;;;;;;;;;;OAYG;WACU,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IA2E/F;;;;;;;;;;;;;;;;;;OAkBG;WACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,sBAAsB,CAAC;IA2ElC;;;;;;;;;OASG;WACU,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;CA+BrD"}
@@ -353,7 +353,8 @@ class SubscriptionService {
353
353
  downgradeWarnings = downgradeCheck.warnings;
354
354
  }
355
355
  try {
356
- await getBillingGateway().updateSubscriptionPlan({
356
+ const gateway = await getBillingGateway();
357
+ await gateway.updateSubscriptionPlan({
357
358
  subscriptionId: currentSub.externalSubscriptionId,
358
359
  newPriceId
359
360
  });
@@ -19,9 +19,15 @@ export declare class TeamMemberService {
19
19
  /**
20
20
  * Get team member by team and user ID
21
21
  *
22
+ * Only resolves memberships of active teams. Team deletion is a soft delete
23
+ * (UPDATE "teams" SET "deletedAt"), which never fires the ON DELETE CASCADE
24
+ * on team_members, so membership rows outlive the team. A member of a
25
+ * soft-deleted team is reported as "not a member" (null), the same shape
26
+ * callers already handle for users who were never on the team (issue #88).
27
+ *
22
28
  * @param teamId - Team ID
23
29
  * @param userId - User ID
24
- * @returns Team member or null if not found
30
+ * @returns Team member or null if not found (or if the team is soft-deleted)
25
31
  *
26
32
  * @example
27
33
  * const member = await TeamMemberService.getByTeamAndUser('team-123', 'user-456')
@@ -41,9 +47,12 @@ export declare class TeamMemberService {
41
47
  /**
42
48
  * Get user's role in a team
43
49
  *
50
+ * Only resolves roles in active teams: a member of a soft-deleted team
51
+ * (teams."deletedAt" set) is reported as not a member (issue #88).
52
+ *
44
53
  * @param teamId - Team ID
45
54
  * @param userId - User ID
46
- * @returns The user's role or null if not a member
55
+ * @returns The user's role or null if not a member (or if the team is soft-deleted)
47
56
  *
48
57
  * @example
49
58
  * const role = await TeamMemberService.getRole('team-123', 'user-456')
@@ -115,9 +124,12 @@ export declare class TeamMemberService {
115
124
  /**
116
125
  * Check if user is a member of a team
117
126
  *
127
+ * Only counts membership in active teams: a member of a soft-deleted team
128
+ * (teams."deletedAt" set) is reported as not a member (issue #88).
129
+ *
118
130
  * @param teamId - Team ID
119
131
  * @param userId - User ID
120
- * @returns True if user is a member
132
+ * @returns True if user is a member of an active team
121
133
  *
122
134
  * @example
123
135
  * const isMember = await TeamMemberService.isMember('team-123', 'user-456')
@@ -1 +1 @@
1
- {"version":3,"file":"team-member.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/team-member.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAM1D,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,qBAAa,iBAAiB;IAK5B;;;;;;;;;OASG;WACU,gBAAgB,CAC3B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAY7B;;;;;;;;;OASG;WACU,UAAU,CACrB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA4BhC;;;;;;;;;OASG;WACU,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAkB9E;;;;;;;;;;;;;OAaG;WACU,GAAG,CACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC;IAwCtB;;;;;;;;;OASG;WACU,WAAW,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,QAAoE,EAC1E,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAoBhB;;;;;;;;;;OAUG;WACU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,aAAa,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,UAAU,CAAA;KAAE,CAAC;IAiE/D;;;;;;;;OAQG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBlE;;;;;;;;;;OAUG;WACU,UAAU,CACrB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC,UAAU,CAAC;IAuCtB;;;;;;;;;OASG;WACU,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAcvE;;;;;;;;;;;;;;OAcG;WACU,aAAa,CACxB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,QAAQ,EAAuB,GAC7C,OAAO,CAAC,OAAO,CAAC;IAcnB;;;;;;;;OAQG;WACU,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAanD;;;;;;;;;OASG;WACU,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAyBzE;;;;;;;;;OASG;WACU,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG;QAClE,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAC,CAAC;IA2BH;;;;;;;;;;OAUG;WACU,UAAU,CACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,EACd,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAwBhC;;;;;;;;;;OAUG;WACU,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAmChC;;;;;;;;;;OAUG;WACU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAW,EAClB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAqBhC;;;;;;;;;;OAUG;WACU,aAAa,CACxB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,EACvB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAuBjC"}
1
+ {"version":3,"file":"team-member.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/team-member.service.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,15 @@ class TeamMemberService {
8
8
  /**
9
9
  * Get team member by team and user ID
10
10
  *
11
+ * Only resolves memberships of active teams. Team deletion is a soft delete
12
+ * (UPDATE "teams" SET "deletedAt"), which never fires the ON DELETE CASCADE
13
+ * on team_members, so membership rows outlive the team. A member of a
14
+ * soft-deleted team is reported as "not a member" (null), the same shape
15
+ * callers already handle for users who were never on the team (issue #88).
16
+ *
11
17
  * @param teamId - Team ID
12
18
  * @param userId - User ID
13
- * @returns Team member or null if not found
19
+ * @returns Team member or null if not found (or if the team is soft-deleted)
14
20
  *
15
21
  * @example
16
22
  * const member = await TeamMemberService.getByTeamAndUser('team-123', 'user-456')
@@ -20,7 +26,10 @@ class TeamMemberService {
20
26
  return null;
21
27
  }
22
28
  return queryOneWithRLS(
23
- 'SELECT * FROM "team_members" WHERE "teamId" = $1 AND "userId" = $2',
29
+ `SELECT tm.*
30
+ FROM "team_members" tm
31
+ INNER JOIN "teams" t ON t.id = tm."teamId"
32
+ WHERE tm."teamId" = $1 AND tm."userId" = $2 AND t."deletedAt" IS NULL`,
24
33
  [teamId, userId],
25
34
  userId
26
35
  );
@@ -64,9 +73,12 @@ class TeamMemberService {
64
73
  /**
65
74
  * Get user's role in a team
66
75
  *
76
+ * Only resolves roles in active teams: a member of a soft-deleted team
77
+ * (teams."deletedAt" set) is reported as not a member (issue #88).
78
+ *
67
79
  * @param teamId - Team ID
68
80
  * @param userId - User ID
69
- * @returns The user's role or null if not a member
81
+ * @returns The user's role or null if not a member (or if the team is soft-deleted)
70
82
  *
71
83
  * @example
72
84
  * const role = await TeamMemberService.getRole('team-123', 'user-456')
@@ -76,7 +88,10 @@ class TeamMemberService {
76
88
  return null;
77
89
  }
78
90
  const member = await queryOneWithRLS(
79
- 'SELECT role FROM "team_members" WHERE "teamId" = $1 AND "userId" = $2',
91
+ `SELECT tm.role
92
+ FROM "team_members" tm
93
+ INNER JOIN "teams" t ON t.id = tm."teamId"
94
+ WHERE tm."teamId" = $1 AND tm."userId" = $2 AND t."deletedAt" IS NULL`,
80
95
  [teamId, userId],
81
96
  userId
82
97
  );
@@ -281,9 +296,12 @@ class TeamMemberService {
281
296
  /**
282
297
  * Check if user is a member of a team
283
298
  *
299
+ * Only counts membership in active teams: a member of a soft-deleted team
300
+ * (teams."deletedAt" set) is reported as not a member (issue #88).
301
+ *
284
302
  * @param teamId - Team ID
285
303
  * @param userId - User ID
286
- * @returns True if user is a member
304
+ * @returns True if user is a member of an active team
287
305
  *
288
306
  * @example
289
307
  * const isMember = await TeamMemberService.isMember('team-123', 'user-456')
@@ -293,7 +311,10 @@ class TeamMemberService {
293
311
  return false;
294
312
  }
295
313
  const member = await queryOneWithRLS(
296
- 'SELECT id FROM "team_members" WHERE "teamId" = $1 AND "userId" = $2',
314
+ `SELECT tm.id
315
+ FROM "team_members" tm
316
+ INNER JOIN "teams" t ON t.id = tm."teamId"
317
+ WHERE tm."teamId" = $1 AND tm."userId" = $2 AND t."deletedAt" IS NULL`,
297
318
  [teamId, userId],
298
319
  userId
299
320
  );
@@ -1 +1 @@
1
- {"version":3,"file":"team.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/team.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAOpD,MAAM,WAAW,mBAAoB,SAAQ,IAAI;IAC/C,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI;IAC3C,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAMD,qBAAa,WAAW;IAKtB;;;;;;;;;OASG;WACU,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAY3E;;;;;;;;OAQG;WACU,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW1D;;;;;;;;OAQG;WACU,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAO9C;;;;;;;;OAQG;WACU,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1C;;;;;;;;OAQG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA2CrE;;;;;;;;;OASG;WACU,kBAAkB,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IA2BtC;;;;;;;;OAQG;WACU,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7C,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,GAAG,IAAI,CAAC;IAmBT;;;;;;;;OAQG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAgB1D;;;;;;;;;;OAUG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsEjE;;;;;;;;;;OAUG;WACU,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA+DhB;;;;;;;;;OASG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoClE;;;;;;;;;OASG;WACU,eAAe,CAC1B,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;IAoBnB;;;;;;;;;OASG;WACU,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC5D;;;;;;;;;;OAUG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0B3E;;;;;;;;OAQG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAYtD"}
1
+ {"version":3,"file":"team.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/team.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAOpD,MAAM,WAAW,mBAAoB,SAAQ,IAAI;IAC/C,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI;IAC3C,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAMD,qBAAa,WAAW;IAKtB;;;;;;;;;OASG;WACU,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAY3E;;;;;;;;OAQG;WACU,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAW1D;;;;;;;;OAQG;WACU,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAO9C;;;;;;;;OAQG;WACU,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAK1C;;;;;;;;OAQG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IA4CrE;;;;;;;;;OASG;WACU,kBAAkB,CAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IA2BtC;;;;;;;;OAQG;WACU,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7C,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KACrB,GAAG,IAAI,CAAC;IAmBT;;;;;;;;OAQG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAgB1D;;;;;;;;;;OAUG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsEjE;;;;;;;;;;OAUG;WACU,MAAM,CACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IA+DhB;;;;;;;;;OASG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoClE;;;;;;;;;OASG;WACU,eAAe,CAC1B,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;IAoBnB;;;;;;;;;OASG;WACU,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC5D;;;;;;;;;;OAUG;WACU,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0B3E;;;;;;;;OAQG;WACU,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAYtD"}
@@ -133,7 +133,9 @@ export declare function isInvitableRole(role: string): boolean;
133
133
  export declare function getInvitableRoles(): string[];
134
134
  /**
135
135
  * Validate role transition
136
- * Check if changing from one role to another is allowed
136
+ * Check if changing from one role to another is allowed.
137
+ *
138
+ * The actor must strictly outrank BOTH the current role and the new role.
137
139
  *
138
140
  * @param fromRole - Current role
139
141
  * @param toRole - New role
@@ -1 +1 @@
1
- {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/lib/teams/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAA;AAE9C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,WAAW,GACX,aAAa,GACb,mBAAmB,GACnB,qBAAqB,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,CAAA;AAEzB;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,EAYhD,CAAA;AAuCD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAgC,CAAA;AAM7F;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,cAAc,EAC1B,aAAa,GAAE,OAAe,GAC7B,OAAO,CAWT;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,OAAe,GAC7B,cAAc,EAAE,CAQlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,cAAc,GACzB,OAAO,CAcT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAExD;AAMD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAKT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAIT;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAI5C;AAMD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA0BvC"}
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/lib/teams/permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAUH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAA;AAE9C;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,WAAW,GACX,aAAa,GACb,mBAAmB,GACnB,qBAAqB,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,CAAA;AAEzB;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,cAAc,EAYhD,CAAA;AAuCD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAgC,CAAA;AAM7F;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,cAAc,EAC1B,aAAa,GAAE,OAAe,GAC7B,OAAO,CAWT;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,OAAe,GAC7B,cAAc,EAAE,CAQlB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,cAAc,GACzB,OAAO,CAcT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAExD;AAMD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAKT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAIT;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGrD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAI5C;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoCvC"}
@@ -97,6 +97,12 @@ function validateRoleTransition(fromRole, toRole, actorRole) {
97
97
  reason: "You do not have permission to change this user's role."
98
98
  };
99
99
  }
100
+ if (!canManageRole(actorRole, toRole)) {
101
+ return {
102
+ allowed: false,
103
+ reason: "You cannot assign a role equal to or higher than your own."
104
+ };
105
+ }
100
106
  return { allowed: true };
101
107
  }
102
108
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/lib/teams/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,cAAc,aAG1B,CAAA;AACD,eAAO,MAAM,sBAAsB;;;;;EAAyD,CAAA;AAG5F,eAAO,MAAM,UAAU;;;;;;;;;;iBAerB,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;iBAS3B,CAAA;AAGF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;iBAa/B,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;iBAOhC,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;iBAIhC,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;iBAAqD,CAAA;AAElF,eAAO,MAAM,kBAAkB;;;iBAM7B,CAAA;AAEF,eAAO,MAAM,sBAAsB;;iBAKjC,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAA;AAGF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAK9B,CAAA;AAEF,eAAO,MAAM,qBAAqB;;;;;iBAGhC,CAAA;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;iBAEpC,CAAA;AAGF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACvE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AACnE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAC3E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AACrE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/lib/teams/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,cAAc,aAI1B,CAAA;AACD,eAAO,MAAM,sBAAsB;;;;;EAAyD,CAAA;AAG5F,eAAO,MAAM,UAAU;;;;;;;;;;iBAerB,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;iBAS3B,CAAA;AAGF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;iBAa/B,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;iBAOhC,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;iBAIhC,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;iBAAqD,CAAA;AAElF,eAAO,MAAM,kBAAkB;;;iBAO7B,CAAA;AAEF,eAAO,MAAM,sBAAsB;;iBAMjC,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAA;AAGF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAK9B,CAAA;AAEF,eAAO,MAAM,qBAAqB;;;;;iBAGhC,CAAA;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;iBAEpC,CAAA;AAGF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACvE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAA;AACnE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAC3E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AACrE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA;AACzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA"}
@@ -3,6 +3,7 @@ import { AVAILABLE_ROLES } from "@nextsparkjs/registries/permissions-registry";
3
3
  import { getInvitableRoles } from "./permissions.js";
4
4
  const teamRoleSchema = z.string().refine(
5
5
  (role) => AVAILABLE_ROLES.includes(role),
6
+ // @ts-expect-error — pre-existing type error, tracked in https://github.com/NextSpark-js/nextspark/issues/131
6
7
  (role) => ({ message: `Invalid team role: ${role}. Must be one of: ${[...AVAILABLE_ROLES].join(", ")}` })
7
8
  );
8
9
  const invitationStatusSchema = z.enum(["pending", "accepted", "declined", "expired"]);
@@ -65,6 +66,7 @@ const inviteMemberSchema = z.object({
65
66
  email: z.string().email("Invalid email address"),
66
67
  role: z.string().refine(
67
68
  (role) => getInvitableRoles().includes(role),
69
+ // @ts-expect-error — pre-existing type error, tracked in https://github.com/NextSpark-js/nextspark/issues/131
68
70
  (role) => ({ message: `Role must be one of: ${getInvitableRoles().join(", ")}` })
69
71
  )
70
72
  // Cannot invite as owner
@@ -72,6 +74,7 @@ const inviteMemberSchema = z.object({
72
74
  const updateMemberRoleSchema = z.object({
73
75
  role: z.string().refine(
74
76
  (role) => getInvitableRoles().includes(role),
77
+ // @ts-expect-error — pre-existing type error, tracked in https://github.com/NextSpark-js/nextspark/issues/131
75
78
  (role) => ({ message: `Role must be one of: ${getInvitableRoles().join(", ")}` })
76
79
  )
77
80
  // Cannot promote to owner
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Route-based forced theme
3
+ *
4
+ * Resolves the theme that must be forced for a given pathname from the
5
+ * `forcedThemeRoutes` map declared in `theme.config.ts`. The result is passed
6
+ * to next-themes' `forcedTheme` prop on the single root ThemeProvider, so the
7
+ * blocking script, SSR output and client hydration all agree from the very
8
+ * first paint (no flash, no post-hydration correction).
9
+ *
10
+ * Matching rules:
11
+ * - Keys are route prefixes matched at segment boundaries:
12
+ * `'/login'` matches `/login` and `/login/verify`, but not `/login-help`.
13
+ * - `'/'` matches every route.
14
+ * - When several prefixes match, the longest (most specific) one wins.
15
+ * - Query strings, hashes and trailing slashes are ignored.
16
+ *
17
+ * @example
18
+ * forcedThemeRoutes: { '/login': 'light', '/signup': 'light', '/embed': 'dark' }
19
+ */
20
+ export type ForcedThemeMode = 'light' | 'dark';
21
+ /** Route prefix → theme to force on that route subtree */
22
+ export type ForcedThemeRoutes = Record<string, ForcedThemeMode>;
23
+ /**
24
+ * Resolve the forced theme for a pathname.
25
+ *
26
+ * Pure function (no Next.js imports) so it can run on the server, in client
27
+ * components and in unit tests.
28
+ *
29
+ * @param pathname - Current pathname (e.g. from `usePathname()` or the `x-pathname` header)
30
+ * @param routes - `forcedThemeRoutes` from the active theme config
31
+ * @returns The theme to force, or `undefined` when the route is not forced
32
+ */
33
+ export declare function resolveForcedTheme(pathname: string | null | undefined, routes: ForcedThemeRoutes | null | undefined): ForcedThemeMode | undefined;
34
+ //# sourceMappingURL=forced-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forced-theme.d.ts","sourceRoot":"","sources":["../../../src/lib/theme/forced-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,CAAA;AAE9C,0DAA0D;AAC1D,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAmB/D;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAC3C,eAAe,GAAG,SAAS,CAkB7B"}
@@ -0,0 +1,27 @@
1
+ const FORCED_THEME_MODES = ["light", "dark"];
2
+ function isForcedThemeMode(value) {
3
+ return typeof value === "string" && FORCED_THEME_MODES.includes(value);
4
+ }
5
+ function normalizePath(value) {
6
+ let path = value.split(/[?#]/)[0].trim();
7
+ if (!path.startsWith("/")) path = `/${path}`;
8
+ path = path.replace(/\/+$/, "");
9
+ return path === "" ? "/" : path;
10
+ }
11
+ function resolveForcedTheme(pathname, routes) {
12
+ if (!pathname || !routes) return void 0;
13
+ const path = normalizePath(pathname);
14
+ let best;
15
+ for (const [pattern, theme] of Object.entries(routes)) {
16
+ if (!isForcedThemeMode(theme)) continue;
17
+ const prefix = normalizePath(pattern);
18
+ const matches = prefix === "/" || path === prefix || path.startsWith(`${prefix}/`);
19
+ if (matches && (!best || prefix.length > best.length)) {
20
+ best = { length: prefix.length, theme };
21
+ }
22
+ }
23
+ return best == null ? void 0 : best.theme;
24
+ }
25
+ export {
26
+ resolveForcedTheme
27
+ };