@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,13 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * NextSpark Core Updater v3.0
3
+ * NextSpark Core Updater
4
4
  *
5
- * Updates core framework files while preserving user customizations.
6
- * Downloads the latest release, copies core files, and preserves user data.
5
+ * Updates the project in the current directory to another release of the
6
+ * @nextsparkjs packages. See core-updater.mjs for what it changes, what it
7
+ * never touches and how a run that fails or is interrupted is rolled back.
7
8
  *
8
9
  * Usage:
9
10
  * pnpm update-core # Update to latest
10
- * pnpm update-core --version v2.0.0 # Specific version
11
+ * pnpm update-core --version 0.1.0-beta.189 # Specific version
11
12
  * pnpm update-core --branch # Create update branch
12
13
  * pnpm update-core --list # List releases
13
14
  * pnpm update-core --check # Check for updates
@@ -15,833 +16,15 @@
15
16
  * pnpm update-core --help # Show help
16
17
  */
17
18
 
18
- import fs from 'fs/promises'
19
- import path from 'path'
20
- import { execSync } from 'child_process'
21
- import https from 'https'
22
- import { createWriteStream } from 'fs'
23
- import { pipeline } from 'stream/promises'
24
- import AdmZip from 'adm-zip'
25
- import dotenv from 'dotenv'
19
+ import { updateCore } from './core-updater.mjs'
26
20
 
27
- // Load environment variables from .env file
28
- dotenv.config()
21
+ // A closed terminal fails writes to it; the run still has to stop its step and set its exit code
22
+ for (const stream of [process.stdout, process.stderr]) stream.on('error', () => {})
29
23
 
30
- // ==================== CONSTANTS ====================
31
-
32
- // Default repository (fallback if core.version.json doesn't exist)
33
- const DEFAULT_CORE_REPO = 'NextSpark-dev/nextspark'
34
-
35
- // Core plugins that should be updated (hardcoded)
36
- const CORE_PLUGINS = ['ai', 'amplitude', 'social-media-publisher']
37
-
38
- // Only theme that should be updated
39
- const CORE_THEME = 'default'
40
-
41
- // Root files that should be overwritten
42
- const ROOT_FILES_TO_COPY = [
43
- 'middleware.ts',
44
- 'next.config.ts',
45
- 'jest.config.ts',
46
- 'eslint.config.mjs',
47
- 'postcss.config.mjs',
48
- 'tsconfig.base.json',
49
- 'tsconfig.test.json',
50
- 'turbo.json',
51
- 'components.json',
52
- 'vercel.json',
53
- 'package.json'
54
- ]
55
-
56
- // Directories that should be completely overwritten
57
- const DIRECTORIES_TO_COPY = [
58
- 'core',
59
- 'app',
60
- '.rules'
61
- ]
62
-
63
- // Paths that should NEVER be overwritten (user files)
64
- const PROTECTED_PATHS = [
65
- // Environment files
66
- '.env',
67
- '.env.local',
68
- '.env.production',
69
- '.env.development',
70
- '.env.backup',
71
- '.env.prod',
72
- '.env.staging',
73
- '.env.vercel',
74
- '.env.example',
75
- // User content
76
- 'contents', // Managed separately (only default theme + core plugins)
77
- 'public/uploads', // User uploads
78
- 'supabase', // Local DB
79
- // Project-specific docs
80
- 'CLAUDE.md',
81
- 'README.md',
82
- 'DEPLOYMENT.md',
83
- // Claude workflow
84
- '.claude',
85
- // Git and dependencies
86
- '.git',
87
- 'node_modules',
88
- '.next',
89
- 'pnpm-lock.yaml',
90
- 'package-lock.json',
91
- // Version file (updated at the end)
92
- 'core.version.json',
93
- // Auto-generated
94
- 'tsconfig.json',
95
- 'tsconfig.tsbuildinfo',
96
- // Temp files
97
- '.tmp-core-update',
98
- '.tmp-core-update.zip',
99
- // IDE and other
100
- '.idea',
101
- '.cursor',
102
- '.vercel',
103
- '.turbo',
104
- '_tmp',
105
- 'coverage'
106
- ]
107
-
108
- // ==================== ARGUMENT PARSER ====================
109
-
110
- /**
111
- * Parse command line arguments into flags object
112
- */
113
- function parseArguments(args) {
114
- const flags = {
115
- version: null,
116
- list: false,
117
- check: false,
118
- current: false,
119
- help: false,
120
- latest: true,
121
- branch: false
122
- }
123
-
124
- for (let i = 0; i < args.length; i++) {
125
- const arg = args[i]
126
-
127
- if (arg === '--version' || arg === '-v') {
128
- flags.version = args[++i]
129
- flags.latest = false
130
- }
131
- else if (arg.startsWith('--version=')) {
132
- flags.version = arg.split('=')[1]
133
- flags.latest = false
134
- }
135
- else if (arg === '--list') flags.list = true
136
- else if (arg === '--check') flags.check = true
137
- else if (arg === '--current') flags.current = true
138
- else if (arg === '--latest') flags.latest = true
139
- else if (arg === '--branch' || arg === '-b') flags.branch = true
140
- else if (arg === '--help' || arg === '-h') flags.help = true
141
- }
142
-
143
- return flags
144
- }
145
-
146
- // ==================== HELPER FUNCTIONS ====================
147
-
148
- /**
149
- * Read current core version from core.version.json
150
- */
151
- async function getCurrentVersion() {
152
- try {
153
- const versionFile = await fs.readFile('core.version.json', 'utf8')
154
- const data = JSON.parse(versionFile)
155
- return data.version
156
- } catch {
157
- return 'unknown'
158
- }
159
- }
160
-
161
- /**
162
- * Get full version info including update date
163
- */
164
- async function getVersionInfo() {
165
- try {
166
- const versionFile = await fs.readFile('core.version.json', 'utf8')
167
- return JSON.parse(versionFile)
168
- } catch {
169
- return {
170
- version: 'unknown',
171
- updatedAt: null,
172
- releaseUrl: null,
173
- previousVersion: null
174
- }
175
- }
176
- }
177
-
178
- /**
179
- * Get core repository from core.version.json
180
- */
181
- async function getCoreRepository() {
182
- try {
183
- const versionFile = await fs.readFile('core.version.json', 'utf8')
184
- const data = JSON.parse(versionFile)
185
- return data.repository || DEFAULT_CORE_REPO
186
- } catch {
187
- return DEFAULT_CORE_REPO
188
- }
189
- }
190
-
191
- /**
192
- * Update core.version.json with new version info
193
- */
194
- async function updateVersionFile(releaseInfo, previousVersion) {
195
- // Preserve existing repository value
196
- const repository = await getCoreRepository()
197
-
198
- const versionData = {
199
- version: releaseInfo.tag_name,
200
- updatedAt: new Date().toISOString(),
201
- releaseUrl: releaseInfo.html_url,
202
- previousVersion: previousVersion,
203
- repository: repository
204
- }
205
-
206
- await fs.writeFile(
207
- 'core.version.json',
208
- JSON.stringify(versionData, null, 2) + '\n'
209
- )
210
-
211
- console.log(` ${previousVersion} -> ${releaseInfo.tag_name}`)
212
- }
213
-
214
- /**
215
- * Create initial core.version.json if it doesn't exist
216
- */
217
- async function ensureVersionFile() {
218
- try {
219
- await fs.access('core.version.json')
220
- } catch {
221
- // File doesn't exist, create it
222
- const versionData = {
223
- version: 'unknown',
224
- updatedAt: new Date().toISOString(),
225
- releaseUrl: null,
226
- previousVersion: null,
227
- repository: DEFAULT_CORE_REPO
228
- }
229
-
230
- await fs.writeFile(
231
- 'core.version.json',
232
- JSON.stringify(versionData, null, 2) + '\n'
233
- )
234
-
235
- console.log(' Created core.version.json (initial setup)')
236
- }
237
- }
238
-
239
- /**
240
- * Fetch release information from GitHub
241
- */
242
- async function fetchReleaseInfo(version = 'latest') {
243
- const CORE_REPO = await getCoreRepository()
244
- const url = version === 'latest'
245
- ? `https://api.github.com/repos/${CORE_REPO}/releases/latest`
246
- : `https://api.github.com/repos/${CORE_REPO}/releases/tags/${version}`
247
-
248
- // Headers for authentication (if repo is private)
249
- const headers = {
250
- 'User-Agent': 'nextspark-updater'
251
- }
252
-
253
- // If there's a GitHub token in env (for private repos or better rate limits)
254
- if (process.env.GITHUB_TOKEN) {
255
- headers['Authorization'] = `Bearer ${process.env.GITHUB_TOKEN}`
256
- }
257
-
258
- return new Promise((resolve, reject) => {
259
- https.get(url, { headers }, (res) => {
260
- let data = ''
261
-
262
- res.on('data', chunk => data += chunk)
263
-
264
- res.on('end', () => {
265
- if (res.statusCode === 401) {
266
- reject(new Error('GitHub authentication failed. Set GITHUB_TOKEN in .env for private repos.'))
267
- } else if (res.statusCode === 404) {
268
- reject(new Error(`Release not found: ${version}`))
269
- } else if (res.statusCode === 200) {
270
- resolve(JSON.parse(data))
271
- } else {
272
- reject(new Error(`Failed to fetch release: HTTP ${res.statusCode}`))
273
- }
274
- })
275
- }).on('error', reject)
276
- })
277
- }
278
-
279
- /**
280
- * Download file from URL
281
- */
282
- async function downloadFile(url, dest) {
283
- return new Promise((resolve, reject) => {
284
- https.get(url, {
285
- headers: {
286
- 'User-Agent': 'nextspark-updater',
287
- ...(process.env.GITHUB_TOKEN && {
288
- 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
289
- })
290
- }
291
- }, (res) => {
292
- // Handle redirects
293
- if (res.statusCode === 302 || res.statusCode === 301) {
294
- downloadFile(res.headers.location, dest)
295
- .then(resolve)
296
- .catch(reject)
297
- return
298
- }
299
-
300
- if (res.statusCode !== 200) {
301
- reject(new Error(`Download failed: HTTP ${res.statusCode}`))
302
- return
303
- }
304
-
305
- const file = createWriteStream(dest)
306
- pipeline(res, file)
307
- .then(resolve)
308
- .catch(reject)
309
- }).on('error', reject)
310
- })
311
- }
312
-
313
- /**
314
- * Recursively copy directory
315
- */
316
- async function copyRecursive(src, dest) {
317
- await fs.mkdir(dest, { recursive: true })
318
- const entries = await fs.readdir(src, { withFileTypes: true })
319
-
320
- for (const entry of entries) {
321
- const srcPath = path.join(src, entry.name)
322
- const destPath = path.join(dest, entry.name)
323
-
324
- if (entry.isDirectory()) {
325
- await copyRecursive(srcPath, destPath)
326
- } else {
327
- await fs.copyFile(srcPath, destPath)
328
- }
329
- }
330
- }
331
-
332
- /**
333
- * Remove directory if it exists
334
- */
335
- async function removeIfExists(dirPath) {
336
- try {
337
- await fs.rm(dirPath, { recursive: true, force: true })
338
- } catch {
339
- // Ignore errors
340
- }
341
- }
342
-
343
- /**
344
- * Copy a directory from source to target, removing target first
345
- */
346
- async function copyDirectory(sourceDir, targetDir, dirName) {
347
- const srcPath = path.join(sourceDir, dirName)
348
- const destPath = path.join(targetDir, dirName)
349
-
350
- // Check if source exists
351
- try {
352
- await fs.access(srcPath)
353
- } catch {
354
- console.log(` Skipped ${dirName}/ (not in source)`)
355
- return 0
356
- }
357
-
358
- // Remove existing and copy new
359
- await removeIfExists(destPath)
360
- await copyRecursive(srcPath, destPath)
361
-
362
- // Count files
363
- let count = 0
364
- async function countFiles(dir) {
365
- const entries = await fs.readdir(dir, { withFileTypes: true })
366
- for (const entry of entries) {
367
- if (entry.isDirectory()) {
368
- await countFiles(path.join(dir, entry.name))
369
- } else {
370
- count++
371
- }
372
- }
373
- }
374
- await countFiles(destPath)
375
-
376
- return count
377
- }
378
-
379
- /**
380
- * Copy root files from source to target
381
- */
382
- async function copyRootFiles(sourceDir, targetDir) {
383
- let copied = 0
384
- let skipped = 0
385
-
386
- for (const fileName of ROOT_FILES_TO_COPY) {
387
- const srcPath = path.join(sourceDir, fileName)
388
- const destPath = path.join(targetDir, fileName)
389
-
390
- try {
391
- await fs.access(srcPath)
392
- await fs.copyFile(srcPath, destPath)
393
- copied++
394
- } catch {
395
- skipped++
396
- }
397
- }
398
-
399
- return { copied, skipped }
400
- }
401
-
402
- /**
403
- * Copy only the default theme
404
- */
405
- async function copyDefaultTheme(sourceDir, targetDir) {
406
- const srcPath = path.join(sourceDir, 'contents', 'themes', CORE_THEME)
407
- const destPath = path.join(targetDir, 'contents', 'themes', CORE_THEME)
408
-
409
- try {
410
- await fs.access(srcPath)
411
- } catch {
412
- console.log(` Skipped theme/${CORE_THEME} (not in source)`)
413
- return 0
414
- }
415
-
416
- await removeIfExists(destPath)
417
- await copyRecursive(srcPath, destPath)
418
-
419
- // Count files
420
- let count = 0
421
- async function countFiles(dir) {
422
- const entries = await fs.readdir(dir, { withFileTypes: true })
423
- for (const entry of entries) {
424
- if (entry.isDirectory()) {
425
- await countFiles(path.join(dir, entry.name))
426
- } else {
427
- count++
428
- }
429
- }
430
- }
431
- await countFiles(destPath)
432
-
433
- return count
434
- }
435
-
436
- /**
437
- * Copy core plugins
438
- */
439
- async function copyCorePlugins(sourceDir, targetDir) {
440
- let totalFiles = 0
441
- const copied = []
442
- const skipped = []
443
-
444
- for (const pluginName of CORE_PLUGINS) {
445
- const srcPath = path.join(sourceDir, 'contents', 'plugins', pluginName)
446
- const destPath = path.join(targetDir, 'contents', 'plugins', pluginName)
447
-
448
- try {
449
- await fs.access(srcPath)
450
- } catch {
451
- skipped.push(pluginName)
452
- continue
453
- }
454
-
455
- await removeIfExists(destPath)
456
- await copyRecursive(srcPath, destPath)
457
- copied.push(pluginName)
458
-
459
- // Count files
460
- async function countFiles(dir) {
461
- const entries = await fs.readdir(dir, { withFileTypes: true })
462
- for (const entry of entries) {
463
- if (entry.isDirectory()) {
464
- await countFiles(path.join(dir, entry.name))
465
- } else {
466
- totalFiles++
467
- }
468
- }
469
- }
470
- await countFiles(destPath)
471
- }
472
-
473
- return { totalFiles, copied, skipped }
474
- }
475
-
476
- /**
477
- * Check for new database migrations
478
- */
479
- async function checkNewMigrations(projectRoot) {
480
- const migrationsDir = path.join(projectRoot, 'core', 'migrations')
481
-
482
- try {
483
- const files = await fs.readdir(migrationsDir)
484
- const sqlFiles = files.filter(f => f.endsWith('.sql')).sort()
485
- return sqlFiles
486
- } catch {
487
- return []
488
- }
489
- }
490
-
491
- /**
492
- * List available releases from GitHub
493
- */
494
- async function listReleases() {
495
- const currentVersion = await getCurrentVersion()
496
- const CORE_REPO = await getCoreRepository()
497
-
498
- console.log('Fetching available releases...\n')
499
-
500
- const response = await fetch(
501
- `https://api.github.com/repos/${CORE_REPO}/releases`,
502
- {
503
- headers: {
504
- 'User-Agent': 'nextspark-updater',
505
- ...(process.env.GITHUB_TOKEN && {
506
- 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`
507
- })
508
- }
509
- }
510
- )
511
-
512
- if (!response.ok) {
513
- throw new Error(`Failed to fetch releases: HTTP ${response.status}`)
514
- }
515
-
516
- const releases = await response.json()
517
-
518
- console.log('Available releases:\n')
519
- releases.forEach((release, index) => {
520
- const isLatest = index === 0 ? ' (latest)' : ''
521
- const isCurrent = release.tag_name === currentVersion ? ' <- installed' : ''
522
- const date = new Date(release.published_at).toLocaleDateString()
523
- console.log(` ${release.tag_name}${isLatest}${isCurrent} - ${date}`)
524
- })
525
- }
526
-
527
- /**
528
- * Check if updates are available
529
- */
530
- async function checkUpdates() {
531
- const current = await getCurrentVersion()
532
- const latestInfo = await fetchReleaseInfo('latest')
533
-
534
- // Normalize versions for comparison (remove 'v' prefix if present)
535
- const currentNormalized = current.replace(/^v/, '')
536
- const latestNormalized = latestInfo.tag_name.replace(/^v/, '')
537
-
538
- console.log(`Current: ${current}`)
539
- console.log(`Latest: ${latestInfo.tag_name}`)
540
-
541
- if (currentNormalized !== latestNormalized) {
542
- console.log(`\nUpdate available! Run: pnpm update-core`)
543
- } else {
544
- console.log(`\nYou're up to date!`)
545
- }
546
- }
547
-
548
- /**
549
- * Show current version
550
- */
551
- async function showVersion() {
552
- const versionInfo = await getVersionInfo()
553
-
554
- if (versionInfo.updatedAt) {
555
- const date = new Date(versionInfo.updatedAt).toLocaleDateString()
556
- console.log(`Core ${versionInfo.version} (updated ${date})`)
557
- } else {
558
- console.log(`Core ${versionInfo.version}`)
559
- }
560
- }
561
-
562
- /**
563
- * Show help message
564
- */
565
- function showHelp() {
566
- console.log(`
567
- NextSpark Core Updater v3.0
568
-
569
- Usage:
570
- pnpm update-core [options]
571
-
572
- Options:
573
- --version <version> Update to specific version (e.g., v2.0.0)
574
- --latest Update to latest version (default)
575
- --branch, -b Create update branch before applying changes
576
- --list List available releases
577
- --check Check for updates
578
- --current Show current version
579
- --help, -h Show this help message
580
-
581
- What gets updated:
582
- /core/ Core framework (complete overwrite)
583
- /app/ App routes and pages (complete overwrite)
584
- /.rules/ Development rules (complete overwrite)
585
- /contents/themes/default/ Default theme only
586
- /contents/plugins/{core}/ Core plugins: ${CORE_PLUGINS.join(', ')}
587
- Root config files middleware.ts, next.config.ts, package.json, etc.
588
-
589
- What is preserved:
590
- .env* Environment files
591
- .claude/ Claude workflow
592
- supabase/ Local database
593
- public/uploads/ User uploads
594
- CLAUDE.md, README.md Project documentation
595
- /contents/themes/* Custom themes (except default)
596
- /contents/plugins/* Custom plugins (except core)
597
-
598
- Examples:
599
- pnpm update-core # Update to latest
600
- pnpm update-core --branch # Update in new branch
601
- pnpm update-core --version v2.5.0 # Specific version
602
- pnpm update-core --list # List releases
603
- pnpm update-core --check # Check for updates
604
- `)
605
- process.exit(0)
24
+ try {
25
+ process.exitCode = await updateCore(process.argv.slice(2))
26
+ } catch (error) {
27
+ // Only reachable before the first write: from there on updateCore reports its own failures
28
+ console.error(`\nUpdate failed: ${error.message}`)
29
+ process.exitCode = 1
606
30
  }
607
-
608
- // ==================== MAIN UPDATE FUNCTION ====================
609
-
610
- async function updateCore() {
611
- const args = process.argv.slice(2)
612
- const flags = parseArguments(args)
613
-
614
- // Handle info commands
615
- if (flags.help) return showHelp()
616
- if (flags.list) return listReleases()
617
- if (flags.check) return checkUpdates()
618
- if (flags.current) return showVersion()
619
-
620
- console.log('\n========================================')
621
- console.log(' NextSpark Core Updater v3.0')
622
- console.log('========================================\n')
623
-
624
- const projectRoot = process.cwd()
625
-
626
- // 1. Pre-flight checks
627
- console.log('[1/9] Pre-flight checks...')
628
- try {
629
- await fs.access(path.join(projectRoot, 'package.json'))
630
- console.log(' Found package.json')
631
- } catch {
632
- console.error(' ERROR: No package.json found. Run from project root.')
633
- process.exit(1)
634
- }
635
-
636
- // Ensure version file exists
637
- await ensureVersionFile()
638
-
639
- // Get current version
640
- const previousVersion = await getCurrentVersion()
641
- console.log(` Current version: ${previousVersion}\n`)
642
-
643
- // Check for uncommitted changes
644
- try {
645
- const status = execSync('git status --porcelain', { encoding: 'utf8' })
646
- if (status.trim()) {
647
- console.error(' ERROR: Uncommitted changes detected.')
648
- console.error(' Commit or stash your changes first.')
649
- console.error(' Run: git status')
650
- process.exit(1)
651
- }
652
- console.log(' Git status: clean')
653
- } catch (error) {
654
- console.warn(' Warning: Not a git repository\n')
655
- }
656
-
657
- // 2. Create safety snapshot
658
- console.log('\n[2/9] Creating safety snapshot...')
659
- const targetVersion = flags.version || 'latest'
660
- try {
661
- const timestamp = Date.now()
662
- execSync(
663
- `git add -A && git commit -m "Pre-update snapshot (${targetVersion})" --allow-empty`,
664
- { stdio: 'ignore' }
665
- )
666
- execSync(`git tag pre-update-${targetVersion}-${timestamp}`, { stdio: 'ignore' })
667
- console.log(` Tag: pre-update-${targetVersion}-${timestamp}`)
668
- } catch {
669
- console.log(' Skipped (not a git repo)')
670
- }
671
-
672
- // 3. Fetch release info
673
- console.log('\n[3/9] Fetching release info...')
674
- const releaseInfo = await fetchReleaseInfo(targetVersion)
675
- const publishedDate = new Date(releaseInfo.published_at).toLocaleDateString()
676
- console.log(` Version: ${releaseInfo.tag_name}`)
677
- console.log(` Published: ${publishedDate}`)
678
-
679
- // 4. Download ZIP
680
- console.log('\n[4/9] Downloading release...')
681
- const zipPath = path.join(projectRoot, '.tmp-core-update.zip')
682
- await downloadFile(releaseInfo.zipball_url, zipPath)
683
- console.log(' Downloaded')
684
-
685
- // 5. Extract
686
- console.log('\n[5/9] Extracting...')
687
- const tmpDir = path.join(projectRoot, '.tmp-core-update')
688
- await fs.mkdir(tmpDir, { recursive: true })
689
-
690
- const zip = new AdmZip(zipPath)
691
- zip.extractAllTo(tmpDir, true)
692
-
693
- const extractedDirs = await fs.readdir(tmpDir)
694
- const sourceDir = path.join(tmpDir, extractedDirs[0])
695
- console.log(' Extracted to temp directory')
696
-
697
- // 6. Create update branch if requested
698
- if (flags.branch) {
699
- console.log('\n[5.5/9] Creating update branch...')
700
-
701
- const versionSlug = releaseInfo.tag_name.replace(/^v/, '').replace(/\./g, '-')
702
- const branchName = `update/${versionSlug}`
703
-
704
- try {
705
- execSync('git rev-parse --git-dir', { stdio: 'ignore' })
706
-
707
- try {
708
- execSync(`git rev-parse --verify ${branchName}`, { stdio: 'ignore' })
709
- console.error(` ERROR: Branch '${branchName}' already exists`)
710
- console.error(` Delete it first: git branch -D ${branchName}`)
711
-
712
- await fs.rm(tmpDir, { recursive: true, force: true })
713
- await fs.rm(zipPath, { force: true })
714
- process.exit(1)
715
- } catch {
716
- // Branch doesn't exist - good
717
- }
718
-
719
- execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' })
720
- console.log(` Created branch: ${branchName}`)
721
- } catch (error) {
722
- console.error(' ERROR: Could not create git branch')
723
- await fs.rm(tmpDir, { recursive: true, force: true })
724
- await fs.rm(zipPath, { force: true })
725
- process.exit(1)
726
- }
727
- }
728
-
729
- // 7. Copy files
730
- console.log('\n[6/9] Copying files...')
731
-
732
- // Copy main directories
733
- let totalFiles = 0
734
- for (const dirName of DIRECTORIES_TO_COPY) {
735
- const count = await copyDirectory(sourceDir, projectRoot, dirName)
736
- console.log(` ${dirName}/ - ${count} files`)
737
- totalFiles += count
738
- }
739
-
740
- // Copy root files
741
- const rootFilesResult = await copyRootFiles(sourceDir, projectRoot)
742
- console.log(` Root files - ${rootFilesResult.copied} copied, ${rootFilesResult.skipped} skipped`)
743
- totalFiles += rootFilesResult.copied
744
-
745
- // Copy default theme
746
- console.log('\n[7/9] Updating theme and plugins...')
747
- const themeFiles = await copyDefaultTheme(sourceDir, projectRoot)
748
- console.log(` themes/${CORE_THEME}/ - ${themeFiles} files`)
749
- totalFiles += themeFiles
750
-
751
- // Copy core plugins
752
- const pluginsResult = await copyCorePlugins(sourceDir, projectRoot)
753
- if (pluginsResult.copied.length > 0) {
754
- console.log(` plugins/ - ${pluginsResult.copied.join(', ')} (${pluginsResult.totalFiles} files)`)
755
- }
756
- if (pluginsResult.skipped.length > 0) {
757
- console.log(` plugins/ skipped - ${pluginsResult.skipped.join(', ')} (not in source)`)
758
- }
759
- totalFiles += pluginsResult.totalFiles
760
-
761
- // 8. Cleanup temp files
762
- console.log('\n[8/9] Cleaning up...')
763
- await fs.rm(tmpDir, { recursive: true, force: true })
764
- await fs.rm(zipPath, { force: true })
765
- console.log(' Temp files removed')
766
-
767
- // 9. Post-update tasks
768
- console.log('\n[9/9] Post-update tasks...')
769
-
770
- // Clear cache
771
- await fs.rm(path.join(projectRoot, '.next'), { recursive: true, force: true }).catch(() => {})
772
- console.log(' Cache cleared')
773
-
774
- // Install dependencies
775
- console.log(' Installing dependencies...')
776
- execSync('pnpm install', { stdio: 'inherit' })
777
-
778
- // Rebuild registries
779
- console.log(' Rebuilding registries...')
780
- try {
781
- execSync('node core/scripts/build/registry.mjs --build', { stdio: 'inherit' })
782
- } catch (error) {
783
- console.error(' Warning: Registry rebuild failed')
784
- }
785
-
786
- try {
787
- execSync('pnpm docs:build', { stdio: 'ignore' })
788
- console.log(' Docs registry rebuilt')
789
- } catch {}
790
-
791
- try {
792
- execSync('node core/scripts/build/theme.mjs', { stdio: 'ignore' })
793
- console.log(' Theme assets rebuilt')
794
- } catch {}
795
-
796
- // Check migrations
797
- const migrations = await checkNewMigrations(projectRoot)
798
- if (migrations.length > 0) {
799
- console.log(`\n Database migrations found: ${migrations.length}`)
800
- console.log(' Run: pnpm db:migrate')
801
- }
802
-
803
- // Update version file
804
- console.log('\n Updating version...')
805
- await updateVersionFile(releaseInfo, previousVersion)
806
-
807
- // Final report
808
- console.log('\n========================================')
809
- console.log(' Update Complete!')
810
- console.log('========================================')
811
- console.log(`\n ${previousVersion} -> ${releaseInfo.tag_name}`)
812
- console.log(` ${totalFiles} files updated`)
813
-
814
- if (flags.branch) {
815
- const versionSlug = releaseInfo.tag_name.replace(/^v/, '').replace(/\./g, '-')
816
- const branchName = `update/${versionSlug}`
817
- console.log(`\n Branch: ${branchName}`)
818
- console.log('\n Next steps:')
819
- console.log(` 1. Review: git diff main..${branchName}`)
820
- console.log(' 2. Test: pnpm dev')
821
- if (migrations.length > 0) {
822
- console.log(' 3. Migrate: pnpm db:migrate')
823
- console.log(` 4. Merge: git checkout main && git merge ${branchName}`)
824
- } else {
825
- console.log(` 3. Merge: git checkout main && git merge ${branchName}`)
826
- }
827
- console.log(`\n Rollback: git checkout main && git branch -D ${branchName}`)
828
- } else {
829
- console.log('\n Next steps:')
830
- console.log(' 1. Review: git diff HEAD~1')
831
- console.log(' 2. Test: pnpm dev')
832
- if (migrations.length > 0) {
833
- console.log(' 3. Migrate: pnpm db:migrate')
834
- }
835
- console.log('\n Rollback: git reset --hard HEAD~1 && pnpm install')
836
- }
837
-
838
- console.log('')
839
- }
840
-
841
- // ==================== CLI ENTRY POINT ====================
842
-
843
- updateCore().catch(error => {
844
- console.error('\nUpdate failed:', error.message)
845
- console.error('\nRollback: git reset --hard HEAD~1 && pnpm install')
846
- process.exit(1)
847
- })