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

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 (456) hide show
  1. package/dist/components/api/keys/CreateApiKeyDialog.d.ts.map +1 -1
  2. package/dist/components/api/keys/CreateApiKeyDialog.js +2 -1
  3. package/dist/components/app/layouts/PublicFooter.d.ts.map +1 -1
  4. package/dist/components/app/layouts/PublicFooter.js +2 -23
  5. package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
  6. package/dist/components/app/misc/ThemeToggle.js +2 -1
  7. package/dist/components/auth/forms/LoginForm.js +1 -1
  8. package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
  9. package/dist/components/auth/forms/SignupForm.js +2 -1
  10. package/dist/components/auth/pages/AuthErrorPage.d.ts.map +1 -1
  11. package/dist/components/auth/pages/AuthErrorPage.js +2 -1
  12. package/dist/components/billing/ManageBillingButton.d.ts.map +1 -1
  13. package/dist/components/billing/ManageBillingButton.js +2 -1
  14. package/dist/components/dashboard/block-editor/array-field.d.ts.map +1 -1
  15. package/dist/components/dashboard/block-editor/array-field.js +2 -1
  16. package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
  17. package/dist/components/dashboard/block-editor/block-picker.js +2 -1
  18. package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
  19. package/dist/components/dashboard/block-editor/builder-editor-view.js +3 -2
  20. package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -1
  21. package/dist/components/dashboard/block-editor/config-panel.js +3 -2
  22. package/dist/components/dashboard/block-editor/dynamic-form.d.ts.map +1 -1
  23. package/dist/components/dashboard/block-editor/dynamic-form.js +2 -1
  24. package/dist/components/dashboard/block-editor/entity-fields-sidebar.d.ts.map +1 -1
  25. package/dist/components/dashboard/block-editor/entity-fields-sidebar.js +3 -2
  26. package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
  27. package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
  28. package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
  29. package/dist/components/dashboard/layouts/TopNavbar.js +4 -3
  30. package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
  31. package/dist/components/dashboard/misc/SearchDropdown.js +2 -1
  32. package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
  33. package/dist/components/dashboard/mobile/MobileTopBar.js +2 -1
  34. package/dist/components/devtools/BlockDetailViewer.d.ts.map +1 -1
  35. package/dist/components/devtools/BlockDetailViewer.js +2 -1
  36. package/dist/components/devtools/BlocksViewer.d.ts.map +1 -1
  37. package/dist/components/devtools/BlocksViewer.js +2 -1
  38. package/dist/components/devtools/ConfigViewer.d.ts.map +1 -1
  39. package/dist/components/devtools/ConfigViewer.js +3 -2
  40. package/dist/components/devtools/TestCasesViewer.d.ts.map +1 -1
  41. package/dist/components/devtools/TestCasesViewer.js +3 -2
  42. package/dist/components/devtools/TestCoverageDashboard.d.ts.map +1 -1
  43. package/dist/components/devtools/TestCoverageDashboard.js +2 -1
  44. package/dist/components/devtools/api-explorer/ApiDocsModal.d.ts.map +1 -1
  45. package/dist/components/devtools/api-explorer/ApiDocsModal.js +0 -0
  46. package/dist/components/devtools/api-explorer/ApiExplorer.d.ts.map +1 -1
  47. package/dist/components/devtools/api-explorer/ApiExplorer.js +2 -1
  48. package/dist/components/devtools/scheduled-actions/actions-table.d.ts.map +1 -1
  49. package/dist/components/devtools/scheduled-actions/actions-table.js +3 -2
  50. package/dist/components/docs/docs-sidebar.d.ts.map +1 -1
  51. package/dist/components/docs/docs-sidebar.js +3 -2
  52. package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
  53. package/dist/components/entities/EntityFieldRenderer.js +2 -1
  54. package/dist/components/entities/EntityList.d.ts.map +1 -1
  55. package/dist/components/entities/EntityList.js +2 -1
  56. package/dist/components/entities/EntityTable.d.ts.map +1 -1
  57. package/dist/components/entities/EntityTable.js +3 -2
  58. package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
  59. package/dist/components/entities/ErrorBoundary.js +2 -1
  60. package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
  61. package/dist/components/entities/wrappers/EntityDetailWrapper.js +3 -2
  62. package/dist/components/media/MediaCard.d.ts.map +1 -1
  63. package/dist/components/media/MediaCard.js +2 -1
  64. package/dist/components/media/MediaDetailPanel.d.ts.map +1 -1
  65. package/dist/components/media/MediaDetailPanel.js +2 -1
  66. package/dist/components/media/MediaList.d.ts.map +1 -1
  67. package/dist/components/media/MediaList.js +2 -1
  68. package/dist/components/media/MediaSelector.d.ts.map +1 -1
  69. package/dist/components/media/MediaSelector.js +2 -1
  70. package/dist/components/media/MediaUploadZone.d.ts.map +1 -1
  71. package/dist/components/media/MediaUploadZone.js +2 -1
  72. package/dist/components/public/entities/PublicEntityDetail.d.ts.map +1 -1
  73. package/dist/components/public/entities/PublicEntityDetail.js +2 -1
  74. package/dist/components/teams/TeamPendingInvitations.d.ts.map +1 -1
  75. package/dist/components/teams/TeamPendingInvitations.js +3 -2
  76. package/dist/components/ui/accordion.js +1 -1
  77. package/dist/components/ui/audio-upload.d.ts.map +1 -1
  78. package/dist/components/ui/audio-upload.js +2 -1
  79. package/dist/components/ui/avatar.d.ts +17 -1
  80. package/dist/components/ui/avatar.d.ts.map +1 -1
  81. package/dist/components/ui/avatar.js +29 -2
  82. package/dist/components/ui/badge.js +1 -1
  83. package/dist/components/ui/breadcrumb.d.ts +13 -0
  84. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  85. package/dist/components/ui/breadcrumb.js +23 -10
  86. package/dist/components/ui/button.js +1 -1
  87. package/dist/components/ui/card.js +1 -1
  88. package/dist/components/ui/checkbox.js +1 -1
  89. package/dist/components/ui/file-upload.d.ts.map +1 -1
  90. package/dist/components/ui/file-upload.js +2 -1
  91. package/dist/components/ui/image-upload.d.ts.map +1 -1
  92. package/dist/components/ui/image-upload.js +4 -3
  93. package/dist/components/ui/input.js +1 -1
  94. package/dist/components/ui/label.js +1 -1
  95. package/dist/components/ui/optimized-image.d.ts.map +1 -1
  96. package/dist/components/ui/optimized-image.js +5 -0
  97. package/dist/components/ui/pagination.d.ts +1 -1
  98. package/dist/components/ui/pagination.d.ts.map +1 -1
  99. package/dist/components/ui/pagination.js +3 -0
  100. package/dist/components/ui/progress.js +1 -1
  101. package/dist/components/ui/relation-display.d.ts.map +1 -1
  102. package/dist/components/ui/relation-display.js +3 -2
  103. package/dist/components/ui/separator.js +1 -1
  104. package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
  105. package/dist/components/ui/simple-relation-select.js +7 -6
  106. package/dist/components/ui/skeleton.js +1 -1
  107. package/dist/components/ui/slider.js +1 -1
  108. package/dist/components/ui/switch.js +1 -1
  109. package/dist/components/ui/tabs.js +1 -1
  110. package/dist/components/ui/textarea.js +1 -1
  111. package/dist/components/ui/user-display.d.ts.map +1 -1
  112. package/dist/components/ui/user-display.js +2 -1
  113. package/dist/components/ui/user-select.d.ts.map +1 -1
  114. package/dist/components/ui/user-select.js +2 -1
  115. package/dist/components/ui/video-upload.d.ts.map +1 -1
  116. package/dist/components/ui/video-upload.js +3 -2
  117. package/dist/components/users/tables/UsersTable.d.ts.map +1 -1
  118. package/dist/components/users/tables/UsersTable.js +3 -2
  119. package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
  120. package/dist/contexts/SubscriptionContext.js +4 -3
  121. package/dist/contexts/TeamContext.d.ts.map +1 -1
  122. package/dist/contexts/TeamContext.js +3 -2
  123. package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -1
  124. package/dist/hooks/useAccountPreferencesSync.js +2 -1
  125. package/dist/hooks/useApiExplorerNavigation.d.ts.map +1 -1
  126. package/dist/hooks/useApiExplorerNavigation.js +2 -1
  127. package/dist/hooks/useAuth.d.ts.map +1 -1
  128. package/dist/hooks/useAuth.js +3 -2
  129. package/dist/hooks/useEnsureUserMetadata.d.ts.map +1 -1
  130. package/dist/hooks/useEnsureUserMetadata.js +3 -2
  131. package/dist/hooks/useEntityWithMeta.d.ts.map +1 -1
  132. package/dist/hooks/useEntityWithMeta.js +3 -2
  133. package/dist/hooks/useInvoice.d.ts.map +1 -1
  134. package/dist/hooks/useInvoice.js +2 -1
  135. package/dist/hooks/useInvoices.d.ts.map +1 -1
  136. package/dist/hooks/useInvoices.js +2 -1
  137. package/dist/hooks/useMedia.d.ts.map +1 -1
  138. package/dist/hooks/useMedia.js +10 -9
  139. package/dist/hooks/useMediaUpload.d.ts.map +1 -1
  140. package/dist/hooks/useMediaUpload.js +2 -1
  141. package/dist/hooks/useMembership.d.ts.map +1 -1
  142. package/dist/hooks/useMembership.js +3 -2
  143. package/dist/hooks/usePatternUsages.d.ts.map +1 -1
  144. package/dist/hooks/usePatternUsages.js +3 -2
  145. package/dist/hooks/usePrefetch.d.ts.map +1 -1
  146. package/dist/hooks/usePrefetch.js +3 -2
  147. package/dist/hooks/useQuota.d.ts.map +1 -1
  148. package/dist/hooks/useQuota.js +2 -1
  149. package/dist/hooks/useTeamInvitations.d.ts.map +1 -1
  150. package/dist/hooks/useTeamInvitations.js +4 -3
  151. package/dist/hooks/useTeamMembers.d.ts.map +1 -1
  152. package/dist/hooks/useTeamMembers.js +5 -4
  153. package/dist/hooks/useTeamUpdate.d.ts.map +1 -1
  154. package/dist/hooks/useTeamUpdate.js +2 -1
  155. package/dist/hooks/useUserProfile.d.ts.map +1 -1
  156. package/dist/hooks/useUserProfile.js +3 -2
  157. package/dist/hooks/useUserSettings.d.ts.map +1 -1
  158. package/dist/hooks/useUserSettings.js +3 -2
  159. package/dist/lib/actions/entity.actions.d.ts.map +1 -1
  160. package/dist/lib/actions/entity.actions.js +2 -1
  161. package/dist/lib/api/entities.d.ts.map +1 -1
  162. package/dist/lib/api/entities.js +4 -3
  163. package/dist/lib/auth/verify-email-link.d.ts +10 -0
  164. package/dist/lib/auth/verify-email-link.d.ts.map +1 -0
  165. package/dist/lib/auth/verify-email-link.js +14 -0
  166. package/dist/lib/auth-client.d.ts +2 -0
  167. package/dist/lib/auth-client.d.ts.map +1 -1
  168. package/dist/lib/auth-client.js +4 -0
  169. package/dist/lib/auth.d.ts.map +1 -1
  170. package/dist/lib/auth.js +10 -2
  171. package/dist/lib/base-path.d.ts +85 -0
  172. package/dist/lib/base-path.d.ts.map +1 -0
  173. package/dist/lib/base-path.js +79 -0
  174. package/dist/lib/billing/schema.d.ts +1 -1
  175. package/dist/lib/billing/schema.d.ts.map +1 -1
  176. package/dist/lib/billing/schema.js +1 -1
  177. package/dist/lib/blocks/sanitize-html.d.ts.map +1 -1
  178. package/dist/lib/blocks/sanitize-html.js +18 -2
  179. package/dist/lib/cache/revalidate-tag.d.ts +14 -0
  180. package/dist/lib/cache/revalidate-tag.d.ts.map +1 -0
  181. package/dist/lib/cache/revalidate-tag.js +8 -0
  182. package/dist/lib/config/dashboard-schema.d.ts +1 -1
  183. package/dist/lib/config/dashboard-schema.d.ts.map +1 -1
  184. package/dist/lib/config/dashboard-schema.js +1 -1
  185. package/dist/lib/config/types.d.ts +36 -16
  186. package/dist/lib/config/types.d.ts.map +1 -1
  187. package/dist/lib/docs/access.d.ts +28 -0
  188. package/dist/lib/docs/access.d.ts.map +1 -0
  189. package/dist/lib/docs/access.js +16 -0
  190. package/dist/lib/docs/parser.d.ts.map +1 -1
  191. package/dist/lib/docs/parser.js +2 -1
  192. package/dist/lib/docs/remark-doc-links.d.ts +14 -0
  193. package/dist/lib/docs/remark-doc-links.d.ts.map +1 -0
  194. package/dist/lib/docs/remark-doc-links.js +38 -0
  195. package/dist/lib/entities/api-generator.d.ts +1 -1
  196. package/dist/lib/entities/api-generator.d.ts.map +1 -1
  197. package/dist/lib/entities/api-generator.js +1 -1
  198. package/dist/lib/entities/schema-generator.d.ts +1 -1
  199. package/dist/lib/entities/schema-generator.d.ts.map +1 -1
  200. package/dist/lib/entities/schema-generator.js +1 -1
  201. package/dist/lib/mcp/engine.js +1 -1
  202. package/dist/lib/mcp/schema-builder.d.ts +1 -1
  203. package/dist/lib/mcp/schema-builder.d.ts.map +1 -1
  204. package/dist/lib/mcp/schema-builder.js +1 -1
  205. package/dist/lib/mcp/tool-generator.js +1 -1
  206. package/dist/lib/mcp/types.d.ts +1 -1
  207. package/dist/lib/mcp/types.d.ts.map +1 -1
  208. package/dist/lib/media/schemas.d.ts +1 -1
  209. package/dist/lib/media/schemas.d.ts.map +1 -1
  210. package/dist/lib/media/schemas.js +1 -1
  211. package/dist/lib/middleware/index.d.ts +5 -1
  212. package/dist/lib/middleware/index.d.ts.map +1 -1
  213. package/dist/lib/middleware/index.js +3 -2
  214. package/dist/lib/services/meta.service.d.ts +60 -0
  215. package/dist/lib/services/meta.service.d.ts.map +1 -1
  216. package/dist/lib/services/meta.service.js +132 -12
  217. package/dist/lib/services/middleware.service.d.ts.map +1 -1
  218. package/dist/lib/services/middleware.service.js +3 -2
  219. package/dist/lib/teams/schema.d.ts +1 -1
  220. package/dist/lib/teams/schema.d.ts.map +1 -1
  221. package/dist/lib/teams/schema.js +1 -1
  222. package/dist/lib/teams/teams.api.d.ts.map +1 -1
  223. package/dist/lib/teams/teams.api.js +4 -3
  224. package/dist/lib/user-data-client.d.ts.map +1 -1
  225. package/dist/lib/user-data-client.js +3 -2
  226. package/dist/lib/validation/invoices.d.ts +1 -1
  227. package/dist/lib/validation/invoices.d.ts.map +1 -1
  228. package/dist/lib/validation/invoices.js +1 -1
  229. package/dist/lib/validation-schemas.d.ts +1 -1
  230. package/dist/lib/validation-schemas.d.ts.map +1 -1
  231. package/dist/lib/validation-schemas.js +1 -1
  232. package/dist/lib/validation.d.ts +1 -1
  233. package/dist/lib/validation.d.ts.map +1 -1
  234. package/dist/lib/validation.js +1 -1
  235. package/dist/messages/de/footer.json +0 -1
  236. package/dist/messages/de/index.d.ts +0 -1
  237. package/dist/messages/de/index.d.ts.map +1 -1
  238. package/dist/messages/en/footer.json +0 -1
  239. package/dist/messages/en/index.d.ts +0 -1
  240. package/dist/messages/en/index.d.ts.map +1 -1
  241. package/dist/messages/es/footer.json +0 -1
  242. package/dist/messages/es/index.d.ts +0 -1
  243. package/dist/messages/es/index.d.ts.map +1 -1
  244. package/dist/messages/fr/footer.json +0 -1
  245. package/dist/messages/fr/index.d.ts +0 -1
  246. package/dist/messages/fr/index.d.ts.map +1 -1
  247. package/dist/messages/it/footer.json +0 -1
  248. package/dist/messages/it/index.d.ts +0 -1
  249. package/dist/messages/it/index.d.ts.map +1 -1
  250. package/dist/messages/pt/footer.json +0 -1
  251. package/dist/messages/pt/index.d.ts +0 -1
  252. package/dist/messages/pt/index.d.ts.map +1 -1
  253. package/dist/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -3
  254. package/dist/templates/app/(auth)/verify-email/page.tsx +4 -3
  255. package/dist/templates/app/(public)/docs/[section]/[page]/page.tsx +11 -0
  256. package/dist/templates/app/api/auth/[...all]/route.ts +15 -14
  257. package/dist/templates/app/api/internal/user-metadata/route.ts +6 -8
  258. package/dist/templates/app/api/user/plan-flags/route.ts +1 -1
  259. package/dist/templates/app/api/user/profile/route.ts +12 -17
  260. package/dist/templates/app/api/v1/api-keys/route.ts +1 -1
  261. package/dist/templates/app/api/v1/auth/signup-with-invite/route.ts +2 -1
  262. package/dist/templates/app/api/v1/billing/cancel/route.ts +1 -1
  263. package/dist/templates/app/api/v1/billing/change-plan/route.ts +1 -1
  264. package/dist/templates/app/api/v1/billing/check-action/route.ts +1 -1
  265. package/dist/templates/app/api/v1/billing/checkout/route.ts +1 -1
  266. package/dist/templates/app/api/v1/blocks/validate/route.ts +1 -1
  267. package/dist/templates/app/api/v1/media/[id]/tags/route.ts +1 -1
  268. package/dist/templates/app/api/v1/post-categories/[id]/route.ts +1 -1
  269. package/dist/templates/app/api/v1/post-categories/route.ts +1 -1
  270. package/dist/templates/app/api/v1/teams/[teamId]/members/route.ts +2 -1
  271. package/dist/templates/app/api/v1/teams/[teamId]/subscription/route.ts +3 -5
  272. package/dist/templates/app/api/v1/teams/docs.md +4 -9
  273. package/dist/templates/app/api/v1/teams/switch/route.ts +1 -1
  274. package/dist/templates/app/api/v1/users/[id]/meta/[key]/route.ts +1 -1
  275. package/dist/templates/app/api/v1/users/[id]/route.ts +1 -1
  276. package/dist/templates/app/api/v1/users/route.ts +1 -1
  277. package/dist/templates/app/dashboard/(main)/media/page.tsx +3 -1
  278. package/dist/templates/app/dashboard/settings/api-keys/page.tsx +5 -4
  279. package/dist/templates/app/dashboard/settings/profile/page.tsx +3 -2
  280. package/dist/templates/app/devtools/scheduled-actions/page.tsx +2 -1
  281. package/dist/templates/app/superadmin/docs/[section]/[page]/page.tsx +16 -0
  282. package/dist/templates/app/superadmin/subscriptions/page.tsx +3 -2
  283. package/dist/templates/app/superadmin/teams/[teamId]/page.tsx +5 -4
  284. package/dist/templates/app/superadmin/users/[userId]/page.tsx +2 -1
  285. package/dist/templates/app/superadmin/users/page.tsx +2 -1
  286. package/dist/templates/blocks/cta-section/component.tsx +3 -2
  287. package/dist/templates/blocks/cta-section/schema.ts +1 -1
  288. package/dist/templates/blocks/features-grid/component.tsx +2 -1
  289. package/dist/templates/blocks/features-grid/schema.ts +1 -1
  290. package/dist/templates/blocks/hero/component.tsx +3 -2
  291. package/dist/templates/blocks/hero/schema.ts +1 -1
  292. package/dist/templates/blocks/testimonials/component.tsx +2 -1
  293. package/dist/templates/blocks/testimonials/schema.ts +1 -1
  294. package/dist/templates/blocks/text-content/component.tsx +2 -1
  295. package/dist/templates/blocks/text-content/schema.ts +1 -1
  296. package/dist/templates/ci-workflows/README.md +1 -1
  297. package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
  298. package/dist/templates/ci-workflows/github/cypress-smoke.yml +1 -1
  299. package/dist/templates/contents/plugins/starter/plugin/api/example/route.ts.template +1 -1
  300. package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +3 -2
  301. package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +1 -1
  302. package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +2 -1
  303. package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +1 -1
  304. package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +3 -2
  305. package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +1 -1
  306. package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +3 -2
  307. package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +1 -1
  308. package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +2 -1
  309. package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +1 -1
  310. package/dist/templates/contents/themes/starter/entities/posts/components/post-header.tsx +2 -1
  311. package/dist/templates/contents/themes/starter/lib/hooks/useAnalyticsData.ts +2 -1
  312. package/dist/templates/contents/themes/starter/lib/hooks/useTaskStats.ts +2 -1
  313. package/dist/templates/eslint.config.mjs +133 -9
  314. package/dist/templates/features/blog/blocks/post-content/component.tsx +2 -1
  315. package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
  316. package/dist/templates/features/blog/entities/posts/components/post-header.tsx +2 -1
  317. package/dist/templates/features/pages/blocks/hero/component.tsx +3 -2
  318. package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
  319. package/dist/templates/next.config.mjs +50 -29
  320. package/dist/templates/proxy.ts +100 -21
  321. package/dist/templates/public/sw.js +2 -2
  322. package/dist/templates/scripts/cy-run-prod.cjs +5 -5
  323. package/dist/types/blocks.d.ts +1 -1
  324. package/dist/types/blocks.d.ts.map +1 -1
  325. package/dist/types/blocks.js +1 -1
  326. package/package.json +9 -5
  327. package/scripts/build/docs-registry.mjs +7 -7
  328. package/scripts/build/registry/__tests__/billing-registry.test.mjs +43 -0
  329. package/scripts/build/registry/__tests__/build-output.test.mjs +209 -0
  330. package/scripts/build/registry/__tests__/copy-race-child.mjs +14 -0
  331. package/scripts/build/registry/__tests__/direct-fs-writes.mjs +203 -0
  332. package/scripts/build/registry/__tests__/globals-css-tag.test.mjs +66 -0
  333. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +530 -29
  334. package/scripts/build/registry/__tests__/page-generator.test.mjs +211 -37
  335. package/scripts/build/registry/__tests__/published-signatures.test.mjs +239 -0
  336. package/scripts/build/registry/__tests__/route-file-rule.test.mjs +170 -0
  337. package/scripts/build/registry/__tests__/safe-fs.test.mjs +333 -0
  338. package/scripts/build/registry/__tests__/template-analysis.test.mjs +142 -0
  339. package/scripts/build/registry/__tests__/template-registry.test.mjs +279 -9
  340. package/scripts/build/registry/__tests__/templates-plan.test.mjs +128 -0
  341. package/scripts/build/registry/__tests__/templates-tree.test.mjs +367 -0
  342. package/scripts/build/registry/__tests__/write-places.test.mjs +425 -0
  343. package/scripts/build/registry/config.mjs +6 -65
  344. package/scripts/build/registry/discovery/icons.mjs +498 -43
  345. package/scripts/build/registry/discovery/templates.mjs +1 -1
  346. package/scripts/build/registry/generators/billing-registry.mjs +1 -1
  347. package/scripts/build/registry/generators/docs-registry.mjs +3 -4
  348. package/scripts/build/registry/generators/feature-registry.mjs +1 -1
  349. package/scripts/build/registry/generators/permissions-registry.mjs +2 -2
  350. package/scripts/build/registry/generators/template-registry.mjs +65 -49
  351. package/scripts/build/registry/index.mjs +1 -2
  352. package/scripts/build/registry/post-build/index.mjs +1 -1
  353. package/scripts/build/registry/post-build/own-gitignores.mjs +220 -0
  354. package/scripts/build/registry/post-build/page-generator.mjs +512 -268
  355. package/scripts/build/registry/post-build/route-cleanup.mjs +16 -13
  356. package/scripts/build/registry/post-build/test-fixtures.mjs +26 -8
  357. package/scripts/build/registry/project-mode.mjs +76 -0
  358. package/scripts/build/registry/shared/typescript-compiler.mjs +77 -0
  359. package/scripts/build/registry/validate-env.test.mjs +12 -8
  360. package/scripts/build/registry/watch.mjs +3 -53
  361. package/scripts/build/registry/write-places.mjs +228 -0
  362. package/scripts/build/registry.mjs +53 -30
  363. package/scripts/build/safe-fs.mjs +279 -0
  364. package/scripts/build/templates-plan.mjs +44 -0
  365. package/scripts/build/theme.mjs +46 -42
  366. package/scripts/build/update-tsconfig.mjs +16 -15
  367. package/scripts/db/cluster-changes.mjs +205 -0
  368. package/scripts/db/connection-time-limits.mjs +53 -0
  369. package/scripts/db/inspect-server.mjs +108 -0
  370. package/scripts/db/migration-time-limit.mjs +695 -0
  371. package/scripts/db/run-migrations.mjs +46 -41
  372. package/scripts/db/ssl-config.mjs +194 -0
  373. package/scripts/db/theme-location.mjs +69 -0
  374. package/scripts/db/verify-tables.mjs +3 -8
  375. package/scripts/db/verify-teams.mjs +2 -6
  376. package/scripts/db/verify-theme-migrations.mjs +169 -0
  377. package/scripts/maintenance/core-updater.mjs +1003 -0
  378. package/scripts/maintenance/step-guard.mjs +74 -0
  379. package/scripts/maintenance/update-core.mjs +14 -831
  380. package/scripts/utils/console-guard.mjs +13 -0
  381. package/scripts/utils/generated-tag.mjs +66 -0
  382. package/scripts/utils/index.mjs +9 -1
  383. package/scripts/utils/logging.mjs +140 -0
  384. package/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -3
  385. package/templates/app/(auth)/verify-email/page.tsx +4 -3
  386. package/templates/app/(public)/docs/[section]/[page]/page.tsx +11 -0
  387. package/templates/app/api/auth/[...all]/route.ts +15 -14
  388. package/templates/app/api/internal/user-metadata/route.ts +6 -8
  389. package/templates/app/api/user/plan-flags/route.ts +1 -1
  390. package/templates/app/api/user/profile/route.ts +12 -17
  391. package/templates/app/api/v1/api-keys/route.ts +1 -1
  392. package/templates/app/api/v1/auth/signup-with-invite/route.ts +2 -1
  393. package/templates/app/api/v1/billing/cancel/route.ts +1 -1
  394. package/templates/app/api/v1/billing/change-plan/route.ts +1 -1
  395. package/templates/app/api/v1/billing/check-action/route.ts +1 -1
  396. package/templates/app/api/v1/billing/checkout/route.ts +1 -1
  397. package/templates/app/api/v1/blocks/validate/route.ts +1 -1
  398. package/templates/app/api/v1/media/[id]/tags/route.ts +1 -1
  399. package/templates/app/api/v1/post-categories/[id]/route.ts +1 -1
  400. package/templates/app/api/v1/post-categories/route.ts +1 -1
  401. package/templates/app/api/v1/teams/[teamId]/members/route.ts +2 -1
  402. package/templates/app/api/v1/teams/[teamId]/subscription/route.ts +3 -5
  403. package/templates/app/api/v1/teams/docs.md +4 -9
  404. package/templates/app/api/v1/teams/switch/route.ts +1 -1
  405. package/templates/app/api/v1/users/[id]/meta/[key]/route.ts +1 -1
  406. package/templates/app/api/v1/users/[id]/route.ts +1 -1
  407. package/templates/app/api/v1/users/route.ts +1 -1
  408. package/templates/app/dashboard/(main)/media/page.tsx +3 -1
  409. package/templates/app/dashboard/settings/api-keys/page.tsx +5 -4
  410. package/templates/app/dashboard/settings/profile/page.tsx +3 -2
  411. package/templates/app/devtools/scheduled-actions/page.tsx +2 -1
  412. package/templates/app/superadmin/docs/[section]/[page]/page.tsx +16 -0
  413. package/templates/app/superadmin/subscriptions/page.tsx +3 -2
  414. package/templates/app/superadmin/teams/[teamId]/page.tsx +5 -4
  415. package/templates/app/superadmin/users/[userId]/page.tsx +2 -1
  416. package/templates/app/superadmin/users/page.tsx +2 -1
  417. package/templates/blocks/cta-section/component.tsx +3 -2
  418. package/templates/blocks/cta-section/schema.ts +1 -1
  419. package/templates/blocks/features-grid/component.tsx +2 -1
  420. package/templates/blocks/features-grid/schema.ts +1 -1
  421. package/templates/blocks/hero/component.tsx +3 -2
  422. package/templates/blocks/hero/schema.ts +1 -1
  423. package/templates/blocks/testimonials/component.tsx +2 -1
  424. package/templates/blocks/testimonials/schema.ts +1 -1
  425. package/templates/blocks/text-content/component.tsx +2 -1
  426. package/templates/blocks/text-content/schema.ts +1 -1
  427. package/templates/ci-workflows/README.md +1 -1
  428. package/templates/ci-workflows/github/cypress-regression.yml +1 -1
  429. package/templates/ci-workflows/github/cypress-smoke.yml +1 -1
  430. package/templates/contents/plugins/starter/plugin/api/example/route.ts.template +1 -1
  431. package/templates/contents/themes/starter/blocks/cta-section/component.tsx +3 -2
  432. package/templates/contents/themes/starter/blocks/cta-section/schema.ts +1 -1
  433. package/templates/contents/themes/starter/blocks/features-grid/component.tsx +2 -1
  434. package/templates/contents/themes/starter/blocks/features-grid/schema.ts +1 -1
  435. package/templates/contents/themes/starter/blocks/hero/component.tsx +3 -2
  436. package/templates/contents/themes/starter/blocks/hero/schema.ts +1 -1
  437. package/templates/contents/themes/starter/blocks/testimonials/component.tsx +3 -2
  438. package/templates/contents/themes/starter/blocks/testimonials/schema.ts +1 -1
  439. package/templates/contents/themes/starter/blocks/text-content/component.tsx +2 -1
  440. package/templates/contents/themes/starter/blocks/text-content/schema.ts +1 -1
  441. package/templates/contents/themes/starter/entities/posts/components/post-header.tsx +2 -1
  442. package/templates/contents/themes/starter/lib/hooks/useAnalyticsData.ts +2 -1
  443. package/templates/contents/themes/starter/lib/hooks/useTaskStats.ts +2 -1
  444. package/templates/eslint.config.mjs +133 -9
  445. package/templates/features/blog/blocks/post-content/component.tsx +2 -1
  446. package/templates/features/blog/blocks/post-content/schema.ts +1 -1
  447. package/templates/features/blog/entities/posts/components/post-header.tsx +2 -1
  448. package/templates/features/pages/blocks/hero/component.tsx +3 -2
  449. package/templates/features/pages/blocks/hero/schema.ts +1 -1
  450. package/templates/next.config.mjs +50 -29
  451. package/templates/proxy.ts +100 -21
  452. package/templates/public/sw.js +2 -2
  453. package/templates/scripts/cy-run-prod.cjs +5 -5
  454. package/tests/jest/__mocks__/@nextsparkjs/registries/template-registry.client.ts +11 -0
  455. package/tests/jest/__mocks__/next-server.js +10 -0
  456. package/scripts/build/docs.mjs +0 -392
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { NextRequest, NextResponse } from 'next/server'
11
- import { z } from 'zod'
11
+ import * as z from 'zod'
12
12
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
13
13
  import { SubscriptionService, MembershipService } from '@nextsparkjs/core/lib/services'
14
14
  import { getBillingGateway } from '@nextsparkjs/core/lib/billing/gateways/factory'
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { NextRequest, NextResponse } from 'next/server'
11
- import { z } from 'zod'
11
+ import * as z from 'zod'
12
12
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
13
13
  import { SubscriptionService, MembershipService } from '@nextsparkjs/core/lib/services'
14
14
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
@@ -12,7 +12,7 @@
12
12
  import { NextRequest, NextResponse } from 'next/server'
13
13
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
14
14
  import { SubscriptionService } from '@nextsparkjs/core/lib/services'
15
- import { z } from 'zod'
15
+ import * as z from 'zod'
16
16
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
17
17
 
18
18
  const checkActionSchema = z.object({
@@ -11,7 +11,7 @@ import { NextRequest, NextResponse } from 'next/server'
11
11
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
12
12
  import { getBillingGateway } from '@nextsparkjs/core/lib/billing/gateways/factory'
13
13
  import { SubscriptionService, MembershipService } from '@nextsparkjs/core/lib/services'
14
- import { z } from 'zod'
14
+ import * as z from 'zod'
15
15
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
16
16
 
17
17
  const checkoutSchema = z.object({
@@ -1,6 +1,6 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
2
  import { BLOCK_REGISTRY } from '@nextsparkjs/registries/block-registry'
3
- import { z } from 'zod'
3
+ import * as z from 'zod'
4
4
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
5
5
 
6
6
  const requestSchema = z.object({
@@ -5,7 +5,7 @@ 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
7
  import { MediaService } from '@nextsparkjs/core/lib/services/media.service'
8
- import { z } from 'zod'
8
+ import * as z from 'zod'
9
9
 
10
10
  const addTagSchema = z.object({
11
11
  tagId: z.string().min(1),
@@ -1,7 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
2
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
3
3
  import { query as dbQuery } from '@nextsparkjs/core/lib/db'
4
- import { z } from 'zod'
4
+ import * as z from 'zod'
5
5
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
6
6
 
7
7
  const updateCategorySchema = z.object({
@@ -1,7 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
2
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
3
3
  import { query as dbQuery } from '@nextsparkjs/core/lib/db'
4
- import { z } from 'zod'
4
+ import * as z from 'zod'
5
5
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
6
6
 
7
7
  const createCategorySchema = z.object({
@@ -19,6 +19,7 @@ import type { TeamMember, TeamInvitation, TeamRole, Team } from '@nextsparkjs/co
19
19
  import { EmailFactory } from '@nextsparkjs/core/lib/email/factory'
20
20
  import { sendTeamInvitationEmail } from '@nextsparkjs/core/lib/email/send'
21
21
  import { I18N_CONFIG } from '@nextsparkjs/core/lib/config'
22
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
22
23
 
23
24
  // Handle CORS preflight
24
25
  export async function OPTIONS(request: NextRequest) {
@@ -294,7 +295,7 @@ export const POST = withRateLimitTier(withApiLogging(
294
295
 
295
296
  // Build accept URL
296
297
  const baseUrl = (process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:5173').replace(/\/$/, '')
297
- const acceptUrl = `${baseUrl}/accept-invite/${token}`
298
+ const acceptUrl = `${baseUrl}${withBasePath(`/accept-invite/${token}`)}`
298
299
 
299
300
  // Send invitation email
300
301
  try {
@@ -41,11 +41,9 @@ export const GET = withRateLimitTier(async function GET(request: NextRequest, pr
41
41
 
42
42
  const subscription = await SubscriptionService.getActive(teamId)
43
43
 
44
- if (!subscription) {
45
- return createApiError('No active subscription found for this team', 404)
46
- }
47
-
48
- return createApiResponse({ subscription })
44
+ // A team can legitimately have no subscription yet. Keep that normal state
45
+ // in the successful response so dashboard loads do not log a 404.
46
+ return createApiResponse({ subscription: subscription ?? null })
49
47
  } catch (error) {
50
48
  console.error('[Billing API] Error fetching subscription:', error)
51
49
  return createApiError('Failed to fetch subscription', 500)
@@ -194,25 +194,20 @@ Same as POST /members - creates a new invitation.
194
194
  ### Get Team Subscription
195
195
  `GET /api/v1/teams/[teamId]/subscription`
196
196
 
197
- Returns the team's active subscription details. Requires `billing.view` permission.
197
+ Returns the team's active subscription details, or `null` when the team has not subscribed yet. Requires `billing.view` permission.
198
198
 
199
199
  **Response:**
200
200
  ```json
201
201
  {
202
202
  "success": true,
203
203
  "data": {
204
- "subscription": {
205
- "id": "sub_123",
206
- "planId": "plan_pro",
207
- "planName": "Pro",
208
- "status": "active",
209
- "currentPeriodEnd": "2024-03-01T00:00:00Z",
210
- "cancelAtPeriodEnd": false
211
- }
204
+ "subscription": null
212
205
  }
213
206
  }
214
207
  ```
215
208
 
209
+ When an active subscription exists, `subscription` contains its details.
210
+
216
211
  ---
217
212
 
218
213
  ## Usage & Quota Endpoints
@@ -14,7 +14,7 @@ import {
14
14
  ACTIVE_TEAM_COOKIE_MAX_AGE,
15
15
  activeTeamCookieValue,
16
16
  } from '@nextsparkjs/core/lib/teams/active-team-cookie'
17
- import { z } from 'zod'
17
+ import * as z from 'zod'
18
18
 
19
19
  const switchTeamSchema = z.object({
20
20
  teamId: z.string().min(1, 'Team ID is required'),
@@ -29,7 +29,7 @@ import {
29
29
  addCorsHeaders,
30
30
  } from '@nextsparkjs/core/lib/api/helpers'
31
31
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth'
32
- import { z } from 'zod'
32
+ import * as z from 'zod'
33
33
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
34
34
 
35
35
  // Validation schema for metadata value
@@ -12,7 +12,7 @@ import {
12
12
  processEntityMetadata
13
13
  } from '@nextsparkjs/core/lib/api/helpers';
14
14
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth';
15
- import { z } from 'zod';
15
+ import * as z from 'zod';
16
16
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit';
17
17
 
18
18
  const updateUserSchema = z.object({
@@ -16,7 +16,7 @@ import {
16
16
  } from '@nextsparkjs/core/lib/api/helpers';
17
17
  import { authenticateRequest, createAuthFailureResponse } from '@nextsparkjs/core/lib/api/auth/dual-auth';
18
18
  import { hasAdminPermission } from '@nextsparkjs/core/lib/api/auth/permissions';
19
- import { z } from 'zod';
19
+ import * as z from 'zod';
20
20
  import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit';
21
21
 
22
22
  const createUserSchema = z.object({
@@ -51,6 +51,7 @@ import { usePermissions } from '@nextsparkjs/core/lib/permissions/hooks'
51
51
  import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
52
52
  import type { Media, MediaListOptions } from '@nextsparkjs/core/lib/media/types'
53
53
  import type { Permission } from '@nextsparkjs/core/lib/permissions/types'
54
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
54
55
 
55
56
  type ViewMode = 'grid' | 'list'
56
57
 
@@ -484,8 +485,9 @@ function DefaultMediaDashboardPage() {
484
485
  {/* Left: Image preview - Dark canvas */}
485
486
  <div className="relative bg-neutral-950 flex items-center justify-center overflow-hidden h-[250px] md:h-auto">
486
487
  {editingMedia?.mimeType.startsWith('image/') ? (
488
+ // eslint-disable-next-line @next/next/no-img-element -- the original upload at its own size, whose dimensions next/image would need up front
487
489
  <img
488
- src={editingMedia.url}
490
+ src={withBasePathIfInApp(editingMedia.url)}
489
491
  alt={editingMedia.alt || editingMedia.filename}
490
492
  className="max-w-[90%] max-h-[90%] object-contain select-none"
491
493
  draggable={false}
@@ -37,6 +37,7 @@ import { ApiKeyDisplay } from '@nextsparkjs/core/components/api/keys/ApiKeyDispl
37
37
  import { toast } from 'sonner';
38
38
  import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
39
39
  import { sel } from '@nextsparkjs/core/selectors'
40
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
40
41
 
41
42
  interface ApiKey {
42
43
  id: string;
@@ -73,7 +74,7 @@ function ApiKeysPage() {
73
74
  const { data: apiKeys, isLoading, error } = useQuery<ApiKey[]>({
74
75
  queryKey: ['api-keys'],
75
76
  queryFn: async () => {
76
- const response = await fetch('/api/v1/api-keys');
77
+ const response = await fetch(withBasePath('/api/v1/api-keys'));
77
78
  if (!response.ok) {
78
79
  const errorData = await response.json();
79
80
  throw new Error(errorData.error || 'Failed to fetch API keys');
@@ -86,7 +87,7 @@ function ApiKeysPage() {
86
87
  // Revoke API key mutation
87
88
  const revokeApiKey = useMutation({
88
89
  mutationFn: async (keyId: string) => {
89
- const response = await fetch(`/api/v1/api-keys/${keyId}`, {
90
+ const response = await fetch(withBasePath(`/api/v1/api-keys/${keyId}`), {
90
91
  method: 'DELETE'
91
92
  });
92
93
  if (!response.ok) {
@@ -107,7 +108,7 @@ function ApiKeysPage() {
107
108
  // Toggle API key status
108
109
  const toggleApiKey = useMutation({
109
110
  mutationFn: async ({ keyId, status }: { keyId: string; status: 'active' | 'inactive' }) => {
110
- const response = await fetch(`/api/v1/api-keys/${keyId}`, {
111
+ const response = await fetch(withBasePath(`/api/v1/api-keys/${keyId}`), {
111
112
  method: 'PATCH',
112
113
  headers: { 'Content-Type': 'application/json' },
113
114
  body: JSON.stringify({ status })
@@ -417,7 +418,7 @@ function ApiKeyDetailsDialog({
417
418
  const { data: keyDetails, isLoading } = useQuery({
418
419
  queryKey: ['api-key-details', keyId],
419
420
  queryFn: async () => {
420
- const response = await fetch(`/api/v1/api-keys/${keyId}`);
421
+ const response = await fetch(withBasePath(`/api/v1/api-keys/${keyId}`));
421
422
  if (!response.ok) throw new Error('Failed to fetch API key details');
422
423
  const result = await response.json();
423
424
  return result.data;
@@ -64,6 +64,7 @@ import { countries, timezones } from '@nextsparkjs/core/lib/countries-timezones'
64
64
  import { sel } from '@nextsparkjs/core/selectors'
65
65
  import { useLocale, useTranslations } from 'next-intl'
66
66
  import { getTemplateOrDefaultClient } from '@nextsparkjs/registries/template-registry.client'
67
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
67
68
 
68
69
  // Language options
69
70
  const languages = [
@@ -119,7 +120,7 @@ function ProfilePage() {
119
120
  // Update profile mutation
120
121
  const updateProfileMutation = useMutation({
121
122
  mutationFn: async (data: ProfileFormData) => {
122
- const response = await fetch('/api/user/profile', {
123
+ const response = await fetch(withBasePath('/api/user/profile'), {
123
124
  method: 'PATCH',
124
125
  headers: {
125
126
  'Content-Type': 'application/json',
@@ -151,7 +152,7 @@ function ProfilePage() {
151
152
  // Delete account mutation
152
153
  const deleteAccountMutation = useMutation({
153
154
  mutationFn: async () => {
154
- const response = await fetch('/api/user/delete-account', {
155
+ const response = await fetch(withBasePath('/api/user/delete-account'), {
155
156
  method: 'DELETE',
156
157
  headers: {
157
158
  'Content-Type': 'application/json',
@@ -23,6 +23,7 @@ import { sel } from '@nextsparkjs/core/selectors'
23
23
  import { Filters } from '@nextsparkjs/core/components/devtools/scheduled-actions/filters'
24
24
  import { ActionsTable } from '@nextsparkjs/core/components/devtools/scheduled-actions/actions-table'
25
25
  import type { ScheduledActionsFilters, ScheduledActionsResponse } from '@nextsparkjs/core/components/devtools/scheduled-actions/types'
26
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
26
27
 
27
28
  async function fetchScheduledActions(
28
29
  filters: ScheduledActionsFilters,
@@ -42,7 +43,7 @@ async function fetchScheduledActions(
42
43
  params.append('page', page.toString())
43
44
  params.append('limit', limit.toString())
44
45
 
45
- const response = await fetch(`/api/v1/devtools/scheduled-actions?${params.toString()}`)
46
+ const response = await fetch(withBasePath(`/api/v1/devtools/scheduled-actions?${params.toString()}`))
46
47
 
47
48
  if (!response.ok) {
48
49
  throw new Error('Failed to fetch scheduled actions')
@@ -15,6 +15,22 @@ interface SuperadminDocsPageProps {
15
15
  }>
16
16
  }
17
17
 
18
+ // generateStaticParams below lists every superadmin doc page, and
19
+ // dynamicParams = false answers 404 for any other section/page pair in
20
+ // `next dev`. connection() keeps these pages from being prerendered, so a
21
+ // production build renders them on demand, where Next has no prerendered list
22
+ // to check, and the notFound() calls below cannot set the status either: they
23
+ // run inside the superadmin layout's Suspense boundary, after the response
24
+ // head has gone out with a 200. For those requests the proxy answers 404
25
+ // before anything renders (isMissingDocsPage in proxy.ts).
26
+ export const dynamicParams = false
27
+
28
+ export async function generateStaticParams() {
29
+ return DOCS_REGISTRY.superadmin.flatMap(section =>
30
+ section.pages.map(page => ({ section: section.slug, page: page.slug }))
31
+ )
32
+ }
33
+
18
34
  export async function generateMetadata({ params }: SuperadminDocsPageProps): Promise<Metadata> {
19
35
  const resolvedParams = await params
20
36
  const { section: sectionSlug, page: pageSlug } = resolvedParams
@@ -43,6 +43,7 @@ import {
43
43
  ExternalLink,
44
44
  } from "lucide-react";
45
45
  import Link from "next/link";
46
+ import { withBasePath, withBasePathIfInApp } from "@nextsparkjs/core/lib/base-path";
46
47
  import { getTemplateOrDefaultClient } from "@nextsparkjs/registries/template-registry.client";
47
48
  import {
48
49
  SearchInput,
@@ -229,7 +230,7 @@ function SubscriptionsPage() {
229
230
  queryFn: async () => {
230
231
  const queryString = getQueryParams();
231
232
  const url = `/api/superadmin/subscriptions${queryString ? `?${queryString}` : ""}`;
232
- const response = await fetch(url);
233
+ const response = await fetch(withBasePath(url));
233
234
  if (!response.ok) {
234
235
  throw new Error("Failed to fetch subscriptions data");
235
236
  }
@@ -600,7 +601,7 @@ function SubscriptionsPage() {
600
601
  className="text-muted-foreground"
601
602
  >
602
603
  <a
603
- href={sub.providerDashboardUrl}
604
+ href={withBasePathIfInApp(sub.providerDashboardUrl)}
604
605
  target="_blank"
605
606
  rel="noopener noreferrer"
606
607
  >
@@ -43,6 +43,7 @@ import {
43
43
  } from "lucide-react";
44
44
  import Link from "next/link";
45
45
  import { getTemplateOrDefaultClient } from "@nextsparkjs/registries/template-registry.client";
46
+ import { withBasePath, withBasePathIfInApp } from "@nextsparkjs/core/lib/base-path"
46
47
 
47
48
  interface TeamOwner {
48
49
  id: string;
@@ -153,7 +154,7 @@ function TeamDetailPage() {
153
154
  const { data: teamData, isLoading, error, refetch } = useQuery<TeamDetailData>({
154
155
  queryKey: ["superadmin-team", teamId],
155
156
  queryFn: async () => {
156
- const response = await fetch(`/api/superadmin/teams/${teamId}`);
157
+ const response = await fetch(withBasePath(`/api/superadmin/teams/${teamId}`));
157
158
  if (!response.ok) {
158
159
  if (response.status === 404) {
159
160
  throw new Error("Team not found");
@@ -503,7 +504,7 @@ function TeamDetailPage() {
503
504
  {teamData.subscription.providerName || 'Payment Provider'}
504
505
  </h4>
505
506
  <a
506
- href={teamData.subscription.providerDashboardUrl}
507
+ href={withBasePathIfInApp(teamData.subscription.providerDashboardUrl)}
507
508
  target="_blank"
508
509
  rel="noopener noreferrer"
509
510
  className="inline-flex items-center gap-1 text-sm text-primary hover:underline"
@@ -604,7 +605,7 @@ function TeamDetailPage() {
604
605
  <div className="flex items-center gap-2">
605
606
  {event.invoiceUrl && (
606
607
  <a
607
- href={event.invoiceUrl}
608
+ href={withBasePathIfInApp(event.invoiceUrl)}
608
609
  target="_blank"
609
610
  rel="noopener noreferrer"
610
611
  className="text-primary hover:underline text-sm"
@@ -614,7 +615,7 @@ function TeamDetailPage() {
614
615
  )}
615
616
  {event.receiptUrl && (
616
617
  <a
617
- href={event.receiptUrl}
618
+ href={withBasePathIfInApp(event.receiptUrl)}
618
619
  target="_blank"
619
620
  rel="noopener noreferrer"
620
621
  className="text-primary hover:underline text-sm"
@@ -39,6 +39,7 @@ import {
39
39
  } from "lucide-react";
40
40
  import Link from "next/link";
41
41
  import { getTemplateOrDefaultClient } from "@nextsparkjs/registries/template-registry.client";
42
+ import { withBasePath } from "@nextsparkjs/core/lib/base-path"
42
43
 
43
44
  interface TeamMembership {
44
45
  teamId: string;
@@ -114,7 +115,7 @@ function UserDetailPage() {
114
115
  const { data: userData, isLoading, error, refetch } = useQuery<UserDetailData>({
115
116
  queryKey: ["superadmin-user", userId],
116
117
  queryFn: async () => {
117
- const response = await fetch(`/api/superadmin/users/${userId}`);
118
+ const response = await fetch(withBasePath(`/api/superadmin/users/${userId}`));
118
119
  if (!response.ok) {
119
120
  if (response.status === 404) {
120
121
  throw new Error("User not found");
@@ -38,6 +38,7 @@ import {
38
38
  FilterDropdown,
39
39
  } from "@nextsparkjs/core/components/superadmin/filters";
40
40
  import { sel } from "@nextsparkjs/core/selectors";
41
+ import { withBasePath } from "@nextsparkjs/core/lib/base-path"
41
42
 
42
43
  interface UsersData {
43
44
  regularUsers: User[];
@@ -119,7 +120,7 @@ function UsersPage() {
119
120
  queryKey: ["superadmin-users", search, roleFilter, statusFilter, activeTab, page, limit],
120
121
  queryFn: async () => {
121
122
  const queryString = getQueryParams();
122
- const response = await fetch(`/api/superadmin/users?${queryString}`);
123
+ const response = await fetch(withBasePath(`/api/superadmin/users?${queryString}`));
123
124
  if (!response.ok) {
124
125
  throw new Error("Failed to fetch users data");
125
126
  }
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import { Button } from '@nextsparkjs/core/components/ui/button'
3
3
  import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
4
4
  import type { CTASectionBlockProps } from './schema'
5
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
5
6
 
6
7
  /**
7
8
  * CTA Section Block Component
@@ -67,7 +68,7 @@ export function CTASectionBlock({
67
68
  {primaryCta && (
68
69
  <Button asChild size="lg">
69
70
  <a
70
- href={primaryCta.link}
71
+ href={withBasePathIfInApp(primaryCta.link)}
71
72
  target={primaryCta.target}
72
73
  rel={primaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
73
74
  >
@@ -83,7 +84,7 @@ export function CTASectionBlock({
83
84
  variant={secondaryButton.variant || 'outline'}
84
85
  >
85
86
  <a
86
- href={secondaryButton.link}
87
+ href={withBasePathIfInApp(secondaryButton.link)}
87
88
  target={secondaryButton.target}
88
89
  rel={secondaryButton.target === '_blank' ? 'noopener noreferrer' : undefined}
89
90
  >
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import { baseBlockSchema, ctaSchema } from '@nextsparkjs/core/types/blocks'
3
3
 
4
4
  /**
@@ -8,6 +8,7 @@ import * as Icons from 'lucide-react'
8
8
  import { cn } from '@nextsparkjs/core/lib/utils'
9
9
  import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
10
10
  import type { FeaturesGridBlockProps, FeatureItem } from './schema'
11
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
11
12
 
12
13
  /**
13
14
  * Features Grid Block Component
@@ -101,7 +102,7 @@ export function FeaturesGridBlock({
101
102
  {cta && (
102
103
  <div className="mt-12 text-center">
103
104
  <a
104
- href={cta.link}
105
+ href={withBasePathIfInApp(cta.link)}
105
106
  target={cta.target}
106
107
  rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
107
108
  className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
3
3
 
4
4
  /**
@@ -3,6 +3,7 @@ import { Button } from '@nextsparkjs/core/components/ui/button'
3
3
  import { cn } from '@nextsparkjs/core/lib/utils'
4
4
  import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
5
5
  import type { HeroBlockProps } from './schema'
6
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
6
7
 
7
8
  /**
8
9
  * Hero Block Component
@@ -62,7 +63,7 @@ export function HeroBlock({
62
63
  <div
63
64
  className="absolute inset-0 z-0"
64
65
  style={{
65
- backgroundImage: `url(${backgroundImageUrl})`,
66
+ backgroundImage: `url(${withBasePathIfInApp(backgroundImageUrl)})`,
66
67
  backgroundSize: 'cover',
67
68
  backgroundPosition: 'center',
68
69
  }}
@@ -88,7 +89,7 @@ export function HeroBlock({
88
89
  {ctaConfig && (
89
90
  <Button asChild size="lg" className="text-lg px-8 py-6">
90
91
  <a
91
- href={ctaConfig.link}
92
+ href={withBasePathIfInApp(ctaConfig.link)}
92
93
  target={ctaConfig.target}
93
94
  rel={ctaConfig.target === '_blank' ? 'noopener noreferrer' : undefined}
94
95
  >
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import {
3
3
  baseBlockSchema,
4
4
  mediaRefSchema,
@@ -4,6 +4,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@nextsparkjs/core/component
4
4
  import { cn } from '@nextsparkjs/core/lib/utils'
5
5
  import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
6
6
  import type { TestimonialsBlockProps, TestimonialItem } from './schema'
7
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
7
8
 
8
9
  /**
9
10
  * Testimonials Block Component
@@ -98,7 +99,7 @@ export function TestimonialsBlock({
98
99
  {cta && (
99
100
  <div className="mt-12 text-center">
100
101
  <a
101
- href={cta.link}
102
+ href={withBasePathIfInApp(cta.link)}
102
103
  target={cta.target}
103
104
  rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
104
105
  className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import { baseBlockSchema, mediaRefSchema } from '@nextsparkjs/core/types/blocks'
3
3
 
4
4
  /**
@@ -3,6 +3,7 @@ import { cn } from '@nextsparkjs/core/lib/utils'
3
3
  import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
4
4
  import { sanitizeBlockHtml } from '@nextsparkjs/core/lib/blocks/sanitize-html'
5
5
  import type { TextContentBlockProps } from './schema'
6
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
6
7
 
7
8
  /**
8
9
  * Text Content Block Component
@@ -82,7 +83,7 @@ export function TextContentBlock({
82
83
  alignmentClasses[alignment]
83
84
  )}>
84
85
  <a
85
- href={cta.link}
86
+ href={withBasePathIfInApp(cta.link)}
86
87
  target={cta.target}
87
88
  rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
88
89
  className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
3
3
 
4
4
  /**
@@ -35,7 +35,7 @@ Runs critical path tests on every PR to catch breaking changes quickly.
35
35
 
36
36
  **Configuration:**
37
37
  - Uses `@smoke` tag to filter tests
38
- - Runs on Ubuntu with Node.js 20
38
+ - Runs on Ubuntu with Node.js 22.14.0 or later
39
39
  - Uploads artifacts on failure
40
40
 
41
41
  ### cypress-regression.yml
@@ -42,7 +42,7 @@ jobs:
42
42
  - name: Setup Node.js
43
43
  uses: actions/setup-node@v4
44
44
  with:
45
- node-version: '20'
45
+ node-version: '22'
46
46
 
47
47
  - name: Setup pnpm
48
48
  uses: pnpm/action-setup@v2
@@ -35,7 +35,7 @@ jobs:
35
35
  - name: Setup Node.js
36
36
  uses: actions/setup-node@v4
37
37
  with:
38
- node-version: '20'
38
+ node-version: '22'
39
39
 
40
40
  - name: Setup pnpm
41
41
  uses: pnpm/action-setup@v2
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { NextRequest, NextResponse } from 'next/server'
11
- import { z } from 'zod'
11
+ import * as z from 'zod'
12
12
  import { getAuthContext } from '@/core/lib/api/auth'
13
13
  import { usePlugin } from '@/core/lib/registries/plugin-registry'
14
14
 
@@ -2,6 +2,7 @@ import React from 'react'
2
2
  import { Button } from '@nextsparkjs/core/components/ui/button'
3
3
  import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
4
4
  import type { CTASectionBlockProps } from './schema'
5
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
5
6
 
6
7
  /**
7
8
  * CTA Section Block Component
@@ -67,7 +68,7 @@ export function CTASectionBlock({
67
68
  {primaryCta && (
68
69
  <Button asChild size="lg">
69
70
  <a
70
- href={primaryCta.link}
71
+ href={withBasePathIfInApp(primaryCta.link)}
71
72
  target={primaryCta.target}
72
73
  rel={primaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
73
74
  >
@@ -83,7 +84,7 @@ export function CTASectionBlock({
83
84
  variant={secondaryButton.variant || 'outline'}
84
85
  >
85
86
  <a
86
- href={secondaryButton.link}
87
+ href={withBasePathIfInApp(secondaryButton.link)}
87
88
  target={secondaryButton.target}
88
89
  rel={secondaryButton.target === '_blank' ? 'noopener noreferrer' : undefined}
89
90
  >