@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
@@ -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
@@ -72,7 +73,7 @@ export function TestimonialsBlock({
72
73
  <Quote className="h-8 w-8 text-primary mb-4" />
73
74
 
74
75
  <blockquote className="mb-6 text-lg flex-grow">
75
- "{item.quote}"
76
+ &quot;{item.quote}&quot;
76
77
  </blockquote>
77
78
 
78
79
  <div className="flex items-center gap-3">
@@ -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
  /**
@@ -1,4 +1,5 @@
1
1
  import { Badge } from '@nextsparkjs/core/components/ui/badge'
2
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
2
3
  import Image from 'next/image'
3
4
 
4
5
  interface Category {
@@ -24,7 +25,7 @@ export function PostHeader({ post }: PostHeaderProps) {
24
25
  {post.featuredImage && (
25
26
  <div className="relative w-full h-[400px] md:h-[500px] mb-8" data-cy="post-featured-image-display">
26
27
  <Image
27
- src={post.featuredImage}
28
+ src={withBasePathIfInApp(post.featuredImage)}
28
29
  alt={post.title}
29
30
  fill
30
31
  className="object-cover rounded-lg"
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { useQuery } from '@tanstack/react-query'
4
4
  import { useTeamContext } from '@nextsparkjs/core/contexts/TeamContext'
5
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
5
6
 
6
7
  interface WeeklyProgress {
7
8
  day: string
@@ -31,7 +32,7 @@ export function useAnalyticsData() {
31
32
  return useQuery({
32
33
  queryKey: ['analytics', currentTeam?.id],
33
34
  queryFn: async (): Promise<AnalyticsData> => {
34
- const res = await fetch(`/api/v1/analytics?teamId=${currentTeam?.id}`)
35
+ const res = await fetch(withBasePath(`/api/v1/analytics?teamId=${currentTeam?.id}`))
35
36
  if (!res.ok) throw new Error('Failed to fetch analytics')
36
37
  return res.json()
37
38
  },
@@ -4,6 +4,7 @@ import { useMemo } from 'react'
4
4
  import { useQuery } from '@tanstack/react-query'
5
5
  import { useTeamContext } from '@nextsparkjs/core/contexts/TeamContext'
6
6
  import { calculateTaskStats, type TaskStats } from '../utils'
7
+ import { withBasePath } from '@nextsparkjs/core/lib/base-path'
7
8
 
8
9
  interface Task {
9
10
  id: string
@@ -32,7 +33,7 @@ export function useTaskStats(): UseTaskStatsReturn {
32
33
  } = useQuery({
33
34
  queryKey: ['tasks', currentTeam?.id, 'stats'],
34
35
  queryFn: async (): Promise<Task[]> => {
35
- const response = await fetch(`/api/v1/tasks?teamId=${currentTeam?.id}&limit=1000`)
36
+ const response = await fetch(withBasePath(`/api/v1/tasks?teamId=${currentTeam?.id}&limit=1000`))
36
37
  if (!response.ok) {
37
38
  throw new Error('Failed to fetch tasks')
38
39
  }
@@ -1,16 +1,140 @@
1
- import { dirname } from "path";
2
- import { fileURLToPath } from "url";
3
- import { FlatCompat } from "@eslint/eslintrc";
1
+ import { createRequire } from "node:module";
2
+ import { dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
4
 
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = dirname(__filename);
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const require = createRequire(import.meta.url);
7
7
 
8
- const compat = new FlatCompat({
9
- baseDirectory: __dirname,
10
- });
8
+ /**
9
+ * Next's presets from the eslint-config-next the project installs, as flat config.
10
+ *
11
+ * Version 16 publishes flat config arrays on these subpaths; reaching them through FlatCompat
12
+ * throws `Converting circular structure to JSON` before a single file is read. Version 15 declares
13
+ * no `exports` and publishes eslintrc presets, which FlatCompat is the only way to read: importing
14
+ * the subpaths throws ERR_MODULE_NOT_FOUND, or, under a loader that adds file extensions, returns
15
+ * eslintrc objects. That is what a Next 15 project gets when `nextspark init` drops this file next
16
+ * to its eslint-config-next. FlatCompat ships in @eslint/eslintrc, which ESLint itself depends on,
17
+ * so it is resolved from there.
18
+ */
19
+ async function nextPresets() {
20
+ let presets;
21
+ try {
22
+ presets = await Promise.all([
23
+ import("eslint-config-next/core-web-vitals"),
24
+ import("eslint-config-next/typescript"),
25
+ ]);
26
+ } catch (error) {
27
+ if (error?.code !== "ERR_MODULE_NOT_FOUND") throw error;
28
+ }
29
+
30
+ if (presets?.every((preset) => Array.isArray(preset.default))) {
31
+ return presets.flatMap((preset) => preset.default);
32
+ }
33
+
34
+ const { FlatCompat } = createRequire(require.resolve("eslint"))("@eslint/eslintrc");
35
+ return new FlatCompat({ baseDirectory: __dirname }).extends("next/core-web-vitals", "next/typescript");
36
+ }
37
+
38
+ /** A config object holding nothing but `ignores` applies to every other object in the array. */
39
+ const isGlobalIgnore = (config) =>
40
+ Object.keys(config).every((key) => key === "ignores" || key === "name");
41
+
42
+ const presets = await nextPresets();
43
+
44
+ /** typescript-eslint's parser, which reads every syntax these trees use: JS, TS and JSX. */
45
+ const typescriptParser = presets
46
+ .map((config) => config.languageOptions?.parser)
47
+ .find((parser) => parser?.meta?.name === "typescript-eslint/parser");
48
+
49
+ const SOURCE_FILES = "**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}";
50
+
51
+ // Tests and fixtures, the project's own and those every theme and plugin brings under contents/:
52
+ // they mock, stub and cast by design, so Next's presets skip them and only the zod rule reaches
53
+ // them. Everything else -- app/, contents/ and what the project adds -- gets the presets.
54
+ const TEST_FILES = [
55
+ "**/tests/**",
56
+ "**/__tests__/**",
57
+ "**/__mocks__/**",
58
+ "**/fixtures/**",
59
+ "**/cypress/**",
60
+ "**/*.{test,spec,cy}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}",
61
+ "**/{jest,cypress}.{config,setup}.{ts,mts,cts,js,mjs,cjs}",
62
+ ];
63
+
64
+ /** "error", 2 or ["error", ...]. */
65
+ const isError = (setting) => [setting, setting?.[0]].some((level) => level === "error" || level === 2);
66
+
67
+ /**
68
+ * The severity this project gives the rules Next's presets configure.
69
+ *
70
+ * `@next/next/no-img-element` is an error: the presets only warn, which leaves `eslint .` passing,
71
+ * and next/image is what serves an image resized and in a modern format.
72
+ *
73
+ * eslint-plugin-react-hooks 7, which Next 16's presets load, adds to rules-of-hooks and
74
+ * exhaustive-deps the rules that flag code the React Compiler cannot compile. A NextSpark project
75
+ * does not build with the React Compiler, and the components NextSpark ships in app/ and its themes
76
+ * and plugins break several of those rules, so they report as warnings. Version 5, which Next 15
77
+ * loads, has none of them.
78
+ */
79
+ function projectSeverity(rule, setting) {
80
+ if (rule === "@next/next/no-img-element") return "error";
81
+ const compilerRule = rule.startsWith("react-hooks/") && !["react-hooks/rules-of-hooks", "react-hooks/exhaustive-deps"].includes(rule);
82
+ return compilerRule && isError(setting) ? "warn" : setting;
83
+ }
11
84
 
12
85
  const eslintConfig = [
13
- ...compat.extends("next/core-web-vitals", "next/typescript"),
86
+ {
87
+ // Next writes next-env.d.ts itself; version 16's presets ignore it and version 15's do not.
88
+ ignores: [".next/**", ".nextspark/**", "next-env.d.ts"],
89
+ },
90
+ ...presets.map((config) =>
91
+ isGlobalIgnore(config)
92
+ ? config
93
+ : {
94
+ ...config,
95
+ ignores: [...(config.ignores ?? []), ...TEST_FILES],
96
+ ...(config.rules && {
97
+ rules: Object.fromEntries(Object.entries(config.rules).map(([rule, setting]) => [rule, projectSeverity(rule, setting)])),
98
+ }),
99
+ },
100
+ ),
101
+ {
102
+ // A .cjs file is CommonJS by definition, so `require` is the only spelling it has.
103
+ files: ["**/*.cjs"],
104
+ ignores: TEST_FILES,
105
+ rules: { "@typescript-eslint/no-require-imports": "off" },
106
+ },
107
+ {
108
+ // The presets would have supplied the parser here. Their plugins are registered so the disable
109
+ // comments in tests resolve the rules they name, without turning any of those rules on.
110
+ files: TEST_FILES,
111
+ languageOptions: {
112
+ parser: typescriptParser,
113
+ parserOptions: { ecmaFeatures: { jsx: true } },
114
+ },
115
+ plugins: Object.assign({}, ...presets.map((config) => config.plugins ?? {})),
116
+ linterOptions: { reportUnusedDisableDirectives: "off" },
117
+ },
118
+ {
119
+ // Spelled out rather than inherited: a block naming these extensions is what makes ESLint lint
120
+ // a .ts file at all.
121
+ files: [SOURCE_FILES],
122
+ rules: {
123
+ // `no-restricted-imports` with `importNames: ["z"]` also rejects `import * as z`, so the
124
+ // named specifier is matched by syntax instead.
125
+ "no-restricted-syntax": [
126
+ "error",
127
+ {
128
+ // `imported` is an Identifier for `{ z }` and a Literal for `{ "z" as zod }`, so the
129
+ // name lives under a different property in each.
130
+ selector:
131
+ "ImportDeclaration[source.value='zod'] > ImportSpecifier:matches([imported.name='z'], [imported.value='z']), ExportNamedDeclaration[source.value='zod'] > ExportSpecifier:matches([local.name='z'], [local.value='z'])",
132
+ message:
133
+ "Use `import * as z from 'zod'`. Turbopack doesn't tree-shake the named `z` import and bundles all of zod, its 63 locales included.",
134
+ },
135
+ ],
136
+ },
137
+ },
14
138
  ];
15
139
 
16
140
  export default eslintConfig;
@@ -4,6 +4,7 @@ import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
4
4
  import { sanitizeBlockHtml } from '@nextsparkjs/core/lib/blocks/sanitize-html'
5
5
  import { sel } from '../../lib/selectors'
6
6
  import type { PostContentBlockProps } from './schema'
7
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
7
8
 
8
9
  /**
9
10
  * Post Content Block Component
@@ -182,7 +183,7 @@ export function PostContentBlock({
182
183
  {cta && (
183
184
  <div className={cn('mt-12 text-center', maxWidthClasses[maxWidth], 'mx-auto')}>
184
185
  <a
185
- href={cta.link}
186
+ href={withBasePathIfInApp(cta.link)}
186
187
  target={cta.target}
187
188
  rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
188
189
  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 shadow-md hover:shadow-lg"
@@ -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
  /**
@@ -1,4 +1,5 @@
1
1
  import { Badge } from '@nextsparkjs/core/components/ui/badge'
2
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
2
3
  import Image from 'next/image'
3
4
 
4
5
  interface Category {
@@ -24,7 +25,7 @@ export function PostHeader({ post }: PostHeaderProps) {
24
25
  {post.featuredImage && (
25
26
  <div className="relative w-full h-[400px] md:h-[500px] mb-8" data-cy="post-featured-image-display">
26
27
  <Image
27
- src={post.featuredImage}
28
+ src={withBasePathIfInApp(post.featuredImage)}
28
29
  alt={post.title}
29
30
  fill
30
31
  className="object-cover rounded-lg"
@@ -4,6 +4,7 @@ import { cn } from '@nextsparkjs/core/lib/utils'
4
4
  import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
5
5
  import { sel } from '../../lib/selectors'
6
6
  import type { HeroBlockProps } from './schema'
7
+ import { withBasePathIfInApp } from '@nextsparkjs/core/lib/base-path'
7
8
 
8
9
  /**
9
10
  * Hero Block Component
@@ -71,7 +72,7 @@ export function HeroBlock({
71
72
  <div
72
73
  className="absolute inset-0 z-0"
73
74
  style={{
74
- backgroundImage: `url(${backgroundImageUrl})`,
75
+ backgroundImage: `url(${withBasePathIfInApp(backgroundImageUrl)})`,
75
76
  backgroundSize: 'cover',
76
77
  backgroundPosition: 'center',
77
78
  }}
@@ -100,7 +101,7 @@ export function HeroBlock({
100
101
  {ctaConfig && (
101
102
  <Button asChild size="lg" className="text-lg px-8 py-6">
102
103
  <a
103
- href={ctaConfig.link}
104
+ href={withBasePathIfInApp(ctaConfig.link)}
104
105
  target={ctaConfig.target}
105
106
  rel={ctaConfig.target === '_blank' ? 'noopener noreferrer' : undefined}
106
107
  data-cy={sel('blocks.hero.cta')}
@@ -1,4 +1,4 @@
1
- import { z } from 'zod'
1
+ import * as z from 'zod'
2
2
  import {
3
3
  baseBlockSchema,
4
4
  mediaRefSchema,
@@ -8,8 +8,52 @@ const __dirname = path.dirname(__filename);
8
8
  // For npm mode, use local i18n.ts that re-exports from @nextsparkjs/core
9
9
  const withNextIntl = createNextIntlPlugin('./i18n.ts');
10
10
 
11
+ // The app's Next.js basePath. Next.js adds it to routes and to <Link>, and to
12
+ // nothing a header names: the CSP report endpoints below are URLs the browser
13
+ // resolves against the origin, so they carry it from here.
14
+ const basePath = '';
15
+
16
+ /**
17
+ * Silences the Node built-ins that client bundles reach transitively, and points
18
+ * `@nextsparkjs/registries` at the generated directory.
19
+ *
20
+ * Only webpack reads this, and either major can build with it: Next 15 by
21
+ * default, Next 16 with `--webpack`. Turbopack resolves `@nextsparkjs/registries`
22
+ * through the `paths` of tsconfig.json, which Next's webpack skips for imports
23
+ * made from inside node_modules, as core's are, and leaves a Node built-in alone
24
+ * unless client code imports it for real.
25
+ */
26
+ const applyWebpackFallbacks = (config, { isServer }) => {
27
+ if (!isServer) {
28
+ config.resolve.fallback = {
29
+ ...config.resolve.fallback,
30
+ fs: false,
31
+ net: false,
32
+ tls: false,
33
+ crypto: false,
34
+ path: false,
35
+ os: false,
36
+ stream: false,
37
+ http: false,
38
+ https: false,
39
+ zlib: false,
40
+ dns: false,
41
+ }
42
+ }
43
+
44
+ // Add alias for @nextsparkjs/registries to fix ChunkLoadError
45
+ config.resolve.alias = {
46
+ ...config.resolve.alias,
47
+ 'pg-native': false,
48
+ '@nextsparkjs/registries': path.resolve(__dirname, '.nextspark/registries'),
49
+ }
50
+
51
+ return config
52
+ }
53
+
11
54
  /** @type {import('next').NextConfig} */
12
55
  const nextConfig = {
56
+ basePath,
13
57
  // Ignore TypeScript build errors - needed until DTS generation is enabled for @nextsparkjs/core
14
58
  // Without this, production builds fail due to missing declaration files for deep imports
15
59
  typescript: {
@@ -81,33 +125,10 @@ const nextConfig = {
81
125
  },
82
126
  ],
83
127
  },
84
- webpack: (config, { isServer }) => {
85
- if (!isServer) {
86
- config.resolve.fallback = {
87
- ...config.resolve.fallback,
88
- fs: false,
89
- net: false,
90
- tls: false,
91
- crypto: false,
92
- path: false,
93
- os: false,
94
- stream: false,
95
- http: false,
96
- https: false,
97
- zlib: false,
98
- dns: false,
99
- }
100
- }
101
-
102
- // Add alias for @nextsparkjs/registries to fix ChunkLoadError
103
- config.resolve.alias = {
104
- ...config.resolve.alias,
105
- 'pg-native': false,
106
- '@nextsparkjs/registries': path.resolve(__dirname, '.nextspark/registries'),
107
- }
108
-
109
- return config
110
- },
128
+ // Next.js sets TURBOPACK before it loads this file whenever Turbopack builds
129
+ // (on 15 with --turbopack, on 16 unless given --webpack), and next-intl picks
130
+ // its own webpack or Turbopack setup from the same variable.
131
+ ...(process.env.TURBOPACK ? {} : { webpack: applyWebpackFallbacks }),
111
132
  async headers() {
112
133
  const isProduction = process.env.NODE_ENV === 'production';
113
134
 
@@ -158,7 +179,7 @@ const nextConfig = {
158
179
  // CSP violation reporting - sends violations to /api/csp-report
159
180
  // report-uri is deprecated but has wider browser support
160
181
  // report-to is the modern replacement (configured via Reporting-Endpoints header)
161
- "report-uri /api/csp-report",
182
+ `report-uri ${basePath}/api/csp-report`,
162
183
  "report-to csp-endpoint",
163
184
  ];
164
185
 
@@ -167,7 +188,7 @@ const nextConfig = {
167
188
  // Reporting API endpoint for modern browsers (used by report-to CSP directive)
168
189
  {
169
190
  key: 'Reporting-Endpoints',
170
- value: 'csp-endpoint="/api/csp-report"'
191
+ value: `csp-endpoint="${basePath}/api/csp-report"`
171
192
  },
172
193
  {
173
194
  key: 'X-Content-Type-Options',