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

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 (338) 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/dashboard/block-editor/block-picker.d.ts.map +1 -1
  8. package/dist/components/dashboard/block-editor/block-picker.js +2 -1
  9. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  10. package/dist/components/dashboard/block-editor/builder-editor-view.js +39 -23
  11. package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
  12. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
  13. package/dist/components/dashboard/layouts/AuthGuard.d.ts.map +1 -1
  14. package/dist/components/dashboard/layouts/AuthGuard.js +3 -4
  15. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.d.ts.map +1 -1
  16. package/dist/components/dashboard/layouts/AuthenticatedDashboardLayout.js +9 -10
  17. package/dist/components/dashboard/layouts/DashboardAuthLayout.d.ts.map +1 -1
  18. package/dist/components/dashboard/layouts/DashboardAuthLayout.js +3 -4
  19. package/dist/components/dashboard/layouts/DashboardAuthSkeleton.d.ts +2 -2
  20. package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
  21. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -2
  22. package/dist/components/entities/wrappers/EntityFormWrapper.d.ts.map +1 -1
  23. package/dist/components/entities/wrappers/EntityFormWrapper.js +5 -2
  24. package/dist/components/entities/wrappers/EntityListWrapper.d.ts.map +1 -1
  25. package/dist/components/entities/wrappers/EntityListWrapper.js +5 -2
  26. package/dist/components/ui/relation-display.d.ts.map +1 -1
  27. package/dist/components/ui/relation-display.js +2 -1
  28. package/dist/components/ui/user-display.d.ts.map +1 -1
  29. package/dist/components/ui/user-display.js +2 -1
  30. package/dist/emails/otp-verification.d.ts.map +1 -1
  31. package/dist/emails/otp-verification.js +5 -3
  32. package/dist/emails/reset-password.d.ts.map +1 -1
  33. package/dist/emails/reset-password.js +5 -3
  34. package/dist/emails/team-invitation.d.ts.map +1 -1
  35. package/dist/emails/team-invitation.js +3 -2
  36. package/dist/emails/verify-email.d.ts.map +1 -1
  37. package/dist/emails/verify-email.js +5 -3
  38. package/dist/hooks/useAuth.d.ts.map +1 -1
  39. package/dist/hooks/useAuth.js +21 -4
  40. package/dist/hooks/usePatternUsages.d.ts.map +1 -1
  41. package/dist/hooks/usePatternUsages.js +3 -2
  42. package/dist/lib/api/auth.d.ts +2 -0
  43. package/dist/lib/api/auth.d.ts.map +1 -1
  44. package/dist/lib/api/auth.js +10 -10
  45. package/dist/lib/api/client-headers.d.ts +11 -0
  46. package/dist/lib/api/client-headers.d.ts.map +1 -0
  47. package/dist/lib/api/client-headers.js +12 -0
  48. package/dist/lib/api/client-ip.d.ts +59 -0
  49. package/dist/lib/api/client-ip.d.ts.map +1 -0
  50. package/dist/lib/api/client-ip.js +91 -0
  51. package/dist/lib/api/cors-response.d.ts +54 -0
  52. package/dist/lib/api/cors-response.d.ts.map +1 -0
  53. package/dist/lib/api/cors-response.js +88 -0
  54. package/dist/lib/api/entities.d.ts.map +1 -1
  55. package/dist/lib/api/entities.js +4 -3
  56. package/dist/lib/api/entity/audit-log.d.ts.map +1 -1
  57. package/dist/lib/api/entity/audit-log.js +2 -1
  58. package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
  59. package/dist/lib/api/entity/generic-handler.js +23 -5
  60. package/dist/lib/api/helpers.d.ts +8 -2
  61. package/dist/lib/api/helpers.d.ts.map +1 -1
  62. package/dist/lib/api/helpers.js +27 -81
  63. package/dist/lib/api/keys.d.ts +6 -0
  64. package/dist/lib/api/keys.d.ts.map +1 -1
  65. package/dist/lib/api/keys.js +7 -1
  66. package/dist/lib/api/rate-limit.d.ts +4 -0
  67. package/dist/lib/api/rate-limit.d.ts.map +1 -1
  68. package/dist/lib/api/rate-limit.js +16 -40
  69. package/dist/lib/api/request-origin.d.ts +16 -7
  70. package/dist/lib/api/request-origin.d.ts.map +1 -1
  71. package/dist/lib/api/request-origin.js +43 -20
  72. package/dist/lib/auth/load-login-page.d.ts +10 -0
  73. package/dist/lib/auth/load-login-page.d.ts.map +1 -0
  74. package/dist/lib/auth/load-login-page.js +7 -0
  75. package/dist/lib/auth/runtime-readiness.d.ts.map +1 -1
  76. package/dist/lib/auth/runtime-readiness.js +2 -0
  77. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts +1 -8
  78. package/dist/lib/auth/security-notifications/device-fingerprint.d.ts.map +1 -1
  79. package/dist/lib/auth/security-notifications/device-fingerprint.js +2 -12
  80. package/dist/lib/auth-email-callbacks.js +3 -3
  81. package/dist/lib/auth.d.ts.map +1 -1
  82. package/dist/lib/auth.js +7 -2
  83. package/dist/lib/config/config-client.d.ts.map +1 -1
  84. package/dist/lib/config/config-client.js +1 -1
  85. package/dist/lib/config/config-sync.d.ts.map +1 -1
  86. package/dist/lib/config/config-sync.js +1 -1
  87. package/dist/lib/config/public-config-client.d.ts +1 -0
  88. package/dist/lib/config/public-config-client.d.ts.map +1 -1
  89. package/dist/lib/config/public-config-client.js +3 -1
  90. package/dist/lib/config/types.d.ts +2 -0
  91. package/dist/lib/config/types.d.ts.map +1 -1
  92. package/dist/lib/constants/reserved-slugs.d.ts +17 -8
  93. package/dist/lib/constants/reserved-slugs.d.ts.map +1 -1
  94. package/dist/lib/constants/reserved-slugs.js +16 -52
  95. package/dist/lib/db.d.ts.map +1 -1
  96. package/dist/lib/db.js +9 -3
  97. package/dist/lib/entities/external-api-generator.d.ts.map +1 -1
  98. package/dist/lib/entities/external-api-generator.js +2 -4
  99. package/dist/lib/entities/public-slug.d.ts +46 -0
  100. package/dist/lib/entities/public-slug.d.ts.map +1 -0
  101. package/dist/lib/entities/public-slug.js +39 -0
  102. package/dist/routes/(auth)/signup/page.cc.d.ts +3 -8
  103. package/dist/routes/(auth)/signup/page.cc.d.ts.map +1 -1
  104. package/dist/routes/(auth)/signup/page.cc.js +7 -1
  105. package/dist/routes/(auth)/verify-email/page.d.ts.map +1 -1
  106. package/dist/routes/(auth)/verify-email/page.js +2 -1
  107. package/dist/routes/(public)/page.cc.d.ts +3 -0
  108. package/dist/routes/(public)/page.cc.d.ts.map +1 -0
  109. package/dist/routes/(public)/page.cc.js +3 -0
  110. package/dist/routes/_internal/area-access.cc.d.ts +21 -0
  111. package/dist/routes/_internal/area-access.cc.d.ts.map +1 -0
  112. package/dist/routes/_internal/area-access.cc.js +19 -0
  113. package/dist/routes/_internal/auth-layout.d.ts.map +1 -1
  114. package/dist/routes/_internal/auth-layout.js +3 -2
  115. package/dist/routes/_internal/dashboard-main-shared.d.ts +7 -0
  116. package/dist/routes/_internal/dashboard-main-shared.d.ts.map +1 -0
  117. package/dist/routes/_internal/dashboard-main-shared.js +49 -0
  118. package/dist/routes/_internal/default-auth-layout.d.ts.map +1 -1
  119. package/dist/routes/_internal/default-auth-layout.js +3 -2
  120. package/dist/routes/_internal/devtools-layout.cc.d.ts +3 -2
  121. package/dist/routes/_internal/devtools-layout.cc.d.ts.map +1 -1
  122. package/dist/routes/_internal/devtools-layout.cc.js +1 -1
  123. package/dist/routes/_internal/devtools-layout.d.ts +7 -2
  124. package/dist/routes/_internal/devtools-layout.d.ts.map +1 -1
  125. package/dist/routes/_internal/devtools-layout.js +4 -4
  126. package/dist/routes/_internal/entity-detail-route.cc.d.ts +8 -0
  127. package/dist/routes/_internal/entity-detail-route.cc.d.ts.map +1 -0
  128. package/dist/routes/_internal/entity-detail-route.cc.js +5 -0
  129. package/dist/routes/_internal/entity-edit-route.cc.d.ts +8 -0
  130. package/dist/routes/_internal/entity-edit-route.cc.d.ts.map +1 -0
  131. package/dist/routes/_internal/entity-edit-route.cc.js +5 -0
  132. package/dist/routes/_internal/public-archive-route.d.ts +1 -1
  133. package/dist/routes/_internal/public-archive-route.d.ts.map +1 -1
  134. package/dist/routes/_internal/public-archive-route.js +8 -3
  135. package/dist/routes/_internal/public-item-route.cc.d.ts +5 -1
  136. package/dist/routes/_internal/public-item-route.cc.d.ts.map +1 -1
  137. package/dist/routes/_internal/public-item-route.cc.js +2 -1
  138. package/dist/routes/_internal/public-item-route.d.ts +7 -0
  139. package/dist/routes/_internal/public-item-route.d.ts.map +1 -1
  140. package/dist/routes/_internal/public-item-route.js +6 -1
  141. package/dist/routes/_internal/superadmin-layout.cc.d.ts +2 -1
  142. package/dist/routes/_internal/superadmin-layout.cc.d.ts.map +1 -1
  143. package/dist/routes/_internal/superadmin-layout.cc.js +1 -1
  144. package/dist/routes/_internal/superadmin-layout.d.ts +7 -2
  145. package/dist/routes/_internal/superadmin-layout.d.ts.map +1 -1
  146. package/dist/routes/_internal/superadmin-layout.js +6 -6
  147. package/dist/routes/_internal/suspended-route.d.ts +16 -0
  148. package/dist/routes/_internal/suspended-route.d.ts.map +1 -0
  149. package/dist/routes/_internal/suspended-route.js +7 -0
  150. package/dist/routes/api/auth/[...all]/route.d.ts.map +1 -1
  151. package/dist/routes/api/auth/[...all]/route.js +4 -12
  152. package/dist/routes/api/csp-report/route.d.ts.map +1 -1
  153. package/dist/routes/api/csp-report/route.js +2 -13
  154. package/dist/routes/api/devtools/config/entities/route.d.ts +2 -0
  155. package/dist/routes/api/devtools/config/entities/route.d.ts.map +1 -1
  156. package/dist/routes/api/devtools/config/entities/route.js +2 -0
  157. package/dist/routes/api/devtools/config/theme/route.d.ts +2 -0
  158. package/dist/routes/api/devtools/config/theme/route.d.ts.map +1 -1
  159. package/dist/routes/api/devtools/config/theme/route.js +2 -0
  160. package/dist/routes/api/devtools/tests/[...path]/route.d.ts +2 -0
  161. package/dist/routes/api/devtools/tests/[...path]/route.d.ts.map +1 -1
  162. package/dist/routes/api/devtools/tests/[...path]/route.js +2 -0
  163. package/dist/routes/api/devtools/tests/route.d.ts +2 -0
  164. package/dist/routes/api/devtools/tests/route.d.ts.map +1 -1
  165. package/dist/routes/api/devtools/tests/route.js +2 -0
  166. package/dist/routes/api/health/route.d.ts +2 -0
  167. package/dist/routes/api/health/route.d.ts.map +1 -1
  168. package/dist/routes/api/health/route.js +2 -0
  169. package/dist/routes/api/internal/user-metadata/route.d.ts +2 -0
  170. package/dist/routes/api/internal/user-metadata/route.d.ts.map +1 -1
  171. package/dist/routes/api/internal/user-metadata/route.js +2 -0
  172. package/dist/routes/api/mcp/route.d.ts +2 -0
  173. package/dist/routes/api/mcp/route.d.ts.map +1 -1
  174. package/dist/routes/api/mcp/route.js +2 -0
  175. package/dist/routes/api/superadmin/subscriptions/route.d.ts +2 -0
  176. package/dist/routes/api/superadmin/subscriptions/route.d.ts.map +1 -1
  177. package/dist/routes/api/superadmin/subscriptions/route.js +2 -0
  178. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts +2 -0
  179. package/dist/routes/api/superadmin/teams/[teamId]/route.d.ts.map +1 -1
  180. package/dist/routes/api/superadmin/teams/[teamId]/route.js +2 -0
  181. package/dist/routes/api/superadmin/teams/route.d.ts +2 -0
  182. package/dist/routes/api/superadmin/teams/route.d.ts.map +1 -1
  183. package/dist/routes/api/superadmin/teams/route.js +2 -0
  184. package/dist/routes/api/superadmin/users/[userId]/route.d.ts +2 -0
  185. package/dist/routes/api/superadmin/users/[userId]/route.d.ts.map +1 -1
  186. package/dist/routes/api/superadmin/users/[userId]/route.js +2 -0
  187. package/dist/routes/api/superadmin/users/route.d.ts +2 -0
  188. package/dist/routes/api/superadmin/users/route.d.ts.map +1 -1
  189. package/dist/routes/api/superadmin/users/route.js +2 -0
  190. package/dist/routes/api/user/delete-account/route.d.ts +2 -0
  191. package/dist/routes/api/user/delete-account/route.d.ts.map +1 -1
  192. package/dist/routes/api/user/delete-account/route.js +2 -0
  193. package/dist/routes/api/user/plan-flags/route.d.ts +2 -0
  194. package/dist/routes/api/user/plan-flags/route.d.ts.map +1 -1
  195. package/dist/routes/api/user/plan-flags/route.js +2 -0
  196. package/dist/routes/api/user/profile/route.d.ts +2 -0
  197. package/dist/routes/api/user/profile/route.d.ts.map +1 -1
  198. package/dist/routes/api/user/profile/route.js +4 -3
  199. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts +2 -0
  200. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.d.ts.map +1 -1
  201. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/[childId]/route.js +2 -0
  202. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts +2 -0
  203. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.d.ts.map +1 -1
  204. package/dist/routes/api/v1/[entity]/[id]/child/[childType]/route.js +2 -0
  205. package/dist/routes/api/v1/billing/cancel/route.d.ts +2 -0
  206. package/dist/routes/api/v1/billing/cancel/route.d.ts.map +1 -1
  207. package/dist/routes/api/v1/billing/cancel/route.js +2 -0
  208. package/dist/routes/api/v1/billing/change-plan/route.d.ts +2 -0
  209. package/dist/routes/api/v1/billing/change-plan/route.d.ts.map +1 -1
  210. package/dist/routes/api/v1/billing/change-plan/route.js +2 -0
  211. package/dist/routes/api/v1/billing/check-action/route.d.ts +2 -0
  212. package/dist/routes/api/v1/billing/check-action/route.d.ts.map +1 -1
  213. package/dist/routes/api/v1/billing/check-action/route.js +2 -0
  214. package/dist/routes/api/v1/billing/checkout/route.d.ts +2 -0
  215. package/dist/routes/api/v1/billing/checkout/route.d.ts.map +1 -1
  216. package/dist/routes/api/v1/billing/checkout/route.js +2 -0
  217. package/dist/routes/api/v1/billing/plans/route.d.ts +2 -0
  218. package/dist/routes/api/v1/billing/plans/route.d.ts.map +1 -1
  219. package/dist/routes/api/v1/billing/plans/route.js +2 -0
  220. package/dist/routes/api/v1/billing/portal/route.d.ts +2 -0
  221. package/dist/routes/api/v1/billing/portal/route.d.ts.map +1 -1
  222. package/dist/routes/api/v1/billing/portal/route.js +2 -0
  223. package/dist/routes/api/v1/blocks/[slug]/route.d.ts +2 -0
  224. package/dist/routes/api/v1/blocks/[slug]/route.d.ts.map +1 -1
  225. package/dist/routes/api/v1/blocks/[slug]/route.js +2 -0
  226. package/dist/routes/api/v1/blocks/route.d.ts +2 -0
  227. package/dist/routes/api/v1/blocks/route.d.ts.map +1 -1
  228. package/dist/routes/api/v1/blocks/route.js +2 -0
  229. package/dist/routes/api/v1/blocks/validate/route.d.ts +2 -0
  230. package/dist/routes/api/v1/blocks/validate/route.d.ts.map +1 -1
  231. package/dist/routes/api/v1/blocks/validate/route.js +2 -0
  232. package/dist/routes/api/v1/devtools/blocks/route.d.ts +2 -1
  233. package/dist/routes/api/v1/devtools/blocks/route.d.ts.map +1 -1
  234. package/dist/routes/api/v1/devtools/blocks/route.js +2 -9
  235. package/dist/routes/api/v1/devtools/docs/route.d.ts +2 -0
  236. package/dist/routes/api/v1/devtools/docs/route.d.ts.map +1 -1
  237. package/dist/routes/api/v1/devtools/docs/route.js +2 -0
  238. package/dist/routes/api/v1/devtools/features/route.d.ts +2 -1
  239. package/dist/routes/api/v1/devtools/features/route.d.ts.map +1 -1
  240. package/dist/routes/api/v1/devtools/features/route.js +2 -9
  241. package/dist/routes/api/v1/devtools/flows/route.d.ts +2 -1
  242. package/dist/routes/api/v1/devtools/flows/route.d.ts.map +1 -1
  243. package/dist/routes/api/v1/devtools/flows/route.js +2 -9
  244. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts +2 -1
  245. package/dist/routes/api/v1/devtools/scheduled-actions/route.d.ts.map +1 -1
  246. package/dist/routes/api/v1/devtools/scheduled-actions/route.js +2 -9
  247. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts +2 -1
  248. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.d.ts.map +1 -1
  249. package/dist/routes/api/v1/devtools/scheduled-actions/run/route.js +2 -9
  250. package/dist/routes/api/v1/devtools/testing/route.d.ts +2 -1
  251. package/dist/routes/api/v1/devtools/testing/route.d.ts.map +1 -1
  252. package/dist/routes/api/v1/devtools/testing/route.js +2 -9
  253. package/dist/routes/api/v1/media/[id]/route.d.ts +2 -0
  254. package/dist/routes/api/v1/media/[id]/route.d.ts.map +1 -1
  255. package/dist/routes/api/v1/media/[id]/route.js +2 -0
  256. package/dist/routes/api/v1/media/[id]/tags/route.d.ts +2 -0
  257. package/dist/routes/api/v1/media/[id]/tags/route.d.ts.map +1 -1
  258. package/dist/routes/api/v1/media/[id]/tags/route.js +2 -0
  259. package/dist/routes/api/v1/media/check-duplicates/route.d.ts +2 -0
  260. package/dist/routes/api/v1/media/check-duplicates/route.d.ts.map +1 -1
  261. package/dist/routes/api/v1/media/check-duplicates/route.js +2 -0
  262. package/dist/routes/api/v1/media/route.d.ts +2 -0
  263. package/dist/routes/api/v1/media/route.d.ts.map +1 -1
  264. package/dist/routes/api/v1/media/route.js +2 -0
  265. package/dist/routes/api/v1/media/upload/route.d.ts +2 -0
  266. package/dist/routes/api/v1/media/upload/route.d.ts.map +1 -1
  267. package/dist/routes/api/v1/media/upload/route.js +2 -0
  268. package/dist/routes/api/v1/media-tags/route.d.ts +2 -0
  269. package/dist/routes/api/v1/media-tags/route.d.ts.map +1 -1
  270. package/dist/routes/api/v1/media-tags/route.js +2 -0
  271. package/dist/routes/api/v1/post-categories/[id]/route.d.ts +2 -0
  272. package/dist/routes/api/v1/post-categories/[id]/route.d.ts.map +1 -1
  273. package/dist/routes/api/v1/post-categories/[id]/route.js +2 -0
  274. package/dist/routes/api/v1/post-categories/route.d.ts +2 -0
  275. package/dist/routes/api/v1/post-categories/route.d.ts.map +1 -1
  276. package/dist/routes/api/v1/post-categories/route.js +2 -0
  277. package/dist/routes/api/v1/teams/[teamId]/members/route.js +2 -2
  278. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts +2 -0
  279. package/dist/routes/api/v1/teams/[teamId]/subscription/route.d.ts.map +1 -1
  280. package/dist/routes/api/v1/teams/[teamId]/subscription/route.js +2 -0
  281. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts +2 -0
  282. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.d.ts.map +1 -1
  283. package/dist/routes/api/v1/teams/[teamId]/usage/[limitSlug]/route.js +2 -0
  284. package/dist/routes/api/v1/users/[id]/route.d.ts.map +1 -1
  285. package/dist/routes/api/v1/users/[id]/route.js +3 -2
  286. package/dist/routes/api/v1/users/docs.md +34 -19
  287. package/dist/routes/api/v1/users/me/route.d.ts +6 -0
  288. package/dist/routes/api/v1/users/me/route.d.ts.map +1 -0
  289. package/dist/routes/api/v1/users/me/route.js +5 -0
  290. package/dist/routes/api/v1/users/presets.ts +2 -2
  291. package/dist/routes/dashboard/(main)/layout.cc.d.ts +4 -0
  292. package/dist/routes/dashboard/(main)/layout.cc.d.ts.map +1 -0
  293. package/dist/routes/dashboard/(main)/layout.cc.js +10 -0
  294. package/dist/routes/dashboard/(main)/layout.d.ts.map +1 -1
  295. package/dist/routes/dashboard/(main)/layout.js +3 -44
  296. package/dist/routes/dashboard/permission-denied/page.d.ts +1 -1
  297. package/dist/routes/dashboard/permission-denied/page.d.ts.map +1 -1
  298. package/dist/routes/dashboard/permission-denied/page.js +5 -1
  299. package/dist/routes/devtools/layout.cc.d.ts.map +1 -1
  300. package/dist/routes/devtools/layout.cc.js +5 -1
  301. package/dist/routes/manifest.json +10 -0
  302. package/dist/routes/robots.d.ts +10 -0
  303. package/dist/routes/robots.d.ts.map +1 -0
  304. package/dist/routes/robots.js +10 -0
  305. package/dist/routes/superadmin/layout.cc.d.ts.map +1 -1
  306. package/dist/routes/superadmin/layout.cc.js +5 -1
  307. package/dist/routes/variants.json +12 -2
  308. package/dist/templates/next.config.mjs +2 -29
  309. package/dist/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  310. package/dist/templates/projects/blog/api/authors/route.ts +3 -0
  311. package/dist/templates/projects/blog/api/posts/public/route.ts +3 -0
  312. package/dist/templates/proxy.ts +12 -1
  313. package/dist/templates/public/favicon.ico +0 -0
  314. package/package.json +2 -2
  315. package/scripts/build/registry/__tests__/api-docs-colocated.test.mjs +3 -0
  316. package/scripts/build/registry/__tests__/billing-registry.test.mjs +50 -1
  317. package/scripts/build/registry/__tests__/block-registry.test.mjs +3 -0
  318. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +3 -0
  319. package/scripts/build/registry/__tests__/quiet-console.mjs +17 -0
  320. package/scripts/build/registry/__tests__/safe-fs.test.mjs +3 -0
  321. package/scripts/build/registry/__tests__/team-roles.test.mjs +3 -0
  322. package/scripts/build/registry/discovery/permissions.test.mjs +3 -0
  323. package/scripts/build/registry/discovery/plugin-capabilities.mjs +2 -2
  324. package/scripts/build/registry/generators/billing-registry.mjs +7 -3
  325. package/scripts/build/registry/host/README.md +25 -1
  326. package/scripts/build/registry/host/__tests__/host-area-access.test.mjs +32 -0
  327. package/scripts/build/registry/host/__tests__/host-entities.test.mjs +32 -1
  328. package/scripts/build/registry/host/__tests__/host-plan.test.mjs +12 -2
  329. package/scripts/build/registry/host/entity-routes.mjs +9 -3
  330. package/scripts/build/registry/host/static-imports.mjs +4 -0
  331. package/scripts/build/routes-manifest.mjs +13 -1
  332. package/scripts/db/ssl-config.mjs +12 -1
  333. package/templates/next.config.mjs +2 -29
  334. package/templates/projects/blog/api/authors/[username]/route.ts +3 -0
  335. package/templates/projects/blog/api/authors/route.ts +3 -0
  336. package/templates/projects/blog/api/posts/public/route.ts +3 -0
  337. package/templates/proxy.ts +12 -1
  338. package/templates/public/favicon.ico +0 -0
@@ -15,7 +15,7 @@ import { dirname, join } from 'node:path'
15
15
  import { ENTITY_DIAGNOSTICS, ENTITY_MODULES, entityConfigFile, planEntityRoutes, readAllEntityFacts, readEntityFacts, routableEntities } from '../entity-routes.mjs'
16
16
  import { PLAN_DIAGNOSTICS, PLAN_NOTICES, planHost, urlConflicts } from '../plan.mjs'
17
17
  import { renderHost } from '../render.mjs'
18
- import { validateGeneratedModule } from '../static-imports.mjs'
18
+ import { CORE_COMPOSITION_WRAPPERS, validateGeneratedModule } from '../static-imports.mjs'
19
19
  import { loadTypeScriptFor } from '../../shared/typescript-compiler.mjs'
20
20
 
21
21
  const CORE_ROOT = join(import.meta.dirname, '../../../../..')
@@ -29,6 +29,8 @@ const CORE_MODULES = {
29
29
  [ENTITY_MODULES.detail]: ['core/entity-detail-route.tsx', factories('createEntityDetailRoute')],
30
30
  [ENTITY_MODULES.create]: ['core/entity-create-route.tsx', factories('createEntityCreateRoute')],
31
31
  [ENTITY_MODULES.edit]: ['core/entity-edit-route.tsx', factories('createEntityEditRoute')],
32
+ [ENTITY_MODULES.detailCc]: ['core/entity-detail-route.cc.tsx', factories('createEntityDetailRoute')],
33
+ [ENTITY_MODULES.editCc]: ['core/entity-edit-route.cc.tsx', factories('createEntityEditRoute')],
32
34
  [ENTITY_MODULES.publicItem]: ['core/public-item-route.tsx', factories('createPublicItemRoute', 'createPublicItemMetadata')],
33
35
  [ENTITY_MODULES.publicItemCc]: ['core/public-item-route.cc.tsx', factories('createPublicItemRoute', 'createPublicItemMetadata')],
34
36
  [ENTITY_MODULES.publicArchive]: ['core/public-archive-route.tsx', factories('createPublicArchiveRoute', 'createPublicArchiveMetadata')],
@@ -690,6 +692,35 @@ test('a host that builds in Cache Components mode only imports the cached item s
690
692
  }
691
693
  })
692
694
 
695
+ test('a Cache Components host writes the detail and edit pages of an entity from the modules that put them behind Suspense (they await `params`)', async () => {
696
+ const w = world()
697
+ try {
698
+ const args = [w, [entity('tasks', 'taskEntityConfig')], { tasks: await factsOf("slug: 'tasks', enabled: true, ui: { dashboard: { showInMenu: true } }") }]
699
+ const moduleOf = async (target, factory, options) => at(await render((await plan(...args, options)).routes), target).match(new RegExp(`import \\{ ${factory} \\} from "([^"]+)"`))[1]
700
+ assert.equal(ENTITY_MODULES.detailCc, `${ENTITY_MODULES.detail}.cc`)
701
+ assert.equal(ENTITY_MODULES.editCc, `${ENTITY_MODULES.edit}.cc`)
702
+ const detail = options => moduleOf('dashboard/(main)/tasks/[id]/page.tsx', 'createEntityDetailRoute', options)
703
+ const edit = options => moduleOf('dashboard/(main)/tasks/[id]/edit/page.tsx', 'createEntityEditRoute', options)
704
+ assert.equal(await detail({ cacheComponents: true }), ENTITY_MODULES.detailCc)
705
+ assert.equal(await edit({ cacheComponents: true }), ENTITY_MODULES.editCc)
706
+ // An ISR host keeps the routes that redirect and answer notFound() before anything is sent; so does one that builds both, or does not know
707
+ for (const options of [{ cacheComponents: false }, {}, { cacheComponents: true, modes: ['isr', 'cc'] }]) {
708
+ assert.equal(await detail(options), ENTITY_MODULES.detail)
709
+ assert.equal(await edit(options), ENTITY_MODULES.edit)
710
+ }
711
+ } finally {
712
+ w.cleanup()
713
+ }
714
+ })
715
+
716
+ test('every factory module the entity routes import is a known composition module, with the factories it exports (a real host fails facade validation otherwise)', () => {
717
+ const FACTORY_MODULES = ['layout', 'list', 'detail', 'create', 'edit', 'detailCc', 'editCc', 'publicItem', 'publicItemCc', 'publicArchive']
718
+ for (const name of FACTORY_MODULES) {
719
+ const wrappers = CORE_COMPOSITION_WRAPPERS[ENTITY_MODULES[name]]
720
+ assert.ok(Array.isArray(wrappers) && wrappers.length > 0, `${name}: ${ENTITY_MODULES[name]} is missing from CORE_COMPOSITION_WRAPPERS`)
721
+ }
722
+ })
723
+
693
724
  // ---------------------------------------------------------------------------
694
725
  // "The template replaces": project templates at an entity's dashboard URL in another route group
695
726
  // ---------------------------------------------------------------------------
@@ -53,6 +53,16 @@ test('core < plugin < project: a higher layer replaces a lower one at the same r
53
53
  }
54
54
  })
55
55
 
56
+ test('a project robots.ts replaces the robots route core ships (#214)', () => {
57
+ const { root, cleanup } = project({ 'templates/robots.ts': 'export default function robots() { return { rules: { userAgent: "*", disallow: "/" } } }\n' })
58
+ try {
59
+ const routes = resolveHostPlan({ coreRoutes: [core('robots.ts', 'robots')], plugins: [], project: { root } })
60
+ assert.deepEqual(summary(routes), ['robots.ts <- project:@/templates/robots (overrides core route @nextsparkjs/core/routes/robots)'])
61
+ } finally {
62
+ cleanup()
63
+ }
64
+ })
65
+
56
66
  test('the extension does not decide the slot: templates/about/page.ts replaces core about/page.tsx', () => {
57
67
  const { root, cleanup } = project({ 'templates/about/page.ts': PAGE })
58
68
  try {
@@ -330,8 +340,8 @@ test('core\'s routes carry their protection level, so a composed layout can be t
330
340
  assert.equal(withCc.routes.find(route => route.target === 'layout.tsx').compose.specifier, '@nextsparkjs/core/routes/_internal/root-layout.ppr')
331
341
  assert.equal(withCc.routes.find(route => route.target === '(auth)/login/page.tsx').specifier, '@nextsparkjs/core/routes/(auth)/login/page.cc')
332
342
  assert.deepEqual(withCc.variantsApplied.sort(), [
333
- '(auth)/layout.tsx', '(auth)/login/page.tsx', '(auth)/signup/page.tsx', '(public)/docs/[section]/[page]/page.tsx', '(public)/layout.tsx',
334
- 'dashboard/layout.tsx', 'devtools/layout.tsx', 'layout.tsx', 'superadmin/docs/[section]/[page]/page.tsx', 'superadmin/layout.tsx',
343
+ '(auth)/layout.tsx', '(auth)/login/page.tsx', '(auth)/signup/page.tsx', '(public)/docs/[section]/[page]/page.tsx', '(public)/layout.tsx', '(public)/page.tsx',
344
+ 'dashboard/(main)/layout.tsx', 'dashboard/layout.tsx', 'devtools/layout.tsx', 'layout.tsx', 'superadmin/docs/[section]/[page]/page.tsx', 'superadmin/layout.tsx',
335
345
  ])
336
346
  // The layouts that load messages keep their wrapper (from the Cache Components module) and their protection level
337
347
  const ccLevel = target => withCc.routes.find(route => route.target === target)
@@ -54,6 +54,9 @@ export const ENTITY_MODULES = Object.freeze({
54
54
  detail: `${CORE_ROUTES_SPECIFIER}_internal/entity-detail-route`,
55
55
  create: `${CORE_ROUTES_SPECIFIER}_internal/entity-create-route`,
56
56
  edit: `${CORE_ROUTES_SPECIFIER}_internal/entity-edit-route`,
57
+ // The detail and edit pages of a host with `cacheComponents` on: the same routes behind a Suspense boundary (they await `params`).
58
+ detailCc: `${CORE_ROUTES_SPECIFIER}_internal/entity-detail-route.cc`,
59
+ editCc: `${CORE_ROUTES_SPECIFIER}_internal/entity-edit-route.cc`,
57
60
  publicItem: `${CORE_ROUTES_SPECIFIER}_internal/public-item-route`,
58
61
  // The item pages of a host with `cacheComponents` on: same factories, `'use cache'` reads instead of `revalidate`.
59
62
  publicItemCc: `${CORE_ROUTES_SPECIFIER}_internal/public-item-route.cc`,
@@ -207,7 +210,10 @@ export function planEntityRoutes({ entities, facts, coreRoutes, resolveFile, cac
207
210
  const revalidates = cacheComponents !== true && !modes.includes('cc')
208
211
  // A host that builds in Cache Components mode only gets the cached item source; one that builds both (the
209
212
  // conformance fixture) or does not know keeps the module that works in either.
210
- const publicItemModule = cacheComponents === true && modes.length === 0 && modules.publicItemCc ? modules.publicItemCc : modules.publicItem
213
+ const ccOnly = cacheComponents === true && modes.length === 0
214
+ const publicItemModule = ccOnly && modules.publicItemCc ? modules.publicItemCc : modules.publicItem
215
+ const detailModule = ccOnly && modules.detailCc ? modules.detailCc : modules.detail
216
+ const editModule = ccOnly && modules.editCc ? modules.editCc : modules.edit
211
217
 
212
218
  const coreFacade = (kind, target, specifier) => ({
213
219
  kind,
@@ -275,8 +281,8 @@ export function planEntityRoutes({ entities, facts, coreRoutes, resolveFile, cac
275
281
  coreFacade('loading', `${base}/loading.tsx`, modules.loading),
276
282
  composed('page', `${base}/page.tsx`, 'createEntityListRoute', modules.list, [config, arg.template()], { acceptsTemplate: true, reexport: [{ names: ['metadata'], specifier: modules.listMetadata }] }),
277
283
  composed('page', `${base}/create/page.tsx`, 'createEntityCreateRoute', modules.create, [config, arg.template()], { acceptsTemplate: true }),
278
- composed('page', `${base}/[id]/page.tsx`, 'createEntityDetailRoute', modules.detail, [config, arg.literal(children), arg.template()], { acceptsTemplate: true, reexport: [{ names: ['metadata'], specifier: modules.detailMetadata }] }),
279
- composed('page', `${base}/[id]/edit/page.tsx`, 'createEntityEditRoute', modules.edit, [config, arg.template()], { acceptsTemplate: true })
284
+ composed('page', `${base}/[id]/page.tsx`, 'createEntityDetailRoute', detailModule, [config, arg.literal(children), arg.template()], { acceptsTemplate: true, reexport: [{ names: ['metadata'], specifier: modules.detailMetadata }] }),
285
+ composed('page', `${base}/[id]/edit/page.tsx`, 'createEntityEditRoute', editModule, [config, arg.template()], { acceptsTemplate: true })
280
286
  )
281
287
  }
282
288
 
@@ -80,11 +80,15 @@ export const CORE_COMPOSITION_WRAPPERS = Object.freeze({
80
80
  [`${INTERNAL}devtools-layout.cc`]: ['withDevtoolsGuard'],
81
81
  // Every page and layout under /superadmin and /devtools (the manifest's `access`).
82
82
  [`${INTERNAL}area-access`]: ['withSuperadminAccess', 'withDevtoolsAccess', 'withSuperadminMetadata', 'withDevtoolsMetadata', 'withSuperadminRouteAccess', 'withDevtoolsRouteAccess'],
83
+ // The same, for a Cache Components host (each segment checks inside its own Suspense boundary).
84
+ [`${INTERNAL}area-access.cc`]: ['withSuperadminAccess', 'withDevtoolsAccess', 'withSuperadminMetadata', 'withDevtoolsMetadata', 'withSuperadminRouteAccess', 'withDevtoolsRouteAccess'],
83
85
  [`${INTERNAL}entity-layout-route`]: ['createEntityLayoutRoute'],
84
86
  [`${INTERNAL}entity-list-route`]: ['createEntityListRoute'],
85
87
  [`${INTERNAL}entity-detail-route`]: ['createEntityDetailRoute'],
86
88
  [`${INTERNAL}entity-create-route`]: ['createEntityCreateRoute'],
87
89
  [`${INTERNAL}entity-edit-route`]: ['createEntityEditRoute'],
90
+ [`${INTERNAL}entity-detail-route.cc`]: ['createEntityDetailRoute'],
91
+ [`${INTERNAL}entity-edit-route.cc`]: ['createEntityEditRoute'],
88
92
  [`${INTERNAL}public-item-route`]: ['createPublicItemRoute', 'createPublicItemMetadata'],
89
93
  [`${INTERNAL}public-item-route.cc`]: ['createPublicItemRoute', 'createPublicItemMetadata'],
90
94
  [`${INTERNAL}public-archive-route`]: ['createPublicArchiveRoute', 'createPublicArchiveMetadata'],
@@ -66,6 +66,8 @@ export const VARIANT_FILES = Object.freeze({
66
66
  'superadmin/layout.cc.tsx': 'superadmin/layout.tsx',
67
67
  'devtools/layout.cc.tsx': 'devtools/layout.tsx',
68
68
  'dashboard/layout.cc.tsx': 'dashboard/layout.tsx',
69
+ 'dashboard/(main)/layout.cc.tsx': 'dashboard/(main)/layout.tsx',
70
+ '(public)/page.cc.tsx': '(public)/page.tsx',
69
71
  '(auth)/login/page.cc.tsx': '(auth)/login/page.tsx',
70
72
  '(auth)/signup/page.cc.tsx': '(auth)/signup/page.tsx',
71
73
  '(public)/docs/[section]/[page]/page.cc.tsx': '(public)/docs/[section]/[page]/page.tsx',
@@ -105,6 +107,15 @@ export const VARIANT_COMPOSE = Object.freeze({
105
107
  'devtools/layout.cc.tsx': { wrapper: 'withDevtoolsGuard', specifier: `${ROUTES_SUBPATH}/_internal/devtools-layout.cc` },
106
108
  })
107
109
 
110
+ /**
111
+ * The per-segment access check of a variant, when it differs from its base route's: in Cache Components mode every
112
+ * page and layout under an area checks the role inside its own Suspense boundary (area-access.cc).
113
+ */
114
+ export const VARIANT_ACCESS = Object.freeze({
115
+ 'superadmin/layout.cc.tsx': { ...ACCESS_ROUTES['superadmin/layout.tsx'], specifier: `${ROUTES_SUBPATH}/_internal/area-access.cc` },
116
+ 'devtools/layout.cc.tsx': { ...ACCESS_ROUTES['devtools/layout.tsx'], specifier: `${ROUTES_SUBPATH}/_internal/area-access.cc` },
117
+ })
118
+
108
119
  /**
109
120
  * Files that live next to a route without being one: the API explorer's presets, read as text by the
110
121
  * registry build (registry/discovery/api-presets.mjs), and its docs.md.
@@ -168,7 +179,8 @@ export function buildRoutesManifest(routesDir = ROUTES_DIR) {
168
179
  const replaced = manifest.find(entry => entry.target === target)
169
180
  if (!replaced) throw new Error(`Variant ${file} (${mode}) replaces ${target}, which is not a core route`)
170
181
  const compose = VARIANT_COMPOSE[file] ?? replaced.compose
171
- return { kind: replaced.kind, target, specifier: specifierForRouteFile(file), ...(compose ? { compose } : {}), ...(replaced.access ? { access: replaced.access } : {}) }
182
+ const access = VARIANT_ACCESS[file] ?? replaced.access
183
+ return { kind: replaced.kind, target, specifier: specifierForRouteFile(file), ...(compose ? { compose } : {}), ...(access ? { access } : {}) }
172
184
  })
173
185
  }
174
186
  return { manifest, variants }
@@ -29,6 +29,17 @@ export function stripSSLParams(databaseUrl) {
29
29
  }
30
30
  }
31
31
 
32
+ // On globalThis, like src/lib/db.ts: one warning per process however many copies of the module are loaded
33
+ const SSL_WARNED = Symbol.for('nextspark.dbSslDisabledWarned')
34
+
35
+ /** Once per process, and not for a loopback host: mirrors `warnSSLDisabledInProduction` in src/lib/db.ts. */
36
+ function warnSSLDisabledInProduction(url) {
37
+ if (globalThis[SSL_WARNED]) return
38
+ if (['localhost', '127.0.0.1', '[::1]'].includes(url.hostname.toLowerCase())) return
39
+ globalThis[SSL_WARNED] = true
40
+ console.warn('[DB] WARNING: SSL disabled in production environment. This is insecure!')
41
+ }
42
+
32
43
  /**
33
44
  * Parse the SSL policy used by database scripts.
34
45
  *
@@ -47,7 +58,7 @@ export function parseSSLConfig(databaseUrl) {
47
58
  if (sslmode) {
48
59
  switch (sslmode) {
49
60
  case 'disable':
50
- if (isProduction) console.warn('[DB] WARNING: SSL disabled in production environment. This is insecure!')
61
+ if (isProduction) warnSSLDisabledInProduction(url)
51
62
  return false
52
63
  case 'require':
53
64
  case 'prefer':
@@ -260,35 +260,8 @@ const nextConfig = {
260
260
  source: '/:path*',
261
261
  headers: securityHeaders
262
262
  },
263
- // CORS headers for API routes
264
- // NOTE: In development, CORS is handled dynamically by API routes using addCorsHeaders()
265
- // to support multiple origins (web app, mobile app, etc.)
266
- // In production, we set static CORS headers here
267
- ...(isProduction ? [{
268
- source: '/api/:path*',
269
- headers: [
270
- {
271
- key: 'Access-Control-Allow-Origin',
272
- value: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'
273
- },
274
- {
275
- key: 'Access-Control-Allow-Methods',
276
- value: 'GET, POST, PUT, DELETE, OPTIONS, PATCH'
277
- },
278
- {
279
- key: 'Access-Control-Allow-Headers',
280
- value: 'Content-Type, Authorization, x-api-key, x-verify-from-ui, Cookie, Set-Cookie'
281
- },
282
- {
283
- key: 'Access-Control-Allow-Credentials',
284
- value: 'true'
285
- },
286
- {
287
- key: 'Access-Control-Expose-Headers',
288
- value: 'Set-Cookie'
289
- }
290
- ]
291
- }] : [])
263
+ // No CORS headers here: core's API routes answer CORS per request (addCorsHeaders), so the
264
+ // origins in api.cors.allowedOrigins and CORS_ADDITIONAL_ORIGINS get their grant in production too
292
265
  ]
293
266
  },
294
267
  }
@@ -10,6 +10,7 @@
10
10
  import { NextRequest, NextResponse } from 'next/server'
11
11
  import { queryWithRLS } from '@nextsparkjs/core/lib/db'
12
12
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
13
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
13
14
 
14
15
  interface Author {
15
16
  id: string
@@ -151,3 +152,5 @@ const getHandler = async (
151
152
  }
152
153
 
153
154
  export const GET = withRateLimitTier(getHandler, 'read')
155
+
156
+ export const OPTIONS = corsPreflight
@@ -10,6 +10,7 @@
10
10
  import { NextRequest, NextResponse } from 'next/server'
11
11
  import { queryWithRLS } from '@nextsparkjs/core/lib/db'
12
12
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
13
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
13
14
 
14
15
  interface AuthorWithCount {
15
16
  id: string
@@ -64,3 +65,5 @@ const getHandler = async (request: NextRequest) => {
64
65
  }
65
66
 
66
67
  export const GET = withRateLimitTier(getHandler, 'read')
68
+
69
+ export const OPTIONS = corsPreflight
@@ -11,6 +11,7 @@
11
11
  import { NextRequest, NextResponse } from 'next/server'
12
12
  import { queryWithRLS } from '@nextsparkjs/core/lib/db'
13
13
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
14
+ import { corsPreflight } from '@nextsparkjs/core/lib/api/cors-response'
14
15
 
15
16
  interface Post {
16
17
  id: string
@@ -152,3 +153,5 @@ const getHandler = async (request: NextRequest) => {
152
153
  }
153
154
 
154
155
  export const GET = withRateLimitTier(getHandler, 'read')
156
+
157
+ export const OPTIONS = corsPreflight
@@ -200,8 +200,19 @@ function getSession(request: NextRequest) {
200
200
  * session. Gating the strip on protected prefixes is not enough: Next.js
201
201
  * dispatches Server Actions by the `Next-Action` header, not by the URL, so an
202
202
  * action can be POSTed to a public path with a forged `x-user-id`.
203
+ *
204
+ * The `x-api-*` names are never set here: core takes an API key's identity from
205
+ * validating the key, and nothing downstream may receive them from the client.
203
206
  */
204
- const TRUSTED_IDENTITY_HEADERS = ['x-user-id', 'x-user-email', 'x-pathname', 'x-active-team-id'] as const
207
+ const TRUSTED_IDENTITY_HEADERS = [
208
+ 'x-user-id',
209
+ 'x-user-email',
210
+ 'x-pathname',
211
+ 'x-active-team-id',
212
+ 'x-api-user-id',
213
+ 'x-api-key-id',
214
+ 'x-api-scopes',
215
+ ] as const
205
216
 
206
217
  /**
207
218
  * Build the request headers forwarded to the app: inbound copy minus every
Binary file