@nextsparkjs/core 0.1.0-beta.194 → 0.1.0-beta.196

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 (481) hide show
  1. package/dist/components/app/guards/DeveloperGuard.d.ts +8 -1
  2. package/dist/components/app/guards/DeveloperGuard.d.ts.map +1 -1
  3. package/dist/components/app/guards/DeveloperGuard.js +2 -1
  4. package/dist/components/app/guards/SuperAdminGuard.d.ts +8 -1
  5. package/dist/components/app/guards/SuperAdminGuard.d.ts.map +1 -1
  6. package/dist/components/app/guards/SuperAdminGuard.js +2 -1
  7. package/dist/components/billing/InvoicesPagination.js +2 -2
  8. package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
  9. package/dist/components/dashboard/block-editor/block-picker.js +2 -1
  10. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  11. package/dist/components/dashboard/block-editor/builder-editor-view.js +39 -23
  12. package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
  13. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
  14. package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
  15. package/dist/components/dashboard/layouts/AuthGuard.js +3 -4
  16. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.d.ts.map +1 -1
  17. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.js +9 -10
  18. package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
  19. package/dist/components/dashboard/layouts/DashboardAuthLayout.js +3 -4
  20. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +2 -2
  21. package/dist/components/dashboard/navigation/DynamicNavigation.js +2 -2
  22. package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
  23. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -2
  24. package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
  25. package/dist/components/entities/wrappers/EntityFormWrapper.js +5 -2
  26. package/dist/components/entities/wrappers/EntityListWrapper.d.ts.map +1 -1
  27. package/dist/components/entities/wrappers/EntityListWrapper.js +5 -2
  28. package/dist/components/settings/layouts/SettingsSidebar.d.ts.map +1 -1
  29. package/dist/components/settings/layouts/SettingsSidebar.js +0 -1
  30. package/dist/components/teams/CreateTeamButton.js +2 -2
  31. package/dist/components/teams/CreateTeamDialog.js +1 -1
  32. package/dist/components/teams/InviteMemberButton.js +3 -3
  33. package/dist/components/teams/InviteMemberDialog.js +1 -1
  34. package/dist/components/teams/TeamPendingInvitations.js +2 -2
  35. package/dist/components/ui/relation-display.d.ts.map +1 -1
  36. package/dist/components/ui/relation-display.js +2 -1
  37. package/dist/components/ui/user-display.d.ts.map +1 -1
  38. package/dist/components/ui/user-display.js +2 -1
  39. package/dist/emails/otp-verification.d.ts.map +1 -1
  40. package/dist/emails/otp-verification.js +5 -3
  41. package/dist/emails/reset-password.d.ts.map +1 -1
  42. package/dist/emails/reset-password.js +5 -3
  43. package/dist/emails/team-invitation.d.ts.map +1 -1
  44. package/dist/emails/team-invitation.js +3 -2
  45. package/dist/emails/verify-email.d.ts.map +1 -1
  46. package/dist/emails/verify-email.js +5 -3
  47. package/dist/hooks/useAuth.d.ts.map +1 -1
  48. package/dist/hooks/useAuth.js +21 -4
  49. package/dist/hooks/usePatternUsages.d.ts.map +1 -1
  50. package/dist/hooks/usePatternUsages.js +3 -2
  51. package/dist/lib/api/api-error.d.ts +2 -0
  52. package/dist/lib/api/api-error.d.ts.map +1 -1
  53. package/dist/lib/api/api-error.js +3 -1
  54. package/dist/lib/api/auth/dual-auth.d.ts +2 -1
  55. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  56. package/dist/lib/api/auth/dual-auth.js +22 -4
  57. package/dist/lib/api/auth/scope-policy.d.ts +6 -3
  58. package/dist/lib/api/auth/scope-policy.d.ts.map +1 -1
  59. package/dist/lib/api/auth.d.ts +2 -0
  60. package/dist/lib/api/auth.d.ts.map +1 -1
  61. package/dist/lib/api/auth.js +10 -10
  62. package/dist/lib/api/client-headers.d.ts +11 -0
  63. package/dist/lib/api/client-headers.d.ts.map +1 -0
  64. package/dist/lib/api/client-headers.js +12 -0
  65. package/dist/lib/api/client-ip.d.ts +59 -0
  66. package/dist/lib/api/client-ip.d.ts.map +1 -0
  67. package/dist/lib/api/client-ip.js +91 -0
  68. package/dist/lib/api/cors-response.d.ts +55 -0
  69. package/dist/lib/api/cors-response.d.ts.map +1 -0
  70. package/dist/lib/api/cors-response.js +90 -0
  71. package/dist/lib/api/entities.d.ts.map +1 -1
  72. package/dist/lib/api/entities.js +4 -3
  73. package/dist/lib/api/entity/audit-log.d.ts.map +1 -1
  74. package/dist/lib/api/entity/audit-log.js +2 -1
  75. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  76. package/dist/lib/api/entity/generic-handler.js +23 -8
  77. package/dist/lib/api/helpers.d.ts +8 -2
  78. package/dist/lib/api/helpers.d.ts.map +1 -1
  79. package/dist/lib/api/helpers.js +32 -103
  80. package/dist/lib/api/keys.d.ts +6 -0
  81. package/dist/lib/api/keys.d.ts.map +1 -1
  82. package/dist/lib/api/keys.js +7 -1
  83. package/dist/lib/api/permission-middleware.d.ts.map +1 -1
  84. package/dist/lib/api/permission-middleware.js +0 -2
  85. package/dist/lib/api/rate-limit.d.ts +12 -0
  86. package/dist/lib/api/rate-limit.d.ts.map +1 -1
  87. package/dist/lib/api/rate-limit.js +50 -43
  88. package/dist/lib/api/request-origin.d.ts +16 -7
  89. package/dist/lib/api/request-origin.d.ts.map +1 -1
  90. package/dist/lib/api/request-origin.js +43 -20
  91. package/dist/lib/auth/load-login-page.d.ts +10 -0
  92. package/dist/lib/auth/load-login-page.d.ts.map +1 -0
  93. package/dist/lib/auth/load-login-page.js +7 -0
  94. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  95. package/dist/lib/auth/runtime-readiness.js +4 -0
  96. package/dist/lib/auth/sample-accounts.d.ts +17 -0
  97. package/dist/lib/auth/sample-accounts.d.ts.map +1 -0
  98. package/dist/lib/auth/sample-accounts.js +22 -0
  99. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +1 -8
  100. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -1
  101. package/dist/lib/auth/security-notifications/device-fingerprint.js +2 -12
  102. package/dist/lib/auth-email-callbacks.js +3 -3
  103. package/dist/lib/auth.d.ts.map +1 -1
  104. package/dist/lib/auth.js +13 -5
  105. package/dist/lib/cache/public-entity-cache.d.ts +21 -0
  106. package/dist/lib/cache/public-entity-cache.d.ts.map +1 -0
  107. package/dist/lib/cache/public-entity-cache.js +25 -0
  108. package/dist/lib/config/config-client.d.ts.map +1 -1
  109. package/dist/lib/config/config-client.js +1 -1
  110. package/dist/lib/config/config-sync.d.ts.map +1 -1
  111. package/dist/lib/config/config-sync.js +1 -1
  112. package/dist/lib/config/public-config-client.d.ts +1 -0
  113. package/dist/lib/config/public-config-client.d.ts.map +1 -1
  114. package/dist/lib/config/public-config-client.js +3 -1
  115. package/dist/lib/config/types.d.ts +2 -0
  116. package/dist/lib/config/types.d.ts.map +1 -1
  117. package/dist/lib/constants/reserved-slugs.d.ts +17 -8
  118. package/dist/lib/constants/reserved-slugs.d.ts.map +1 -1
  119. package/dist/lib/constants/reserved-slugs.js +16 -52
  120. package/dist/lib/db.d.ts.map +1 -1
  121. package/dist/lib/db.js +9 -3
  122. package/dist/lib/entities/entity-hooks.d.ts.map +1 -1
  123. package/dist/lib/entities/entity-hooks.js +4 -0
  124. package/dist/lib/entities/external-api-generator.d.ts.map +1 -1
  125. package/dist/lib/entities/external-api-generator.js +2 -4
  126. package/dist/lib/entities/public-slug.d.ts +46 -0
  127. package/dist/lib/entities/public-slug.d.ts.map +1 -0
  128. package/dist/lib/entities/public-slug.js +39 -0
  129. package/dist/lib/mcp/errors.d.ts +2 -0
  130. package/dist/lib/mcp/errors.d.ts.map +1 -1
  131. package/dist/lib/mcp/errors.js +3 -1
  132. package/dist/lib/mcp/index.d.ts +1 -1
  133. package/dist/lib/mcp/index.d.ts.map +1 -1
  134. package/dist/lib/mcp/index.js +2 -1
  135. package/dist/lib/services/generic-entity.service.d.ts.map +1 -1
  136. package/dist/lib/services/generic-entity.service.js +2 -0
  137. package/dist/lib/teams/actions.d.ts.map +1 -1
  138. package/dist/lib/teams/actions.js +0 -1
  139. package/dist/messages/de/billing.json +12 -1
  140. package/dist/messages/de/common.json +2 -0
  141. package/dist/messages/de/docs.json +1 -0
  142. package/dist/messages/de/features.json +16 -4
  143. package/dist/messages/de/home.json +5 -0
  144. package/dist/messages/de/index.d.ts +68 -25
  145. package/dist/messages/de/index.d.ts.map +1 -1
  146. package/dist/messages/de/index.js +2 -0
  147. package/dist/messages/de/index.ts +2 -0
  148. package/dist/messages/de/settings.json +1 -0
  149. package/dist/messages/de/teams.json +3 -18
  150. package/dist/messages/en/billing.json +1 -1
  151. package/dist/messages/en/common.json +2 -0
  152. package/dist/messages/en/docs.json +1 -0
  153. package/dist/messages/en/features.json +16 -4
  154. package/dist/messages/en/home.json +5 -0
  155. package/dist/messages/en/index.d.ts +58 -25
  156. package/dist/messages/en/index.d.ts.map +1 -1
  157. package/dist/messages/en/index.js +2 -0
  158. package/dist/messages/en/index.ts +2 -0
  159. package/dist/messages/en/settings.json +1 -0
  160. package/dist/messages/en/teams.json +3 -18
  161. package/dist/messages/es/billing.json +1 -1
  162. package/dist/messages/es/common.json +2 -0
  163. package/dist/messages/es/docs.json +1 -0
  164. package/dist/messages/es/features.json +16 -4
  165. package/dist/messages/es/home.json +5 -0
  166. package/dist/messages/es/index.d.ts +41 -8
  167. package/dist/messages/es/index.d.ts.map +1 -1
  168. package/dist/messages/es/index.js +2 -0
  169. package/dist/messages/es/index.ts +2 -0
  170. package/dist/messages/es/settings.json +1 -0
  171. package/dist/messages/es/teams.json +3 -0
  172. package/dist/messages/fr/billing.json +12 -1
  173. package/dist/messages/fr/common.json +2 -0
  174. package/dist/messages/fr/docs.json +1 -0
  175. package/dist/messages/fr/features.json +16 -4
  176. package/dist/messages/fr/home.json +5 -0
  177. package/dist/messages/fr/index.d.ts +68 -25
  178. package/dist/messages/fr/index.d.ts.map +1 -1
  179. package/dist/messages/fr/index.js +2 -0
  180. package/dist/messages/fr/index.ts +2 -0
  181. package/dist/messages/fr/settings.json +1 -0
  182. package/dist/messages/fr/teams.json +3 -18
  183. package/dist/messages/it/billing.json +12 -1
  184. package/dist/messages/it/common.json +2 -0
  185. package/dist/messages/it/docs.json +1 -0
  186. package/dist/messages/it/features.json +16 -4
  187. package/dist/messages/it/home.json +5 -0
  188. package/dist/messages/it/index.d.ts +68 -25
  189. package/dist/messages/it/index.d.ts.map +1 -1
  190. package/dist/messages/it/index.js +2 -0
  191. package/dist/messages/it/index.ts +2 -0
  192. package/dist/messages/it/settings.json +1 -0
  193. package/dist/messages/it/teams.json +3 -18
  194. package/dist/messages/pt/billing.json +12 -1
  195. package/dist/messages/pt/common.json +2 -0
  196. package/dist/messages/pt/docs.json +1 -0
  197. package/dist/messages/pt/features.json +16 -4
  198. package/dist/messages/pt/home.json +5 -0
  199. package/dist/messages/pt/index.d.ts +68 -25
  200. package/dist/messages/pt/index.d.ts.map +1 -1
  201. package/dist/messages/pt/index.js +2 -0
  202. package/dist/messages/pt/index.ts +2 -0
  203. package/dist/messages/pt/settings.json +1 -0
  204. package/dist/messages/pt/teams.json +3 -18
  205. package/dist/migrations/029_sample_accounts_outside_development.sql +55 -0
  206. package/dist/migrations/090_sample_data.sql +10 -0
  207. package/dist/routes/(auth)/signup/page.cc.d.ts +3 -8
  208. package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
  209. package/dist/routes/(auth)/signup/page.cc.js +7 -1
  210. package/dist/routes/(auth)/verify-email/page.d.ts.map +1 -1
  211. package/dist/routes/(auth)/verify-email/page.js +2 -1
  212. package/dist/routes/(public)/page.cc.d.ts +3 -0
  213. package/dist/routes/(public)/page.cc.d.ts.map +1 -0
  214. package/dist/routes/(public)/page.cc.js +3 -0
  215. package/dist/routes/_internal/area-access.cc.d.ts +21 -0
  216. package/dist/routes/_internal/area-access.cc.d.ts.map +1 -0
  217. package/dist/routes/_internal/area-access.cc.js +19 -0
  218. package/dist/routes/_internal/auth-layout.d.ts.map +1 -1
  219. package/dist/routes/_internal/auth-layout.js +3 -2
  220. package/dist/routes/_internal/dashboard-main-shared.d.ts +7 -0
  221. package/dist/routes/_internal/dashboard-main-shared.d.ts.map +1 -0
  222. package/dist/routes/_internal/dashboard-main-shared.js +49 -0
  223. package/dist/routes/_internal/default-auth-layout.d.ts.map +1 -1
  224. package/dist/routes/_internal/default-auth-layout.js +3 -2
  225. package/dist/routes/_internal/devtools-layout.cc.d.ts +3 -2
  226. package/dist/routes/_internal/devtools-layout.cc.d.ts.map +1 -1
  227. package/dist/routes/_internal/devtools-layout.cc.js +1 -1
  228. package/dist/routes/_internal/devtools-layout.d.ts +7 -2
  229. package/dist/routes/_internal/devtools-layout.d.ts.map +1 -1
  230. package/dist/routes/_internal/devtools-layout.js +4 -4
  231. package/dist/routes/_internal/entity-detail-route.cc.d.ts +8 -0
  232. package/dist/routes/_internal/entity-detail-route.cc.d.ts.map +1 -0
  233. package/dist/routes/_internal/entity-detail-route.cc.js +5 -0
  234. package/dist/routes/_internal/entity-edit-route.cc.d.ts +8 -0
  235. package/dist/routes/_internal/entity-edit-route.cc.d.ts.map +1 -0
  236. package/dist/routes/_internal/entity-edit-route.cc.js +5 -0
  237. package/dist/routes/_internal/entity-permission-layout.d.ts.map +1 -1
  238. package/dist/routes/_internal/entity-permission-layout.js +0 -7
  239. package/dist/routes/_internal/public-archive-route.d.ts +1 -1
  240. package/dist/routes/_internal/public-archive-route.d.ts.map +1 -1
  241. package/dist/routes/_internal/public-archive-route.js +8 -3
  242. package/dist/routes/_internal/public-item-route.cc.d.ts +5 -1
  243. package/dist/routes/_internal/public-item-route.cc.d.ts.map +1 -1
  244. package/dist/routes/_internal/public-item-route.cc.js +2 -1
  245. package/dist/routes/_internal/public-item-route.d.ts +7 -0
  246. package/dist/routes/_internal/public-item-route.d.ts.map +1 -1
  247. package/dist/routes/_internal/public-item-route.js +6 -1
  248. package/dist/routes/_internal/superadmin-layout.cc.d.ts +2 -1
  249. package/dist/routes/_internal/superadmin-layout.cc.d.ts.map +1 -1
  250. package/dist/routes/_internal/superadmin-layout.cc.js +1 -1
  251. package/dist/routes/_internal/superadmin-layout.d.ts +7 -2
  252. package/dist/routes/_internal/superadmin-layout.d.ts.map +1 -1
  253. package/dist/routes/_internal/superadmin-layout.js +6 -6
  254. package/dist/routes/_internal/suspended-route.d.ts +16 -0
  255. package/dist/routes/_internal/suspended-route.d.ts.map +1 -0
  256. package/dist/routes/_internal/suspended-route.js +7 -0
  257. package/dist/routes/api/auth/[...all]/route.d.ts.map +1 -1
  258. package/dist/routes/api/auth/[...all]/route.js +4 -12
  259. package/dist/routes/api/csp-report/route.d.ts.map +1 -1
  260. package/dist/routes/api/csp-report/route.js +2 -13
  261. package/dist/routes/api/devtools/config/entities/route.d.ts +2 -0
  262. package/dist/routes/api/devtools/config/entities/route.d.ts.map +1 -1
  263. package/dist/routes/api/devtools/config/entities/route.js +2 -0
  264. package/dist/routes/api/devtools/config/theme/route.d.ts +2 -0
  265. package/dist/routes/api/devtools/config/theme/route.d.ts.map +1 -1
  266. package/dist/routes/api/devtools/config/theme/route.js +2 -0
  267. package/dist/routes/api/devtools/tests/[...path]/route.d.ts +2 -0
  268. package/dist/routes/api/devtools/tests/[...path]/route.d.ts.map +1 -1
  269. package/dist/routes/api/devtools/tests/[...path]/route.js +2 -0
  270. package/dist/routes/api/devtools/tests/route.d.ts +2 -0
  271. package/dist/routes/api/devtools/tests/route.d.ts.map +1 -1
  272. package/dist/routes/api/devtools/tests/route.js +2 -0
  273. package/dist/routes/api/health/route.d.ts +2 -0
  274. package/dist/routes/api/health/route.d.ts.map +1 -1
  275. package/dist/routes/api/health/route.js +2 -0
  276. package/dist/routes/api/internal/user-metadata/route.d.ts +2 -0
  277. package/dist/routes/api/internal/user-metadata/route.d.ts.map +1 -1
  278. package/dist/routes/api/internal/user-metadata/route.js +2 -0
  279. package/dist/routes/api/mcp/route.d.ts +2 -0
  280. package/dist/routes/api/mcp/route.d.ts.map +1 -1
  281. package/dist/routes/api/mcp/route.js +9 -1
  282. package/dist/routes/api/superadmin/subscriptions/route.d.ts +2 -0
  283. package/dist/routes/api/superadmin/subscriptions/route.d.ts.map +1 -1
  284. package/dist/routes/api/superadmin/subscriptions/route.js +2 -0
  285. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts +2 -0
  286. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts.map +1 -1
  287. package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -0
  288. package/dist/routes/api/superadmin/teams/route.d.ts +2 -0
  289. package/dist/routes/api/superadmin/teams/route.d.ts.map +1 -1
  290. package/dist/routes/api/superadmin/teams/route.js +2 -0
  291. package/dist/routes/api/superadmin/users/[userId]/route.d.ts +2 -0
  292. package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
  293. package/dist/routes/api/superadmin/users/[userId]/route.js +2 -0
  294. package/dist/routes/api/superadmin/users/route.d.ts +2 -0
  295. package/dist/routes/api/superadmin/users/route.d.ts.map +1 -1
  296. package/dist/routes/api/superadmin/users/route.js +2 -0
  297. package/dist/routes/api/user/delete-account/route.d.ts +2 -0
  298. package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
  299. package/dist/routes/api/user/delete-account/route.js +2 -0
  300. package/dist/routes/api/user/plan-flags/route.d.ts +2 -0
  301. package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
  302. package/dist/routes/api/user/plan-flags/route.js +2 -0
  303. package/dist/routes/api/user/profile/route.d.ts +2 -0
  304. package/dist/routes/api/user/profile/route.d.ts.map +1 -1
  305. package/dist/routes/api/user/profile/route.js +4 -3
  306. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts +2 -0
  307. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts.map +1 -1
  308. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.js +2 -0
  309. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts +2 -0
  310. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts.map +1 -1
  311. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.js +2 -0
  312. package/dist/routes/api/v1/billing/cancel/route.d.ts +2 -0
  313. package/dist/routes/api/v1/billing/cancel/route.d.ts.map +1 -1
  314. package/dist/routes/api/v1/billing/cancel/route.js +2 -0
  315. package/dist/routes/api/v1/billing/change-plan/route.d.ts +2 -0
  316. package/dist/routes/api/v1/billing/change-plan/route.d.ts.map +1 -1
  317. package/dist/routes/api/v1/billing/change-plan/route.js +2 -0
  318. package/dist/routes/api/v1/billing/check-action/route.d.ts +2 -0
  319. package/dist/routes/api/v1/billing/check-action/route.d.ts.map +1 -1
  320. package/dist/routes/api/v1/billing/check-action/route.js +2 -0
  321. package/dist/routes/api/v1/billing/checkout/route.d.ts +2 -0
  322. package/dist/routes/api/v1/billing/checkout/route.d.ts.map +1 -1
  323. package/dist/routes/api/v1/billing/checkout/route.js +2 -0
  324. package/dist/routes/api/v1/billing/plans/route.d.ts +2 -0
  325. package/dist/routes/api/v1/billing/plans/route.d.ts.map +1 -1
  326. package/dist/routes/api/v1/billing/plans/route.js +2 -0
  327. package/dist/routes/api/v1/billing/portal/route.d.ts +2 -0
  328. package/dist/routes/api/v1/billing/portal/route.d.ts.map +1 -1
  329. package/dist/routes/api/v1/billing/portal/route.js +2 -0
  330. package/dist/routes/api/v1/blocks/[slug]/route.d.ts +2 -0
  331. package/dist/routes/api/v1/blocks/[slug]/route.d.ts.map +1 -1
  332. package/dist/routes/api/v1/blocks/[slug]/route.js +2 -0
  333. package/dist/routes/api/v1/blocks/route.d.ts +2 -0
  334. package/dist/routes/api/v1/blocks/route.d.ts.map +1 -1
  335. package/dist/routes/api/v1/blocks/route.js +2 -0
  336. package/dist/routes/api/v1/blocks/validate/route.d.ts +2 -0
  337. package/dist/routes/api/v1/blocks/validate/route.d.ts.map +1 -1
  338. package/dist/routes/api/v1/blocks/validate/route.js +2 -0
  339. package/dist/routes/api/v1/devtools/blocks/route.d.ts +2 -1
  340. package/dist/routes/api/v1/devtools/blocks/route.d.ts.map +1 -1
  341. package/dist/routes/api/v1/devtools/blocks/route.js +2 -9
  342. package/dist/routes/api/v1/devtools/docs/route.d.ts +2 -0
  343. package/dist/routes/api/v1/devtools/docs/route.d.ts.map +1 -1
  344. package/dist/routes/api/v1/devtools/docs/route.js +2 -0
  345. package/dist/routes/api/v1/devtools/features/route.d.ts +2 -1
  346. package/dist/routes/api/v1/devtools/features/route.d.ts.map +1 -1
  347. package/dist/routes/api/v1/devtools/features/route.js +2 -9
  348. package/dist/routes/api/v1/devtools/flows/route.d.ts +2 -1
  349. package/dist/routes/api/v1/devtools/flows/route.d.ts.map +1 -1
  350. package/dist/routes/api/v1/devtools/flows/route.js +2 -9
  351. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts +2 -1
  352. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts.map +1 -1
  353. package/dist/routes/api/v1/devtools/scheduled-actions/route.js +2 -9
  354. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts +2 -1
  355. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts.map +1 -1
  356. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.js +2 -9
  357. package/dist/routes/api/v1/devtools/testing/route.d.ts +2 -1
  358. package/dist/routes/api/v1/devtools/testing/route.d.ts.map +1 -1
  359. package/dist/routes/api/v1/devtools/testing/route.js +2 -9
  360. package/dist/routes/api/v1/media/[id]/route.d.ts +2 -0
  361. package/dist/routes/api/v1/media/[id]/route.d.ts.map +1 -1
  362. package/dist/routes/api/v1/media/[id]/route.js +2 -0
  363. package/dist/routes/api/v1/media/[id]/tags/route.d.ts +2 -0
  364. package/dist/routes/api/v1/media/[id]/tags/route.d.ts.map +1 -1
  365. package/dist/routes/api/v1/media/[id]/tags/route.js +2 -0
  366. package/dist/routes/api/v1/media/check-duplicates/route.d.ts +2 -0
  367. package/dist/routes/api/v1/media/check-duplicates/route.d.ts.map +1 -1
  368. package/dist/routes/api/v1/media/check-duplicates/route.js +2 -0
  369. package/dist/routes/api/v1/media/route.d.ts +2 -0
  370. package/dist/routes/api/v1/media/route.d.ts.map +1 -1
  371. package/dist/routes/api/v1/media/route.js +2 -0
  372. package/dist/routes/api/v1/media/upload/route.d.ts +4 -1
  373. package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
  374. package/dist/routes/api/v1/media/upload/route.js +12 -2
  375. package/dist/routes/api/v1/media-tags/route.d.ts +2 -0
  376. package/dist/routes/api/v1/media-tags/route.d.ts.map +1 -1
  377. package/dist/routes/api/v1/media-tags/route.js +2 -0
  378. package/dist/routes/api/v1/post-categories/[id]/route.d.ts +2 -0
  379. package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
  380. package/dist/routes/api/v1/post-categories/[id]/route.js +2 -0
  381. package/dist/routes/api/v1/post-categories/route.d.ts +2 -0
  382. package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
  383. package/dist/routes/api/v1/post-categories/route.js +2 -0
  384. package/dist/routes/api/v1/teams/[teamId]/members/route.d.ts.map +1 -1
  385. package/dist/routes/api/v1/teams/[teamId]/members/route.js +14 -12
  386. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts +2 -0
  387. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts.map +1 -1
  388. package/dist/routes/api/v1/teams/[teamId]/subscription/route.js +2 -0
  389. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts +2 -0
  390. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts.map +1 -1
  391. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.js +2 -0
  392. package/dist/routes/api/v1/teams/switch/route.d.ts.map +1 -1
  393. package/dist/routes/api/v1/teams/switch/route.js +4 -1
  394. package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
  395. package/dist/routes/api/v1/users/[id]/route.js +3 -2
  396. package/dist/routes/api/v1/users/docs.md +34 -19
  397. package/dist/routes/api/v1/users/me/route.d.ts +6 -0
  398. package/dist/routes/api/v1/users/me/route.d.ts.map +1 -0
  399. package/dist/routes/api/v1/users/me/route.js +5 -0
  400. package/dist/routes/api/v1/users/presets.ts +2 -2
  401. package/dist/routes/dashboard/(main)/layout.cc.d.ts +4 -0
  402. package/dist/routes/dashboard/(main)/layout.cc.d.ts.map +1 -0
  403. package/dist/routes/dashboard/(main)/layout.cc.js +10 -0
  404. package/dist/routes/dashboard/(main)/layout.d.ts.map +1 -1
  405. package/dist/routes/dashboard/(main)/layout.js +3 -44
  406. package/dist/routes/dashboard/permission-denied/page.d.ts +1 -1
  407. package/dist/routes/dashboard/permission-denied/page.d.ts.map +1 -1
  408. package/dist/routes/dashboard/permission-denied/page.js +5 -1
  409. package/dist/routes/dashboard/settings/password/page.d.ts.map +1 -1
  410. package/dist/routes/dashboard/settings/password/page.js +10 -12
  411. package/dist/routes/devtools/config/page.js +1 -1
  412. package/dist/routes/devtools/layout.cc.d.ts.map +1 -1
  413. package/dist/routes/devtools/layout.cc.js +5 -1
  414. package/dist/routes/devtools/page.js +1 -1
  415. package/dist/routes/devtools/scheduled-actions/page.js +1 -1
  416. package/dist/routes/devtools/tests/[[...path]]/page.js +1 -1
  417. package/dist/routes/manifest.json +10 -0
  418. package/dist/routes/robots.d.ts +10 -0
  419. package/dist/routes/robots.d.ts.map +1 -0
  420. package/dist/routes/robots.js +10 -0
  421. package/dist/routes/superadmin/layout.cc.d.ts.map +1 -1
  422. package/dist/routes/superadmin/layout.cc.js +5 -1
  423. package/dist/routes/variants.json +12 -2
  424. package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
  425. package/dist/templates/ci-workflows/github/cypress-smoke.yml +2 -1
  426. package/dist/templates/next.config.mjs +2 -29
  427. package/dist/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  428. package/dist/templates/projects/blog/api/authors/route.ts +3 -0
  429. package/dist/templates/projects/blog/api/posts/public/route.ts +3 -0
  430. package/dist/templates/projects/starter/README.md +2 -0
  431. package/dist/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
  432. package/dist/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
  433. package/dist/templates/proxy.ts +27 -9
  434. package/dist/templates/public/favicon.ico +0 -0
  435. package/dist/templates/public/uploads/README.md +5 -94
  436. package/migrations/029_sample_accounts_outside_development.sql +55 -0
  437. package/migrations/090_sample_data.sql +10 -0
  438. package/package.json +2 -2
  439. package/scripts/build/registry/__tests__/api-docs-colocated.test.mjs +3 -0
  440. package/scripts/build/registry/__tests__/billing-registry.test.mjs +50 -1
  441. package/scripts/build/registry/__tests__/block-registry.test.mjs +3 -0
  442. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
  443. package/scripts/build/registry/__tests__/quiet-console.mjs +17 -0
  444. package/scripts/build/registry/__tests__/safe-fs.test.mjs +3 -0
  445. package/scripts/build/registry/__tests__/team-roles.test.mjs +3 -0
  446. package/scripts/build/registry/discovery/permissions.test.mjs +3 -0
  447. package/scripts/build/registry/discovery/plugin-capabilities.mjs +2 -2
  448. package/scripts/build/registry/generators/billing-registry.mjs +7 -3
  449. package/scripts/build/registry/host/README.md +25 -1
  450. package/scripts/build/registry/host/__tests__/host-area-access.test.mjs +32 -0
  451. package/scripts/build/registry/host/__tests__/host-entities.test.mjs +32 -1
  452. package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
  453. package/scripts/build/registry/host/__tests__/host-proxy-areas.test.mjs +72 -1
  454. package/scripts/build/registry/host/entity-routes.mjs +9 -3
  455. package/scripts/build/registry/host/proxy-areas.mjs +65 -2
  456. package/scripts/build/registry/host/static-imports.mjs +4 -0
  457. package/scripts/build/routes-manifest.mjs +13 -1
  458. package/scripts/db/run-migrations.mjs +30 -10
  459. package/scripts/db/sample-data.mjs +44 -0
  460. package/scripts/db/ssl-config.mjs +12 -1
  461. package/scripts/db/verify-theme-migrations.mjs +6 -0
  462. package/templates/ci-workflows/github/cypress-regression.yml +1 -1
  463. package/templates/ci-workflows/github/cypress-smoke.yml +2 -1
  464. package/templates/next.config.mjs +2 -29
  465. package/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  466. package/templates/projects/blog/api/authors/route.ts +3 -0
  467. package/templates/projects/blog/api/posts/public/route.ts +3 -0
  468. package/templates/projects/starter/README.md +2 -0
  469. package/templates/projects/starter/docs/public/01-overview/01-introduction.md +2 -0
  470. package/templates/projects/starter/templates/dashboard/analytics/layout.tsx +14 -0
  471. package/templates/proxy.ts +27 -9
  472. package/templates/public/favicon.ico +0 -0
  473. package/templates/public/uploads/README.md +5 -94
  474. package/tests/jest/__mocks__/@nextsparkjs/registries/api-presets-registry.ts +2 -0
  475. package/tests/jest/__mocks__/@nextsparkjs/registries/mcp-registry.ts +2 -0
  476. package/dist/templates/projects/starter/public/brand/.gitkeep +0 -0
  477. package/dist/templates/public/uploads/.gitignore +0 -6
  478. package/dist/templates/public/uploads/temp/.gitkeep +0 -1
  479. package/templates/projects/starter/public/brand/.gitkeep +0 -0
  480. package/templates/public/uploads/.gitignore +0 -6
  481. package/templates/public/uploads/temp/.gitkeep +0 -1
@@ -4,6 +4,7 @@ import { createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/hel
4
4
  import { API_ERROR_CODES } from "@nextsparkjs/core/lib/api/api-error";
5
5
  import { checkPermission } from "@nextsparkjs/core/lib/permissions/check";
6
6
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
7
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
7
8
  import { MEDIA_CONFIG } from "@nextsparkjs/core/lib/config/config-sync";
8
9
  import { MediaService } from "@nextsparkjs/core/lib/services/media.service";
9
10
  import { extractImageDimensions } from "@nextsparkjs/core/lib/media/utils";
@@ -14,6 +15,13 @@ const isVercelBlobConfigured = () => {
14
15
  const token = process.env.BLOB_READ_WRITE_TOKEN;
15
16
  return !!token && token.startsWith("vercel_blob_");
16
17
  };
18
+ const localFallbackAllowed = () => process.env.NODE_ENV !== "production";
19
+ const storageNotConfigured = () => createApiError(
20
+ 'Media storage is not configured: set BLOB_READ_WRITE_TOKEN (a Vercel Blob read/write token, starts with "vercel_blob_") to upload files in production.',
21
+ 503,
22
+ { missing: "BLOB_READ_WRITE_TOKEN" },
23
+ API_ERROR_CODES.STORAGE_NOT_CONFIGURED
24
+ );
17
25
  async function uploadToLocalStorageBuffer(buffer, fileName) {
18
26
  const uploadDir = join(process.cwd(), "public", "uploads", "temp");
19
27
  if (!existsSync(uploadDir)) {
@@ -36,6 +44,7 @@ export const POST = withRateLimitTier(async (request) => {
36
44
  if (!await checkPermission(authResult.user.id, teamId, "media.upload")) {
37
45
  return createApiError("Permission denied", 403, void 0, API_ERROR_CODES.PERMISSION_DENIED);
38
46
  }
47
+ if (!isVercelBlobConfigured() && !localFallbackAllowed()) return storageNotConfigured();
39
48
  const formData = await request.formData();
40
49
  const files = Array.from(formData.getAll("files")).filter((value) => value instanceof File);
41
50
  if (files.length === 0) {
@@ -45,7 +54,6 @@ export const POST = withRateLimitTier(async (request) => {
45
54
  const uploadedMedia = [];
46
55
  const useVercelBlob = isVercelBlobConfigured();
47
56
  console.log(`\u{1F4E4} [Media Upload] Storage mode: ${useVercelBlob ? "Vercel Blob" : "Local Storage"}`);
48
- console.log(`\u{1F4E4} [Media Upload] Team context: ${teamId}`);
49
57
  for (const file of files) {
50
58
  if (!file.size) {
51
59
  continue;
@@ -100,6 +108,7 @@ export const POST = withRateLimitTier(async (request) => {
100
108
  uploadedUrl = blob.url;
101
109
  console.log(`\u2705 [Media Upload] Uploaded to Vercel Blob: ${uploadedUrl}`);
102
110
  } catch (blobError) {
111
+ if (!localFallbackAllowed()) throw blobError;
103
112
  console.warn(`\u26A0\uFE0F [Media Upload] Vercel Blob failed, falling back to local storage:`, blobError);
104
113
  uploadedUrl = await uploadToLocalStorageBuffer(fileBuffer, fileName);
105
114
  console.log(`\u2705 [Media Upload] Uploaded to local storage (fallback): ${uploadedUrl}`);
@@ -178,7 +187,7 @@ export const GET = withRateLimitTier(async (request) => {
178
187
  const maxSizeMB = ((_a = MEDIA_CONFIG) == null ? void 0 : _a.maxSizeMB) ?? 10;
179
188
  return createApiResponse({
180
189
  message: "Media upload endpoint is active",
181
- storage: useVercelBlob ? "Vercel Blob" : "Local Storage",
190
+ storage: useVercelBlob ? "Vercel Blob" : localFallbackAllowed() ? "Local Storage" : "Not configured (set BLOB_READ_WRITE_TOKEN)",
182
191
  uploadPath: "uploads/temp/",
183
192
  supportedTypes: ((_b = MEDIA_CONFIG) == null ? void 0 : _b.allowedMimeTypes) ?? ["image/jpeg", "image/png", "image/gif", "image/webp", "video/mp4", "video/webm"],
184
193
  maxFileSize: `${maxSizeMB}MB`,
@@ -194,3 +203,4 @@ export const GET = withRateLimitTier(async (request) => {
194
203
  );
195
204
  }
196
205
  }, "read");
206
+ export const OPTIONS = corsPreflight;
@@ -1,4 +1,5 @@
1
1
  import { NextRequest } from 'next/server';
2
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
2
3
  /**
3
4
  * GET /api/v1/media-tags
4
5
  *
@@ -16,4 +17,5 @@ export declare const GET: (request: NextRequest) => Promise<import("next/server"
16
17
  * Authentication: Requires valid session or API key with media:write scope
17
18
  */
18
19
  export declare const POST: (request: NextRequest) => Promise<import("next/server").NextResponse>;
20
+ export declare const OPTIONS: typeof corsPreflight;
19
21
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/v1/media-tags/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAQzC;;;;;;GAMG;AACH,eAAO,MAAM,GAAG,uEAwBN,CAAA;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,uEA+BN,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/v1/media-tags/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAMzC,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAGvE;;;;;;GAMG;AACH,eAAO,MAAM,GAAG,uEAwBN,CAAA;AAEV;;;;;;;GAOG;AACH,eAAO,MAAM,IAAI,uEA+BN,CAAA;AAEX,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -3,6 +3,7 @@ import { createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/hel
3
3
  import { API_ERROR_CODES } from "@nextsparkjs/core/lib/api/api-error";
4
4
  import { checkPermission } from "@nextsparkjs/core/lib/permissions/check";
5
5
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
6
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
6
7
  import { MediaService } from "@nextsparkjs/core/lib/services/media.service";
7
8
  export const GET = withRateLimitTier(async (request) => {
8
9
  try {
@@ -47,3 +48,4 @@ export const POST = withRateLimitTier(async (request) => {
47
48
  return createApiError("Failed to create media tag", 500);
48
49
  }
49
50
  }, "write");
51
+ export const OPTIONS = corsPreflight;
@@ -1,4 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
2
3
  export declare const GET: (request: NextRequest, args_0: {
3
4
  params: Promise<{
4
5
  id: string;
@@ -14,4 +15,5 @@ export declare const DELETE: (request: NextRequest, args_0: {
14
15
  id: string;
15
16
  }>;
16
17
  }) => Promise<NextResponse>;
18
+ export declare const OPTIONS: typeof corsPreflight;
17
19
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/post-categories/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAmBvD,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAyBrC,CAAC;AAGX,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAwIpC,CAAC;AAGZ,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAiEpC,CAAC"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/post-categories/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAevE,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAyBrC,CAAC;AAGX,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAwIpC,CAAC;AAGZ,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAiEpC,CAAC;AAEZ,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -3,6 +3,7 @@ import { authenticateRequest, createAuthFailureResponse } from "@nextsparkjs/cor
3
3
  import { query as dbQuery } from "@nextsparkjs/core/lib/db";
4
4
  import * as z from "zod";
5
5
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
6
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
6
7
  const updateCategorySchema = z.object({
7
8
  name: z.string().min(1).max(255).optional(),
8
9
  slug: z.string().min(2).max(100).regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with dashes").optional(),
@@ -201,3 +202,4 @@ export const DELETE = withRateLimitTier(async (request, { params }) => {
201
202
  return NextResponse.json({ success: false, error: "Internal server error" }, { status: 500 });
202
203
  }
203
204
  }, "write");
205
+ export const OPTIONS = corsPreflight;
@@ -1,4 +1,6 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
2
3
  export declare const GET: (request: NextRequest) => Promise<NextResponse>;
3
4
  export declare const POST: (request: NextRequest) => Promise<NextResponse>;
5
+ export declare const OPTIONS: typeof corsPreflight;
4
6
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/v1/post-categories/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA6BvD,eAAO,MAAM,GAAG,iDAkBN,CAAC;AAGX,eAAO,MAAM,IAAI,iDAsEN,CAAC"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/routes/api/v1/post-categories/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAyBvE,eAAO,MAAM,GAAG,iDAkBN,CAAC;AAGX,eAAO,MAAM,IAAI,iDAsEN,CAAC;AAEZ,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -3,6 +3,7 @@ import { authenticateRequest, createAuthFailureResponse } from "@nextsparkjs/cor
3
3
  import { query as dbQuery } from "@nextsparkjs/core/lib/db";
4
4
  import * as z from "zod";
5
5
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
6
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
6
7
  const createCategorySchema = z.object({
7
8
  name: z.string().min(1).max(255),
8
9
  slug: z.string().min(2).max(100).regex(/^[a-z0-9-]+$/, "Slug must be lowercase alphanumeric with dashes").optional(),
@@ -92,3 +93,4 @@ export const POST = withRateLimitTier(async (request) => {
92
93
  return NextResponse.json({ success: false, error: "Internal server error" }, { status: 500 });
93
94
  }
94
95
  }, "write");
96
+ export const OPTIONS = corsPreflight;
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/routes/api/v1/teams/[teamId]/members/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAwBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,GAAG;YACiC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;2BA2HlE,CAAA;AAGV,eAAO,MAAM,IAAI;YACgC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;2BAgMjE,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/routes/api/v1/teams/[teamId]/members/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAwBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,GAAG;YACiC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;2BA2HlE,CAAA;AAGV,eAAO,MAAM,IAAI;YACgC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;2BAkMjE,CAAA"}
@@ -17,7 +17,7 @@ import { MembershipService } from "@nextsparkjs/core/lib/services";
17
17
  import { canInviteToRole } from "@nextsparkjs/core/lib/teams/permissions";
18
18
  import { EmailFactory } from "@nextsparkjs/core/lib/email/factory";
19
19
  import { sendTeamInvitationEmail } from "@nextsparkjs/core/lib/email/send";
20
- import { I18N_CONFIG } from "@nextsparkjs/core/lib/config";
20
+ import { I18N_CONFIG, APP_NAME } from "@nextsparkjs/core/lib/config";
21
21
  import { withBasePath } from "@nextsparkjs/core/lib/base-path";
22
22
  export async function OPTIONS(request) {
23
23
  return handleCorsPreflightRequest(request);
@@ -230,25 +230,27 @@ export const POST = withRateLimitTier(withApiLogging(
230
230
  role: validatedData.role,
231
231
  acceptUrl,
232
232
  expiresIn: "7 days",
233
- appName: process.env.NEXT_PUBLIC_APP_NAME || "Your App"
233
+ appName: process.env.NEXT_PUBLIC_APP_NAME || APP_NAME
234
234
  }, I18N_CONFIG.defaultLocale);
235
235
  await emailProvider.send({
236
236
  to: validatedData.email,
237
237
  subject: emailContent.subject,
238
238
  html: emailContent.html
239
239
  });
240
- console.log("\n" + "\u{1F3AB}".repeat(30));
241
- console.log("\u{1F4E8} TEAM INVITATION CREATED");
242
- console.log("\u{1F3AB}".repeat(30));
243
- console.log(`\u{1F4E7} To: ${validatedData.email}`);
244
- console.log(`\u{1F464} Invited by: ${inviterName}`);
245
- console.log(`\u{1F3E2} Team: ${team.name}`);
246
- console.log(`\u{1F451} Role: ${validatedData.role}`);
247
- console.log(`\u{1F517} Accept URL: ${acceptUrl}`);
248
- console.log("\u{1F3AB}".repeat(30) + "\n");
240
+ if (process.env.NODE_ENV === "development") {
241
+ console.log("\n" + "\u{1F3AB}".repeat(30));
242
+ console.log("\u{1F4E8} TEAM INVITATION CREATED");
243
+ console.log("\u{1F3AB}".repeat(30));
244
+ console.log(`\u{1F4E7} To: ${validatedData.email}`);
245
+ console.log(`\u{1F464} Invited by: ${inviterName}`);
246
+ console.log(`\u{1F3E2} Team: ${team.name}`);
247
+ console.log(`\u{1F451} Role: ${validatedData.role}`);
248
+ console.log(`\u{1F517} Accept URL: ${acceptUrl}`);
249
+ console.log("\u{1F3AB}".repeat(30) + "\n");
250
+ }
249
251
  } catch (emailError) {
250
252
  console.error("Failed to send invitation email:", emailError);
251
- console.log(`\u26A0\uFE0F Email failed but invitation created. Accept URL: ${acceptUrl}`);
253
+ if (process.env.NODE_ENV === "development") console.log(`\u26A0\uFE0F Email failed but invitation created. Accept URL: ${acceptUrl}`);
252
254
  }
253
255
  const response = createApiResponse(invitation, { created: true }, 201);
254
256
  return addCorsHeaders(response, req);
@@ -4,11 +4,13 @@
4
4
  * GET /api/v1/teams/[teamId]/subscription - Get team's active subscription
5
5
  */
6
6
  import { NextRequest, NextResponse } from 'next/server';
7
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
7
8
  interface RouteParams {
8
9
  params: Promise<{
9
10
  teamId: string;
10
11
  }>;
11
12
  }
12
13
  export declare const GET: (request: NextRequest, props: RouteParams) => Promise<NextResponse>;
14
+ export declare const OPTIONS: typeof corsPreflight;
13
15
  export {};
14
16
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/routes/api/v1/teams/[teamId]/subscription/route.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKvD,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACpC;AAED,eAAO,MAAM,GAAG,qEAmCN,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/routes/api/v1/teams/[teamId]/subscription/route.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAGvE,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACpC;AAED,eAAO,MAAM,GAAG,qEAmCN,CAAA;AAEV,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { validateAndAuthenticateRequest, createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/helpers";
3
3
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
4
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
4
5
  import { SubscriptionService, MembershipService } from "@nextsparkjs/core/lib/services";
5
6
  export const GET = withRateLimitTier(async function GET2(request, props) {
6
7
  const { auth, rateLimitResponse, errorResponse } = await validateAndAuthenticateRequest(request, { requiredScope: "billing:read" });
@@ -28,3 +29,4 @@ export const GET = withRateLimitTier(async function GET2(request, props) {
28
29
  return createApiError("Failed to fetch subscription", 500);
29
30
  }
30
31
  }, "read");
32
+ export const OPTIONS = corsPreflight;
@@ -5,6 +5,7 @@
5
5
  * POST /api/v1/teams/[teamId]/usage/[limitSlug] - Track usage
6
6
  */
7
7
  import { NextRequest, NextResponse } from 'next/server';
8
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response';
8
9
  interface RouteParams {
9
10
  params: Promise<{
10
11
  teamId: string;
@@ -13,5 +14,6 @@ interface RouteParams {
13
14
  }
14
15
  export declare const GET: (request: NextRequest, props: RouteParams) => Promise<NextResponse>;
15
16
  export declare const POST: (request: NextRequest, props: RouteParams) => Promise<NextResponse>;
17
+ export declare const OPTIONS: typeof corsPreflight;
16
18
  export {};
17
19
  //# sourceMappingURL=route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAMvD,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,GAAG,qEAgCN,CAAA;AAEV,eAAO,MAAM,IAAI,qEA4CN,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAGvD,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAIvE,UAAU,WAAW;IACnB,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,GAAG,qEAgCN,CAAA;AAEV,eAAO,MAAM,IAAI,qEA4CN,CAAA;AAEX,eAAO,MAAM,OAAO,sBAAgB,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { validateAndAuthenticateRequest, createApiResponse, createApiError } from "@nextsparkjs/core/lib/api/helpers";
3
3
  import { withRateLimitTier } from "@nextsparkjs/core/lib/api/rate-limit";
4
+ import { corsPreflight } from "@nextsparkjs/core/lib/api/cors-response";
4
5
  import { SubscriptionService, UsageService, MembershipService } from "@nextsparkjs/core/lib/services";
5
6
  import { trackUsageSchema } from "@nextsparkjs/core/lib/billing/schema";
6
7
  export const GET = withRateLimitTier(async function GET2(request, props) {
@@ -65,3 +66,4 @@ export const POST = withRateLimitTier(async function POST2(request, props) {
65
66
  return createApiError(errorMessage, 500);
66
67
  }
67
68
  }, "write");
69
+ export const OPTIONS = corsPreflight;
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/teams/switch/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAuBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,IAAI,iDA6EL,CAAA"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/teams/switch/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAuBvD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,IAAI,iDAkFL,CAAA"}
@@ -38,7 +38,10 @@ export const POST = withRateLimitTier(withApiLogging(async (req) => {
38
38
  );
39
39
  return addCorsHeaders(response, req);
40
40
  }
41
- const body = await req.json();
41
+ const body = await req.json().catch(() => void 0);
42
+ if (body === void 0) {
43
+ return addCorsHeaders(createApiError("Request body must be valid JSON", 400, null, "INVALID_JSON"), req);
44
+ }
42
45
  const validatedData = switchTeamSchema.parse(body);
43
46
  try {
44
47
  await TeamService.switchActive(authResult.user.id, validatedData.teamId);
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2BxD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAoDpC,CAAC;AAGZ,eAAO,MAAM,KAAK;YAEM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAqInC,CAAC;AAGb,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAiEnC,CAAC"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/[id]/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA+BxD,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,kCAEjD;AAGD,eAAO,MAAM,GAAG;YAEQ,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAoDpC,CAAC;AAGZ,eAAO,MAAM,KAAK;YAEM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAqInC,CAAC;AAGb,eAAO,MAAM,MAAM;YAEK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;2BAiEnC,CAAC"}
@@ -21,6 +21,7 @@ const updateUserSchema = z.object({
21
21
  role: z.enum(["member", "superadmin"]).optional(),
22
22
  metas: z.record(z.string(), z.any()).optional()
23
23
  });
24
+ const resolveUserId = ({ id }, callerId) => id === "me" ? callerId : id;
24
25
  export async function OPTIONS(request) {
25
26
  return handleCorsPreflightRequest(request);
26
27
  }
@@ -33,7 +34,7 @@ export const GET = withRateLimitTier(withApiLogging(async (req, { params }) => {
33
34
  if (authResult.rateLimitResponse) {
34
35
  return authResult.rateLimitResponse;
35
36
  }
36
- const { id } = await params;
37
+ const id = resolveUserId(await params, authResult.user.id);
37
38
  if (!id || id.trim() === "") {
38
39
  const response2 = createApiError("User ID or email is required", 400, null, "MISSING_IDENTIFIER");
39
40
  return addCorsHeaders(response2, req);
@@ -70,7 +71,7 @@ export const PATCH = withRateLimitTier(withApiLogging(async (req, { params }) =>
70
71
  if (authResult.rateLimitResponse) {
71
72
  return authResult.rateLimitResponse;
72
73
  }
73
- const { id } = await params;
74
+ const id = resolveUserId(await params, authResult.user.id);
74
75
  if (!id || id.trim() === "") {
75
76
  const response2 = createApiError("User ID or email is required", 400, null, "MISSING_IDENTIFIER");
76
77
  return addCorsHeaders(response2, req);
@@ -4,52 +4,67 @@ Manage user profiles and account settings.
4
4
 
5
5
  ## Overview
6
6
 
7
- The Users API allows you to view and update user profile information. Users can update their own profile, while admins can manage other users within their team.
7
+ The Users API allows you to view and update user profile information. Users can read and update their own profile; a superadmin can manage any user.
8
8
 
9
9
  ## Authentication
10
10
 
11
11
  All endpoints require authentication via:
12
12
  - **Session cookie** (for browser-based requests)
13
- - **API Key** header (for server-to-server requests)
13
+ - **API Key** (for server-to-server requests), sent as `x-api-key: <key>` or `Authorization: Bearer <key>`: it needs the `users:read` scope to read and `users:write` to update, and it answers as the key's owner
14
+
15
+ A user can read and update only themselves; a superadmin can manage any user. Anything else answers `403`.
14
16
 
15
17
  ## Endpoints
16
18
 
17
19
  ### Get Current User
18
20
  `GET /api/v1/users/me`
19
21
 
20
- Returns the currently authenticated user's profile.
22
+ Returns the signed-in user, with a session cookie or an API key. It is `GET /api/v1/users/:id` for the caller's own id, so it takes the same `metas` query parameters and answers with the same fields.
23
+
24
+ ```bash
25
+ curl -H "Cookie: <session cookie>" https://yourdomain.com/api/v1/users/me
26
+ curl -H "Authorization: Bearer <api key>" https://yourdomain.com/api/v1/users/me
27
+ curl -H "x-api-key: <api key>" https://yourdomain.com/api/v1/users/me
28
+ ```
21
29
 
22
30
  **Example Response:**
23
31
  ```json
24
32
  {
25
- "id": "user_123",
26
- "name": "John Doe",
27
- "email": "john@example.com",
28
- "image": "/uploads/avatar.png",
29
- "createdAt": "2024-01-15T10:30:00Z",
30
- "teams": [
31
- {
32
- "id": "team_456",
33
- "name": "Acme Corp",
34
- "role": "admin"
35
- }
36
- ]
33
+ "success": true,
34
+ "data": {
35
+ "id": "user_123",
36
+ "email": "john@example.com",
37
+ "name": "John Doe",
38
+ "firstName": "John",
39
+ "lastName": "Doe",
40
+ "image": "/uploads/avatar.png",
41
+ "country": null,
42
+ "timezone": null,
43
+ "language": "en",
44
+ "role": "member",
45
+ "emailVerified": true,
46
+ "createdAt": "2024-01-15T10:30:00Z",
47
+ "updatedAt": "2024-01-15T10:30:00Z"
48
+ }
37
49
  }
38
50
  ```
39
51
 
40
52
  ### Update Current User
41
53
  `PATCH /api/v1/users/me`
42
54
 
43
- Update the current user's profile.
55
+ Update the signed-in user. It is `PATCH /api/v1/users/:id` for the caller's own id, with the same rules: only `firstName`, `lastName`, `language` and `metas` are accepted, and `role` is a superadmin's to change (anyone else gets `403`).
44
56
 
45
57
  **Request Body:**
46
58
  ```json
47
59
  {
48
- "name": "John Smith",
49
- "image": "/uploads/new-avatar.png"
60
+ "firstName": "John",
61
+ "lastName": "Smith",
62
+ "metas": { "preferences": { "theme": "dark" } }
50
63
  }
51
64
  ```
52
65
 
66
+ To store per-user settings (the mobile client's preferences), use the user's metadata: `GET`/`PUT /api/v1/users/:id/meta/:key`.
67
+
53
68
  ### List Team Members
54
69
  `GET /api/v1/users`
55
70
 
@@ -63,7 +78,7 @@ Returns all users in the current team.
63
78
  ### Get User by ID
64
79
  `GET /api/v1/users/[id]`
65
80
 
66
- Returns a specific user's profile (within the same team).
81
+ Returns a specific user's profile. Only that user or a superadmin can read it; `403` otherwise.
67
82
 
68
83
  **Path Parameters:**
69
84
  - `id` (string, required): User ID
@@ -0,0 +1,6 @@
1
+ import type { NextRequest } from 'next/server';
2
+ import { OPTIONS } from '@nextsparkjs/core/routes/api/v1/users/[id]/route';
3
+ export { OPTIONS };
4
+ export declare const GET: (req: NextRequest) => Promise<import("next/server").NextResponse<unknown>>;
5
+ export declare const PATCH: (req: NextRequest) => Promise<import("next/server").NextResponse<unknown>>;
6
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/routes/api/v1/users/me/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAsC,MAAM,kDAAkD,CAAA;AAO9G,OAAO,EAAE,OAAO,EAAE,CAAA;AAClB,eAAO,MAAM,GAAG,GAAI,KAAK,WAAW,yDAAqB,CAAA;AACzD,eAAO,MAAM,KAAK,GAAI,KAAK,WAAW,yDAAuB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { OPTIONS, GET as getUser, PATCH as patchUser } from "@nextsparkjs/core/routes/api/v1/users/[id]/route";
2
+ const me = { params: Promise.resolve({ id: "me" }) };
3
+ export { OPTIONS };
4
+ export const GET = (req) => getUser(req, me);
5
+ export const PATCH = (req) => patchUser(req, me);
@@ -34,13 +34,13 @@ export default defineApiEndpoint({
34
34
  {
35
35
  id: 'update-profile',
36
36
  title: 'Update My Profile',
37
- description: 'Update current user name',
37
+ description: 'Update the current user first name',
38
38
  method: 'PATCH',
39
39
  pathParams: {
40
40
  id: 'me'
41
41
  },
42
42
  payload: {
43
- name: 'Updated Name'
43
+ firstName: 'Updated'
44
44
  },
45
45
  tags: ['write', 'profile']
46
46
  },
@@ -0,0 +1,4 @@
1
+ export default function MainDashboardLayout({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=layout.cc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.cc.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.cc.tsx"],"names":[],"mappings":"AAgBA,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAQtF"}
@@ -0,0 +1,10 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ import { Suspense } from "react";
3
+ import { MainDashboardShell, enforceEntityPermission } from "../../_internal/dashboard-main-shared.js";
4
+ async function EntityPermission({ children }) {
5
+ await enforceEntityPermission();
6
+ return /* @__PURE__ */ jsx(Fragment, { children });
7
+ }
8
+ export default function MainDashboardLayout({ children }) {
9
+ return /* @__PURE__ */ jsx(MainDashboardShell, { children: /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(EntityPermission, { children }) }) });
10
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.tsx"],"names":[],"mappings":"AAsDA,iBAAe,0BAA0B,CAAC,EACxC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,oDAmCA;AAGD,eAAe,0BAA0B,CAAA"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/(main)/layout.tsx"],"names":[],"mappings":"AAcA,iBAAe,0BAA0B,CAAC,EACxC,QAAQ,EACT,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B,oDAIA;AAGD,eAAe,0BAA0B,CAAA"}
@@ -1,50 +1,9 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { headers } from "next/headers";
3
- import { redirect } from "next/navigation";
4
- import { DashboardShell } from "@nextsparkjs/core/components/dashboard/layouts/DashboardShell";
5
- import { serializeEntityConfig } from "@nextsparkjs/core/lib/entities/serialization";
6
- import { setEntityRegistry } from "@nextsparkjs/core/lib/entities/queries";
7
- import { checkPermission } from "@nextsparkjs/core/lib/permissions/check";
8
- import { getDashboardPermissionContext } from "@nextsparkjs/core/lib/auth/request-session";
9
- import { isValidPermission } from "@nextsparkjs/core/lib/permissions/init";
10
- import { ENTITY_REGISTRY, ENTITY_METADATA } from "@nextsparkjs/registries/entity-registry";
11
- setEntityRegistry(ENTITY_REGISTRY, ENTITY_METADATA);
12
- function parseEntityFromPathname(pathname) {
13
- const match = pathname.match(/^\/dashboard\/([^/]+)(?:\/(.*))?$/);
14
- if (!match) return null;
15
- const entity = match[1];
16
- const rest = match[2] || "";
17
- if (rest === "" || rest === "/") return { entity, action: "list" };
18
- if (rest === "create") return { entity, action: "create" };
19
- if (rest.match(/^[^/]+\/edit$/)) return { entity, action: "update" };
20
- if (rest.match(/^[^/]+$/)) return { entity, action: "read" };
21
- return { entity, action: "read" };
22
- }
23
- function isEntityConfig(entity) {
24
- return "slug" in entity;
25
- }
2
+ import { MainDashboardShell, enforceEntityPermission } from "../../_internal/dashboard-main-shared.js";
26
3
  async function DefaultMainDashboardLayout({
27
4
  children
28
5
  }) {
29
- const allEntities = Object.values(ENTITY_REGISTRY).map((entry) => entry.config);
30
- const entities = allEntities.filter(isEntityConfig);
31
- const serializedEntities = entities.map(serializeEntityConfig);
32
- const headersList = await headers();
33
- const pathname = headersList.get("x-pathname") || "";
34
- const { userId, teamId } = await getDashboardPermissionContext();
35
- if (userId && teamId && pathname) {
36
- const parsed = parseEntityFromPathname(pathname);
37
- if (parsed) {
38
- const { entity, action } = parsed;
39
- const permission = `${entity}.${action}`;
40
- if (isValidPermission(`${entity}.list`)) {
41
- const hasPermission = await checkPermission(userId, teamId, permission);
42
- if (!hasPermission) {
43
- redirect(`/dashboard/permission-denied?entity=${entity}&action=${action}`);
44
- }
45
- }
46
- }
47
- }
48
- return /* @__PURE__ */ jsx(DashboardShell, { entities: serializedEntities, children });
6
+ await enforceEntityPermission();
7
+ return /* @__PURE__ */ jsx(MainDashboardShell, { children });
49
8
  }
50
9
  export default DefaultMainDashboardLayout;
@@ -4,6 +4,6 @@ interface PermissionDeniedPageProps {
4
4
  action?: string;
5
5
  }>;
6
6
  }
7
- declare function PermissionDeniedPage({ searchParams }: PermissionDeniedPageProps): Promise<import("react/jsx-runtime").JSX.Element>;
7
+ declare function PermissionDeniedPage({ searchParams }: PermissionDeniedPageProps): import("react/jsx-runtime").JSX.Element;
8
8
  export default PermissionDeniedPage;
9
9
  //# sourceMappingURL=page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/permission-denied/page.tsx"],"names":[],"mappings":"AAQA,UAAU,yBAAyB;IACjC,YAAY,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAED,iBAAe,oBAAoB,CAAC,EAClC,YAAY,EACb,EAAE,yBAAyB,oDAW3B;AAED,eAAe,oBAAoB,CAAA"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../src/routes/dashboard/permission-denied/page.tsx"],"names":[],"mappings":"AASA,UAAU,yBAAyB;IACjC,YAAY,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAC,CAAA;CACH;AAkBD,iBAAS,oBAAoB,CAAC,EAAE,YAAY,EAAE,EAAE,yBAAyB,2CAMxE;AAED,eAAe,oBAAoB,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
+ import { Suspense } from "react";
2
3
  import { NoPermission } from "@nextsparkjs/core/components/permissions/NoPermission";
3
- async function PermissionDeniedPage({
4
+ async function DeniedMessage({
4
5
  searchParams
5
6
  }) {
6
7
  const { entity, action } = await searchParams;
@@ -14,4 +15,7 @@ async function PermissionDeniedPage({
14
15
  }
15
16
  );
16
17
  }
18
+ function PermissionDeniedPage({ searchParams }) {
19
+ return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(DeniedMessage, { searchParams }) });
20
+ }
17
21
  export default PermissionDeniedPage;
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../src/routes/dashboard/settings/password/page.tsx"],"names":[],"mappings":"AAwBA,iBAAS,kBAAkB,4CAmR1B;AAID,eAAe,kBAAkB,CAAA"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../src/routes/dashboard/settings/password/page.tsx"],"names":[],"mappings":"AAwBA,iBAAS,kBAAkB,4CAsR1B;AAID,eAAe,kBAAkB,CAAA"}