@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.
- package/dist/components/api/keys/CreateApiKeyDialog.d.ts.map +1 -1
- package/dist/components/api/keys/CreateApiKeyDialog.js +2 -1
- package/dist/components/app/layouts/PublicFooter.d.ts.map +1 -1
- package/dist/components/app/layouts/PublicFooter.js +2 -23
- package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
- package/dist/components/app/misc/ThemeToggle.js +2 -1
- package/dist/components/auth/forms/LoginForm.js +1 -1
- package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
- package/dist/components/auth/forms/SignupForm.js +2 -1
- package/dist/components/auth/pages/AuthErrorPage.d.ts.map +1 -1
- package/dist/components/auth/pages/AuthErrorPage.js +2 -1
- package/dist/components/billing/ManageBillingButton.d.ts.map +1 -1
- package/dist/components/billing/ManageBillingButton.js +2 -1
- package/dist/components/dashboard/block-editor/array-field.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/array-field.js +2 -1
- package/dist/components/dashboard/block-editor/block-picker.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/block-picker.js +2 -1
- package/dist/components/dashboard/block-editor/builder-editor-view.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/builder-editor-view.js +3 -2
- package/dist/components/dashboard/block-editor/config-panel.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/config-panel.js +3 -2
- package/dist/components/dashboard/block-editor/dynamic-form.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/dynamic-form.js +2 -1
- package/dist/components/dashboard/block-editor/entity-fields-sidebar.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/entity-fields-sidebar.js +3 -2
- package/dist/components/dashboard/block-editor/pattern-reference-preview.d.ts.map +1 -1
- package/dist/components/dashboard/block-editor/pattern-reference-preview.js +2 -1
- package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/TopNavbar.js +4 -3
- package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/SearchDropdown.js +2 -1
- package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +2 -1
- package/dist/components/devtools/BlockDetailViewer.d.ts.map +1 -1
- package/dist/components/devtools/BlockDetailViewer.js +2 -1
- package/dist/components/devtools/BlocksViewer.d.ts.map +1 -1
- package/dist/components/devtools/BlocksViewer.js +2 -1
- package/dist/components/devtools/ConfigViewer.d.ts.map +1 -1
- package/dist/components/devtools/ConfigViewer.js +3 -2
- package/dist/components/devtools/TestCasesViewer.d.ts.map +1 -1
- package/dist/components/devtools/TestCasesViewer.js +3 -2
- package/dist/components/devtools/TestCoverageDashboard.d.ts.map +1 -1
- package/dist/components/devtools/TestCoverageDashboard.js +2 -1
- package/dist/components/devtools/api-explorer/ApiDocsModal.d.ts.map +1 -1
- package/dist/components/devtools/api-explorer/ApiDocsModal.js +0 -0
- package/dist/components/devtools/api-explorer/ApiExplorer.d.ts.map +1 -1
- package/dist/components/devtools/api-explorer/ApiExplorer.js +2 -1
- package/dist/components/devtools/scheduled-actions/actions-table.d.ts.map +1 -1
- package/dist/components/devtools/scheduled-actions/actions-table.js +3 -2
- package/dist/components/docs/docs-sidebar.d.ts.map +1 -1
- package/dist/components/docs/docs-sidebar.js +3 -2
- package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
- package/dist/components/entities/EntityFieldRenderer.js +2 -1
- package/dist/components/entities/EntityList.d.ts.map +1 -1
- package/dist/components/entities/EntityList.js +2 -1
- package/dist/components/entities/EntityTable.d.ts.map +1 -1
- package/dist/components/entities/EntityTable.js +3 -2
- package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/entities/ErrorBoundary.js +2 -1
- package/dist/components/entities/wrappers/EntityDetailWrapper.d.ts.map +1 -1
- package/dist/components/entities/wrappers/EntityDetailWrapper.js +3 -2
- package/dist/components/media/MediaCard.d.ts.map +1 -1
- package/dist/components/media/MediaCard.js +2 -1
- package/dist/components/media/MediaDetailPanel.d.ts.map +1 -1
- package/dist/components/media/MediaDetailPanel.js +2 -1
- package/dist/components/media/MediaList.d.ts.map +1 -1
- package/dist/components/media/MediaList.js +2 -1
- package/dist/components/media/MediaSelector.d.ts.map +1 -1
- package/dist/components/media/MediaSelector.js +2 -1
- package/dist/components/media/MediaUploadZone.d.ts.map +1 -1
- package/dist/components/media/MediaUploadZone.js +2 -1
- package/dist/components/public/entities/PublicEntityDetail.d.ts.map +1 -1
- package/dist/components/public/entities/PublicEntityDetail.js +2 -1
- package/dist/components/teams/TeamPendingInvitations.d.ts.map +1 -1
- package/dist/components/teams/TeamPendingInvitations.js +3 -2
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/audio-upload.d.ts.map +1 -1
- package/dist/components/ui/audio-upload.js +2 -1
- package/dist/components/ui/avatar.d.ts +17 -1
- package/dist/components/ui/avatar.d.ts.map +1 -1
- package/dist/components/ui/avatar.js +29 -2
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/breadcrumb.d.ts +13 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -1
- package/dist/components/ui/breadcrumb.js +23 -10
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/file-upload.d.ts.map +1 -1
- package/dist/components/ui/file-upload.js +2 -1
- package/dist/components/ui/image-upload.d.ts.map +1 -1
- package/dist/components/ui/image-upload.js +4 -3
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/optimized-image.d.ts.map +1 -1
- package/dist/components/ui/optimized-image.js +5 -0
- package/dist/components/ui/pagination.d.ts +1 -1
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/pagination.js +3 -0
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/relation-display.d.ts.map +1 -1
- package/dist/components/ui/relation-display.js +3 -2
- package/dist/components/ui/separator.js +1 -1
- package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
- package/dist/components/ui/simple-relation-select.js +7 -6
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/tabs.js +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/user-display.d.ts.map +1 -1
- package/dist/components/ui/user-display.js +2 -1
- package/dist/components/ui/user-select.d.ts.map +1 -1
- package/dist/components/ui/user-select.js +2 -1
- package/dist/components/ui/video-upload.d.ts.map +1 -1
- package/dist/components/ui/video-upload.js +3 -2
- package/dist/components/users/tables/UsersTable.d.ts.map +1 -1
- package/dist/components/users/tables/UsersTable.js +3 -2
- package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
- package/dist/contexts/SubscriptionContext.js +4 -3
- package/dist/contexts/TeamContext.d.ts.map +1 -1
- package/dist/contexts/TeamContext.js +3 -2
- package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -1
- package/dist/hooks/useAccountPreferencesSync.js +2 -1
- package/dist/hooks/useApiExplorerNavigation.d.ts.map +1 -1
- package/dist/hooks/useApiExplorerNavigation.js +2 -1
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +3 -2
- package/dist/hooks/useEnsureUserMetadata.d.ts.map +1 -1
- package/dist/hooks/useEnsureUserMetadata.js +3 -2
- package/dist/hooks/useEntityWithMeta.d.ts.map +1 -1
- package/dist/hooks/useEntityWithMeta.js +3 -2
- package/dist/hooks/useInvoice.d.ts.map +1 -1
- package/dist/hooks/useInvoice.js +2 -1
- package/dist/hooks/useInvoices.d.ts.map +1 -1
- package/dist/hooks/useInvoices.js +2 -1
- package/dist/hooks/useMedia.d.ts.map +1 -1
- package/dist/hooks/useMedia.js +10 -9
- package/dist/hooks/useMediaUpload.d.ts.map +1 -1
- package/dist/hooks/useMediaUpload.js +2 -1
- package/dist/hooks/useMembership.d.ts.map +1 -1
- package/dist/hooks/useMembership.js +3 -2
- package/dist/hooks/usePatternUsages.d.ts.map +1 -1
- package/dist/hooks/usePatternUsages.js +3 -2
- package/dist/hooks/usePrefetch.d.ts.map +1 -1
- package/dist/hooks/usePrefetch.js +3 -2
- package/dist/hooks/useQuota.d.ts.map +1 -1
- package/dist/hooks/useQuota.js +2 -1
- package/dist/hooks/useTeamInvitations.d.ts.map +1 -1
- package/dist/hooks/useTeamInvitations.js +4 -3
- package/dist/hooks/useTeamMembers.d.ts.map +1 -1
- package/dist/hooks/useTeamMembers.js +5 -4
- package/dist/hooks/useTeamUpdate.d.ts.map +1 -1
- package/dist/hooks/useTeamUpdate.js +2 -1
- package/dist/hooks/useUserProfile.d.ts.map +1 -1
- package/dist/hooks/useUserProfile.js +3 -2
- package/dist/hooks/useUserSettings.d.ts.map +1 -1
- package/dist/hooks/useUserSettings.js +3 -2
- package/dist/lib/actions/entity.actions.d.ts.map +1 -1
- package/dist/lib/actions/entity.actions.js +2 -1
- package/dist/lib/api/entities.d.ts.map +1 -1
- package/dist/lib/api/entities.js +4 -3
- package/dist/lib/auth/verify-email-link.d.ts +10 -0
- package/dist/lib/auth/verify-email-link.d.ts.map +1 -0
- package/dist/lib/auth/verify-email-link.js +14 -0
- package/dist/lib/auth-client.d.ts +2 -0
- package/dist/lib/auth-client.d.ts.map +1 -1
- package/dist/lib/auth-client.js +4 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +10 -2
- package/dist/lib/base-path.d.ts +85 -0
- package/dist/lib/base-path.d.ts.map +1 -0
- package/dist/lib/base-path.js +79 -0
- package/dist/lib/billing/schema.d.ts +1 -1
- package/dist/lib/billing/schema.d.ts.map +1 -1
- package/dist/lib/billing/schema.js +1 -1
- package/dist/lib/blocks/sanitize-html.d.ts.map +1 -1
- package/dist/lib/blocks/sanitize-html.js +18 -2
- package/dist/lib/cache/revalidate-tag.d.ts +14 -0
- package/dist/lib/cache/revalidate-tag.d.ts.map +1 -0
- package/dist/lib/cache/revalidate-tag.js +8 -0
- package/dist/lib/config/dashboard-schema.d.ts +1 -1
- package/dist/lib/config/dashboard-schema.d.ts.map +1 -1
- package/dist/lib/config/dashboard-schema.js +1 -1
- package/dist/lib/config/types.d.ts +36 -16
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/docs/access.d.ts +28 -0
- package/dist/lib/docs/access.d.ts.map +1 -0
- package/dist/lib/docs/access.js +16 -0
- package/dist/lib/docs/parser.d.ts.map +1 -1
- package/dist/lib/docs/parser.js +2 -1
- package/dist/lib/docs/remark-doc-links.d.ts +14 -0
- package/dist/lib/docs/remark-doc-links.d.ts.map +1 -0
- package/dist/lib/docs/remark-doc-links.js +38 -0
- package/dist/lib/entities/api-generator.d.ts +1 -1
- package/dist/lib/entities/api-generator.d.ts.map +1 -1
- package/dist/lib/entities/api-generator.js +1 -1
- package/dist/lib/entities/schema-generator.d.ts +1 -1
- package/dist/lib/entities/schema-generator.d.ts.map +1 -1
- package/dist/lib/entities/schema-generator.js +1 -1
- package/dist/lib/mcp/engine.js +1 -1
- package/dist/lib/mcp/schema-builder.d.ts +1 -1
- package/dist/lib/mcp/schema-builder.d.ts.map +1 -1
- package/dist/lib/mcp/schema-builder.js +1 -1
- package/dist/lib/mcp/tool-generator.js +1 -1
- package/dist/lib/mcp/types.d.ts +1 -1
- package/dist/lib/mcp/types.d.ts.map +1 -1
- package/dist/lib/media/schemas.d.ts +1 -1
- package/dist/lib/media/schemas.d.ts.map +1 -1
- package/dist/lib/media/schemas.js +1 -1
- package/dist/lib/middleware/index.d.ts +5 -1
- package/dist/lib/middleware/index.d.ts.map +1 -1
- package/dist/lib/middleware/index.js +3 -2
- package/dist/lib/services/meta.service.d.ts +60 -0
- package/dist/lib/services/meta.service.d.ts.map +1 -1
- package/dist/lib/services/meta.service.js +132 -12
- package/dist/lib/services/middleware.service.d.ts.map +1 -1
- package/dist/lib/services/middleware.service.js +3 -2
- package/dist/lib/teams/schema.d.ts +1 -1
- package/dist/lib/teams/schema.d.ts.map +1 -1
- package/dist/lib/teams/schema.js +1 -1
- package/dist/lib/teams/teams.api.d.ts.map +1 -1
- package/dist/lib/teams/teams.api.js +4 -3
- package/dist/lib/user-data-client.d.ts.map +1 -1
- package/dist/lib/user-data-client.js +3 -2
- package/dist/lib/validation/invoices.d.ts +1 -1
- package/dist/lib/validation/invoices.d.ts.map +1 -1
- package/dist/lib/validation/invoices.js +1 -1
- package/dist/lib/validation-schemas.d.ts +1 -1
- package/dist/lib/validation-schemas.d.ts.map +1 -1
- package/dist/lib/validation-schemas.js +1 -1
- package/dist/lib/validation.d.ts +1 -1
- package/dist/lib/validation.d.ts.map +1 -1
- package/dist/lib/validation.js +1 -1
- package/dist/messages/de/footer.json +0 -1
- package/dist/messages/de/index.d.ts +0 -1
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/en/footer.json +0 -1
- package/dist/messages/en/index.d.ts +0 -1
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/es/footer.json +0 -1
- package/dist/messages/es/index.d.ts +0 -1
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/fr/footer.json +0 -1
- package/dist/messages/fr/index.d.ts +0 -1
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/it/footer.json +0 -1
- package/dist/messages/it/index.d.ts +0 -1
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/pt/footer.json +0 -1
- package/dist/messages/pt/index.d.ts +0 -1
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -3
- package/dist/templates/app/(auth)/verify-email/page.tsx +4 -3
- package/dist/templates/app/(public)/docs/[section]/[page]/page.tsx +11 -0
- package/dist/templates/app/api/auth/[...all]/route.ts +15 -14
- package/dist/templates/app/api/internal/user-metadata/route.ts +6 -8
- package/dist/templates/app/api/user/plan-flags/route.ts +1 -1
- package/dist/templates/app/api/user/profile/route.ts +12 -17
- package/dist/templates/app/api/v1/api-keys/route.ts +1 -1
- package/dist/templates/app/api/v1/auth/signup-with-invite/route.ts +2 -1
- package/dist/templates/app/api/v1/billing/cancel/route.ts +1 -1
- package/dist/templates/app/api/v1/billing/change-plan/route.ts +1 -1
- package/dist/templates/app/api/v1/billing/check-action/route.ts +1 -1
- package/dist/templates/app/api/v1/billing/checkout/route.ts +1 -1
- package/dist/templates/app/api/v1/blocks/validate/route.ts +1 -1
- package/dist/templates/app/api/v1/media/[id]/tags/route.ts +1 -1
- package/dist/templates/app/api/v1/post-categories/[id]/route.ts +1 -1
- package/dist/templates/app/api/v1/post-categories/route.ts +1 -1
- package/dist/templates/app/api/v1/teams/[teamId]/members/route.ts +2 -1
- package/dist/templates/app/api/v1/teams/[teamId]/subscription/route.ts +3 -5
- package/dist/templates/app/api/v1/teams/docs.md +4 -9
- package/dist/templates/app/api/v1/teams/switch/route.ts +1 -1
- package/dist/templates/app/api/v1/users/[id]/meta/[key]/route.ts +1 -1
- package/dist/templates/app/api/v1/users/[id]/route.ts +1 -1
- package/dist/templates/app/api/v1/users/route.ts +1 -1
- package/dist/templates/app/dashboard/(main)/media/page.tsx +3 -1
- package/dist/templates/app/dashboard/settings/api-keys/page.tsx +5 -4
- package/dist/templates/app/dashboard/settings/profile/page.tsx +3 -2
- package/dist/templates/app/devtools/scheduled-actions/page.tsx +2 -1
- package/dist/templates/app/superadmin/docs/[section]/[page]/page.tsx +16 -0
- package/dist/templates/app/superadmin/subscriptions/page.tsx +3 -2
- package/dist/templates/app/superadmin/teams/[teamId]/page.tsx +5 -4
- package/dist/templates/app/superadmin/users/[userId]/page.tsx +2 -1
- package/dist/templates/app/superadmin/users/page.tsx +2 -1
- package/dist/templates/blocks/cta-section/component.tsx +3 -2
- package/dist/templates/blocks/cta-section/schema.ts +1 -1
- package/dist/templates/blocks/features-grid/component.tsx +2 -1
- package/dist/templates/blocks/features-grid/schema.ts +1 -1
- package/dist/templates/blocks/hero/component.tsx +3 -2
- package/dist/templates/blocks/hero/schema.ts +1 -1
- package/dist/templates/blocks/testimonials/component.tsx +2 -1
- package/dist/templates/blocks/testimonials/schema.ts +1 -1
- package/dist/templates/blocks/text-content/component.tsx +2 -1
- package/dist/templates/blocks/text-content/schema.ts +1 -1
- package/dist/templates/ci-workflows/README.md +1 -1
- package/dist/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/dist/templates/ci-workflows/github/cypress-smoke.yml +1 -1
- package/dist/templates/contents/plugins/starter/plugin/api/example/route.ts.template +1 -1
- package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +3 -2
- package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +1 -1
- package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +2 -1
- package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +1 -1
- package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +3 -2
- package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +1 -1
- package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +3 -2
- package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +1 -1
- package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +2 -1
- package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +1 -1
- package/dist/templates/contents/themes/starter/entities/posts/components/post-header.tsx +2 -1
- package/dist/templates/contents/themes/starter/lib/hooks/useAnalyticsData.ts +2 -1
- package/dist/templates/contents/themes/starter/lib/hooks/useTaskStats.ts +2 -1
- package/dist/templates/eslint.config.mjs +133 -9
- package/dist/templates/features/blog/blocks/post-content/component.tsx +2 -1
- package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/dist/templates/features/blog/entities/posts/components/post-header.tsx +2 -1
- package/dist/templates/features/pages/blocks/hero/component.tsx +3 -2
- package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/dist/templates/next.config.mjs +50 -29
- package/dist/templates/proxy.ts +100 -21
- package/dist/templates/public/sw.js +2 -2
- package/dist/templates/scripts/cy-run-prod.cjs +5 -5
- package/dist/types/blocks.d.ts +1 -1
- package/dist/types/blocks.d.ts.map +1 -1
- package/dist/types/blocks.js +1 -1
- package/package.json +9 -5
- package/scripts/build/docs-registry.mjs +7 -7
- package/scripts/build/registry/__tests__/billing-registry.test.mjs +43 -0
- package/scripts/build/registry/__tests__/build-output.test.mjs +209 -0
- package/scripts/build/registry/__tests__/copy-race-child.mjs +14 -0
- package/scripts/build/registry/__tests__/direct-fs-writes.mjs +203 -0
- package/scripts/build/registry/__tests__/globals-css-tag.test.mjs +66 -0
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +530 -29
- package/scripts/build/registry/__tests__/page-generator.test.mjs +211 -37
- package/scripts/build/registry/__tests__/published-signatures.test.mjs +239 -0
- package/scripts/build/registry/__tests__/route-file-rule.test.mjs +170 -0
- package/scripts/build/registry/__tests__/safe-fs.test.mjs +333 -0
- package/scripts/build/registry/__tests__/template-analysis.test.mjs +142 -0
- package/scripts/build/registry/__tests__/template-registry.test.mjs +279 -9
- package/scripts/build/registry/__tests__/templates-plan.test.mjs +128 -0
- package/scripts/build/registry/__tests__/templates-tree.test.mjs +367 -0
- package/scripts/build/registry/__tests__/write-places.test.mjs +425 -0
- package/scripts/build/registry/config.mjs +6 -65
- package/scripts/build/registry/discovery/icons.mjs +498 -43
- package/scripts/build/registry/discovery/templates.mjs +1 -1
- package/scripts/build/registry/generators/billing-registry.mjs +1 -1
- package/scripts/build/registry/generators/docs-registry.mjs +3 -4
- package/scripts/build/registry/generators/feature-registry.mjs +1 -1
- package/scripts/build/registry/generators/permissions-registry.mjs +2 -2
- package/scripts/build/registry/generators/template-registry.mjs +65 -49
- package/scripts/build/registry/index.mjs +1 -2
- package/scripts/build/registry/post-build/index.mjs +1 -1
- package/scripts/build/registry/post-build/own-gitignores.mjs +220 -0
- package/scripts/build/registry/post-build/page-generator.mjs +512 -268
- package/scripts/build/registry/post-build/route-cleanup.mjs +16 -13
- package/scripts/build/registry/post-build/test-fixtures.mjs +26 -8
- package/scripts/build/registry/project-mode.mjs +76 -0
- package/scripts/build/registry/shared/typescript-compiler.mjs +77 -0
- package/scripts/build/registry/validate-env.test.mjs +12 -8
- package/scripts/build/registry/watch.mjs +3 -53
- package/scripts/build/registry/write-places.mjs +228 -0
- package/scripts/build/registry.mjs +53 -30
- package/scripts/build/safe-fs.mjs +279 -0
- package/scripts/build/templates-plan.mjs +44 -0
- package/scripts/build/theme.mjs +46 -42
- package/scripts/build/update-tsconfig.mjs +16 -15
- package/scripts/db/cluster-changes.mjs +205 -0
- package/scripts/db/connection-time-limits.mjs +53 -0
- package/scripts/db/inspect-server.mjs +108 -0
- package/scripts/db/migration-time-limit.mjs +695 -0
- package/scripts/db/run-migrations.mjs +46 -41
- package/scripts/db/ssl-config.mjs +194 -0
- package/scripts/db/theme-location.mjs +69 -0
- package/scripts/db/verify-tables.mjs +3 -8
- package/scripts/db/verify-teams.mjs +2 -6
- package/scripts/db/verify-theme-migrations.mjs +169 -0
- package/scripts/maintenance/core-updater.mjs +1003 -0
- package/scripts/maintenance/step-guard.mjs +74 -0
- package/scripts/maintenance/update-core.mjs +14 -831
- package/scripts/utils/console-guard.mjs +13 -0
- package/scripts/utils/generated-tag.mjs +66 -0
- package/scripts/utils/index.mjs +9 -1
- package/scripts/utils/logging.mjs +140 -0
- package/templates/app/(auth)/accept-invite/[token]/page.tsx +4 -3
- package/templates/app/(auth)/verify-email/page.tsx +4 -3
- package/templates/app/(public)/docs/[section]/[page]/page.tsx +11 -0
- package/templates/app/api/auth/[...all]/route.ts +15 -14
- package/templates/app/api/internal/user-metadata/route.ts +6 -8
- package/templates/app/api/user/plan-flags/route.ts +1 -1
- package/templates/app/api/user/profile/route.ts +12 -17
- package/templates/app/api/v1/api-keys/route.ts +1 -1
- package/templates/app/api/v1/auth/signup-with-invite/route.ts +2 -1
- package/templates/app/api/v1/billing/cancel/route.ts +1 -1
- package/templates/app/api/v1/billing/change-plan/route.ts +1 -1
- package/templates/app/api/v1/billing/check-action/route.ts +1 -1
- package/templates/app/api/v1/billing/checkout/route.ts +1 -1
- package/templates/app/api/v1/blocks/validate/route.ts +1 -1
- package/templates/app/api/v1/media/[id]/tags/route.ts +1 -1
- package/templates/app/api/v1/post-categories/[id]/route.ts +1 -1
- package/templates/app/api/v1/post-categories/route.ts +1 -1
- package/templates/app/api/v1/teams/[teamId]/members/route.ts +2 -1
- package/templates/app/api/v1/teams/[teamId]/subscription/route.ts +3 -5
- package/templates/app/api/v1/teams/docs.md +4 -9
- package/templates/app/api/v1/teams/switch/route.ts +1 -1
- package/templates/app/api/v1/users/[id]/meta/[key]/route.ts +1 -1
- package/templates/app/api/v1/users/[id]/route.ts +1 -1
- package/templates/app/api/v1/users/route.ts +1 -1
- package/templates/app/dashboard/(main)/media/page.tsx +3 -1
- package/templates/app/dashboard/settings/api-keys/page.tsx +5 -4
- package/templates/app/dashboard/settings/profile/page.tsx +3 -2
- package/templates/app/devtools/scheduled-actions/page.tsx +2 -1
- package/templates/app/superadmin/docs/[section]/[page]/page.tsx +16 -0
- package/templates/app/superadmin/subscriptions/page.tsx +3 -2
- package/templates/app/superadmin/teams/[teamId]/page.tsx +5 -4
- package/templates/app/superadmin/users/[userId]/page.tsx +2 -1
- package/templates/app/superadmin/users/page.tsx +2 -1
- package/templates/blocks/cta-section/component.tsx +3 -2
- package/templates/blocks/cta-section/schema.ts +1 -1
- package/templates/blocks/features-grid/component.tsx +2 -1
- package/templates/blocks/features-grid/schema.ts +1 -1
- package/templates/blocks/hero/component.tsx +3 -2
- package/templates/blocks/hero/schema.ts +1 -1
- package/templates/blocks/testimonials/component.tsx +2 -1
- package/templates/blocks/testimonials/schema.ts +1 -1
- package/templates/blocks/text-content/component.tsx +2 -1
- package/templates/blocks/text-content/schema.ts +1 -1
- package/templates/ci-workflows/README.md +1 -1
- package/templates/ci-workflows/github/cypress-regression.yml +1 -1
- package/templates/ci-workflows/github/cypress-smoke.yml +1 -1
- package/templates/contents/plugins/starter/plugin/api/example/route.ts.template +1 -1
- package/templates/contents/themes/starter/blocks/cta-section/component.tsx +3 -2
- package/templates/contents/themes/starter/blocks/cta-section/schema.ts +1 -1
- package/templates/contents/themes/starter/blocks/features-grid/component.tsx +2 -1
- package/templates/contents/themes/starter/blocks/features-grid/schema.ts +1 -1
- package/templates/contents/themes/starter/blocks/hero/component.tsx +3 -2
- package/templates/contents/themes/starter/blocks/hero/schema.ts +1 -1
- package/templates/contents/themes/starter/blocks/testimonials/component.tsx +3 -2
- package/templates/contents/themes/starter/blocks/testimonials/schema.ts +1 -1
- package/templates/contents/themes/starter/blocks/text-content/component.tsx +2 -1
- package/templates/contents/themes/starter/blocks/text-content/schema.ts +1 -1
- package/templates/contents/themes/starter/entities/posts/components/post-header.tsx +2 -1
- package/templates/contents/themes/starter/lib/hooks/useAnalyticsData.ts +2 -1
- package/templates/contents/themes/starter/lib/hooks/useTaskStats.ts +2 -1
- package/templates/eslint.config.mjs +133 -9
- package/templates/features/blog/blocks/post-content/component.tsx +2 -1
- package/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/templates/features/blog/entities/posts/components/post-header.tsx +2 -1
- package/templates/features/pages/blocks/hero/component.tsx +3 -2
- package/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/templates/next.config.mjs +50 -29
- package/templates/proxy.ts +100 -21
- package/templates/public/sw.js +2 -2
- package/templates/scripts/cy-run-prod.cjs +5 -5
- package/tests/jest/__mocks__/@nextsparkjs/registries/template-registry.client.ts +11 -0
- package/tests/jest/__mocks__/next-server.js +10 -0
- package/scripts/build/docs.mjs +0 -392
|
@@ -12,6 +12,7 @@ import { join, dirname } from 'path'
|
|
|
12
12
|
import { fileURLToPath } from 'url'
|
|
13
13
|
|
|
14
14
|
import { log, verbose } from '../../../utils/index.mjs'
|
|
15
|
+
import { isUnsafeWrite, projectFiles } from '../../safe-fs.mjs'
|
|
15
16
|
|
|
16
17
|
const __filename = fileURLToPath(import.meta.url)
|
|
17
18
|
const __dirname = dirname(__filename)
|
|
@@ -39,9 +40,7 @@ export async function cleanupOldRouteFiles(CONFIG) {
|
|
|
39
40
|
const content = await readFile(routeFile, 'utf8')
|
|
40
41
|
if (content.includes('Auto-generated Plugin Route Proxy')) {
|
|
41
42
|
// Remove the entire plugin route directory
|
|
42
|
-
await
|
|
43
|
-
fs.rm(pluginDir, { recursive: true, force: true })
|
|
44
|
-
)
|
|
43
|
+
await projectFiles(rootDir).rm(pluginDir, { recursive: true, force: true })
|
|
45
44
|
verbose(`Cleaned up old route: ${pluginDir}`)
|
|
46
45
|
}
|
|
47
46
|
}
|
|
@@ -49,6 +48,8 @@ export async function cleanupOldRouteFiles(CONFIG) {
|
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
} catch (error) {
|
|
51
|
+
// An UNSAFE_WRITE refusal propagates and stops the build; every other error here is a non-fatal cleanup failure
|
|
52
|
+
if (isUnsafeWrite(error)) throw error
|
|
52
53
|
verbose(`Error during route cleanup: ${error.message}`)
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -80,7 +81,6 @@ export async function cleanupOrphanedTemplates(activeTemplates, CONFIG) {
|
|
|
80
81
|
|
|
81
82
|
async function scanAndCleanDirectory(dir, relativePath = '') {
|
|
82
83
|
try {
|
|
83
|
-
const { readdir, stat, unlink } = await import('fs/promises')
|
|
84
84
|
const entries = await readdir(dir, { withFileTypes: true })
|
|
85
85
|
|
|
86
86
|
for (const entry of entries) {
|
|
@@ -103,13 +103,14 @@ export async function cleanupOrphanedTemplates(activeTemplates, CONFIG) {
|
|
|
103
103
|
|
|
104
104
|
// Check if this generated file has a corresponding active template
|
|
105
105
|
if (!activeTemplatePaths.has(fullPath)) {
|
|
106
|
-
await unlink(fullPath)
|
|
106
|
+
await projectFiles(rootDir).unlink(fullPath)
|
|
107
107
|
log(`Cleaned orphaned file: ${fullPath.replace(rootDir, '')}`, 'info')
|
|
108
108
|
cleaned++
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
} catch (error) {
|
|
113
|
+
if (isUnsafeWrite(error)) throw error
|
|
113
114
|
verbose(`Error scanning directory ${dir}: ${error.message}`)
|
|
114
115
|
}
|
|
115
116
|
}
|
|
@@ -118,12 +119,12 @@ export async function cleanupOrphanedTemplates(activeTemplates, CONFIG) {
|
|
|
118
119
|
|
|
119
120
|
// Clean up empty directories (in reverse order to handle nested structures)
|
|
120
121
|
if (dirsToCleanup.length > 0) {
|
|
121
|
-
const { rmdir } = await import('fs/promises')
|
|
122
122
|
for (const dir of dirsToCleanup.reverse()) {
|
|
123
123
|
try {
|
|
124
|
-
await rmdir(dir)
|
|
124
|
+
await projectFiles(rootDir).rmdir(dir)
|
|
125
125
|
log(`Removed empty directory: ${dir.replace(rootDir, '')}`, 'info')
|
|
126
|
-
} catch {
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (isUnsafeWrite(error)) throw error
|
|
127
128
|
// Directory might not be empty anymore, ignore
|
|
128
129
|
}
|
|
129
130
|
}
|
|
@@ -166,10 +167,10 @@ export async function cleanupDeletedTemplate(templateFilePath, CONFIG) {
|
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
try {
|
|
169
|
-
const
|
|
170
|
+
const files = projectFiles(rootDir)
|
|
170
171
|
|
|
171
172
|
// Remove the generated template file
|
|
172
|
-
await unlink(appTemplatePath)
|
|
173
|
+
await files.unlink(appTemplatePath)
|
|
173
174
|
log(`Removed generated template: ${appTemplatePath.replace(rootDir, '')}`, 'info')
|
|
174
175
|
|
|
175
176
|
// Try to remove empty parent directories (but don't fail if they're not empty)
|
|
@@ -178,19 +179,21 @@ export async function cleanupDeletedTemplate(templateFilePath, CONFIG) {
|
|
|
178
179
|
|
|
179
180
|
while (parentDir !== templatesDir && parentDir !== rootDir) {
|
|
180
181
|
try {
|
|
181
|
-
const entries = await
|
|
182
|
+
const entries = await readdir(parentDir)
|
|
182
183
|
if (entries.length === 0) {
|
|
183
|
-
await rmdir(parentDir)
|
|
184
|
+
await files.rmdir(parentDir)
|
|
184
185
|
log(`Removed empty directory: ${parentDir.replace(rootDir, '')}`, 'info')
|
|
185
186
|
parentDir = dirname(parentDir)
|
|
186
187
|
} else {
|
|
187
188
|
break // Directory is not empty, stop cleanup
|
|
188
189
|
}
|
|
189
|
-
} catch {
|
|
190
|
+
} catch (error) {
|
|
191
|
+
if (isUnsafeWrite(error)) throw error
|
|
190
192
|
break // Error reading directory or removing, stop cleanup
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
195
|
} catch (error) {
|
|
196
|
+
if (isUnsafeWrite(error)) throw error
|
|
194
197
|
verbose(`Failed to cleanup template file ${appTemplatePath}: ${error.message}`)
|
|
195
198
|
}
|
|
196
199
|
}
|
|
@@ -7,18 +7,36 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { existsSync } from 'fs'
|
|
10
|
-
import { readFile
|
|
10
|
+
import { readFile } from 'fs/promises'
|
|
11
11
|
import { join, dirname } from 'path'
|
|
12
12
|
import { fileURLToPath } from 'url'
|
|
13
13
|
|
|
14
14
|
import { log, verbose } from '../../../utils/index.mjs'
|
|
15
|
-
import { CONFIG } from '../config.mjs'
|
|
15
|
+
import { CONFIG as DEFAULT_CONFIG } from '../config.mjs'
|
|
16
|
+
import { projectFiles } from '../../safe-fs.mjs'
|
|
16
17
|
|
|
17
18
|
const __filename = fileURLToPath(import.meta.url)
|
|
18
19
|
const __dirname = dirname(__filename)
|
|
19
20
|
// Path from packages/core/scripts/build/registry/post-build/ to project root (6 levels up)
|
|
20
21
|
const rootDir = join(__dirname, '../../../../../..')
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* The directory of the active theme's Cypress fixtures, which the build writes
|
|
25
|
+
* entities.json and blocks.json into when it exists, and the root those writes
|
|
26
|
+
* may land under: the project's, or the monorepo's, where the themes of the
|
|
27
|
+
* monorepo are.
|
|
28
|
+
*
|
|
29
|
+
* @param {object} config - Configuration object from getConfig()
|
|
30
|
+
* @returns {{ fixturesDir: string, root: string } | null} Null when no theme is active
|
|
31
|
+
*/
|
|
32
|
+
export function testFixturesPlace(config) {
|
|
33
|
+
if (!config.activeTheme) return null
|
|
34
|
+
return {
|
|
35
|
+
fixturesDir: join(config.themesDir, config.activeTheme, 'tests', 'cypress', 'fixtures'),
|
|
36
|
+
root: config.isMonorepoMode ? config.monorepoRoot : config.projectRoot,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
/**
|
|
23
41
|
* Extract test-relevant data from an entity config file using regex
|
|
24
42
|
* @param {string} configPath - Path to the entity config file
|
|
@@ -88,7 +106,7 @@ export async function extractEntityTestData(configPath, entityDir) {
|
|
|
88
106
|
* @param {Array} entities - All discovered entities
|
|
89
107
|
* @param {Array} themes - All discovered themes
|
|
90
108
|
*/
|
|
91
|
-
export async function generateTestEntitiesJson(entities, themes) {
|
|
109
|
+
export async function generateTestEntitiesJson(entities, themes, CONFIG = DEFAULT_CONFIG) {
|
|
92
110
|
const activeTheme = CONFIG.activeTheme
|
|
93
111
|
if (!activeTheme) {
|
|
94
112
|
verbose('No active theme set, skipping test fixtures generation')
|
|
@@ -103,7 +121,7 @@ export async function generateTestEntitiesJson(entities, themes) {
|
|
|
103
121
|
}
|
|
104
122
|
|
|
105
123
|
// Check if tests directory exists
|
|
106
|
-
const fixturesDir =
|
|
124
|
+
const { fixturesDir, root } = testFixturesPlace(CONFIG)
|
|
107
125
|
if (!existsSync(fixturesDir)) {
|
|
108
126
|
verbose(`Test fixtures directory not found for theme "${activeTheme}", skipping`)
|
|
109
127
|
return
|
|
@@ -178,7 +196,7 @@ export async function generateTestEntitiesJson(entities, themes) {
|
|
|
178
196
|
|
|
179
197
|
// Write the file
|
|
180
198
|
const outputPath = join(fixturesDir, 'entities.json')
|
|
181
|
-
await writeFile(outputPath, JSON.stringify(jsonContent, null, 2), 'utf8')
|
|
199
|
+
await projectFiles(root).writeFile(outputPath, JSON.stringify(jsonContent, null, 2), 'utf8')
|
|
182
200
|
log(`entities.json generated for theme "${activeTheme}"`, 'success')
|
|
183
201
|
}
|
|
184
202
|
|
|
@@ -187,7 +205,7 @@ export async function generateTestEntitiesJson(entities, themes) {
|
|
|
187
205
|
* This file is used by Cypress tests for block-related testing
|
|
188
206
|
* @param {Array} blocks - All discovered blocks
|
|
189
207
|
*/
|
|
190
|
-
export async function generateTestBlocksJson(blocks) {
|
|
208
|
+
export async function generateTestBlocksJson(blocks, CONFIG = DEFAULT_CONFIG) {
|
|
191
209
|
const activeTheme = CONFIG.activeTheme
|
|
192
210
|
if (!activeTheme) {
|
|
193
211
|
verbose('No active theme set, skipping blocks.json generation')
|
|
@@ -195,7 +213,7 @@ export async function generateTestBlocksJson(blocks) {
|
|
|
195
213
|
}
|
|
196
214
|
|
|
197
215
|
// Check if tests directory exists
|
|
198
|
-
const fixturesDir =
|
|
216
|
+
const { fixturesDir, root } = testFixturesPlace(CONFIG)
|
|
199
217
|
if (!existsSync(fixturesDir)) {
|
|
200
218
|
verbose(`Test fixtures directory not found for theme "${activeTheme}", skipping blocks.json`)
|
|
201
219
|
return
|
|
@@ -229,6 +247,6 @@ export async function generateTestBlocksJson(blocks) {
|
|
|
229
247
|
}
|
|
230
248
|
|
|
231
249
|
const outputPath = join(fixturesDir, 'blocks.json')
|
|
232
|
-
await writeFile(outputPath, JSON.stringify(jsonContent, null, 2), 'utf8')
|
|
250
|
+
await projectFiles(root).writeFile(outputPath, JSON.stringify(jsonContent, null, 2), 'utf8')
|
|
233
251
|
log(`blocks.json generated for theme "${activeTheme}" (${blocks.length} blocks)`, 'success')
|
|
234
252
|
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How core is installed in a project, told from the project alone: from npm, or
|
|
3
|
+
* as a package of the NextSpark monorepo. Nothing here reads configuration or
|
|
4
|
+
* loads a .env, so a check that runs before the build - in the build itself or
|
|
5
|
+
* in `nextspark` - can ask it.
|
|
6
|
+
*
|
|
7
|
+
* @module core/scripts/build/registry/project-mode
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync, lstatSync, readlinkSync } from 'fs'
|
|
11
|
+
import { dirname, join } from 'path'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Detect monorepo root by searching for pnpm-workspace.yaml
|
|
15
|
+
* @param {string} startDir - Directory to start searching from
|
|
16
|
+
* @returns {string|null} Monorepo root path or null if not in monorepo
|
|
17
|
+
*/
|
|
18
|
+
export function detectMonorepoRoot(startDir = process.cwd()) {
|
|
19
|
+
let dir = startDir
|
|
20
|
+
const maxDepth = 10
|
|
21
|
+
let depth = 0
|
|
22
|
+
|
|
23
|
+
while (dir !== '/' && depth < maxDepth) {
|
|
24
|
+
if (existsSync(join(dir, 'pnpm-workspace.yaml'))) {
|
|
25
|
+
return dir
|
|
26
|
+
}
|
|
27
|
+
dir = dirname(dir)
|
|
28
|
+
depth++
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Check if NextSpark is installed as a package (from npm registry)
|
|
36
|
+
*
|
|
37
|
+
* This handles both traditional npm/yarn AND pnpm:
|
|
38
|
+
* - npm/yarn: packages are copied to node_modules (not symlinks)
|
|
39
|
+
* - pnpm: ALL packages are symlinks, but npm packages point to .pnpm/ store
|
|
40
|
+
* - pnpm workspace: local packages symlink to the actual package path
|
|
41
|
+
*
|
|
42
|
+
* @param {string} root - Project root path
|
|
43
|
+
* @returns {boolean} True if installed from npm registry
|
|
44
|
+
*/
|
|
45
|
+
export function isInstalledAsPackage(root) {
|
|
46
|
+
const corePath = join(root, 'node_modules/@nextsparkjs/core')
|
|
47
|
+
if (!existsSync(corePath)) {
|
|
48
|
+
return false
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const stat = lstatSync(corePath)
|
|
53
|
+
|
|
54
|
+
// If not a symlink, it's a traditional npm/yarn install
|
|
55
|
+
if (!stat.isSymbolicLink()) {
|
|
56
|
+
return true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// For symlinks (pnpm), check WHERE it points to:
|
|
60
|
+
// - npm install: points to .pnpm/@nextsparkjs+core@version.../node_modules/@nextsparkjs/core
|
|
61
|
+
// - workspace: points to ../../packages/core or similar
|
|
62
|
+
const linkTarget = readlinkSync(corePath)
|
|
63
|
+
|
|
64
|
+
// If symlink points to .pnpm/ or .pnpmN/ directory, it's a real npm installation via pnpm
|
|
65
|
+
// The .pnpm/.pnpm2/etc directory is pnpm's content-addressable store
|
|
66
|
+
if (/\.pnpm\d?[/\\]/.test(linkTarget)) {
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Otherwise it's a workspace symlink (monorepo development)
|
|
71
|
+
return false
|
|
72
|
+
} catch {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Compiler Loader
|
|
3
|
+
*
|
|
4
|
+
* Resolves the TypeScript 5/6 compiler API a registry build step needs to
|
|
5
|
+
* read a source file's real syntax tree, shared by every discovery or
|
|
6
|
+
* generation step that parses TypeScript instead of scanning raw text.
|
|
7
|
+
*
|
|
8
|
+
* @module core/scripts/build/registry/shared/typescript-compiler
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { createRequire } from 'node:module'
|
|
12
|
+
import { join } from 'node:path'
|
|
13
|
+
import { errorWithLines } from '../../../utils/logging.mjs'
|
|
14
|
+
|
|
15
|
+
/** TypeScript 7's native port doesn't ship the compiler API - its package
|
|
16
|
+
* exports are `./lib/version.cjs` plus `./unstable/*` - so a candidate module
|
|
17
|
+
* is checked for the API surface this build needs, not just for existing. */
|
|
18
|
+
function hasCompilerApi(ts) {
|
|
19
|
+
return Boolean(ts && typeof ts.createSourceFile === 'function' && typeof ts.getScriptKindFromFileName === 'function' && ts.ScriptKind)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Try each TypeScript candidate in order and return the first module whose API this
|
|
24
|
+
* build needs. A candidate that loads but lacks the API is recorded and the next
|
|
25
|
+
* one is tried, rather than failing on the first hit - the point of trying more than
|
|
26
|
+
* one candidate at all.
|
|
27
|
+
*/
|
|
28
|
+
export async function selectTypeScriptModule(candidates) {
|
|
29
|
+
const rejected = []
|
|
30
|
+
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
let loaded
|
|
33
|
+
try {
|
|
34
|
+
loaded = await candidate.load()
|
|
35
|
+
} catch (error) {
|
|
36
|
+
rejected.push(`${candidate.label}: could not be loaded (${error.message})`)
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const ts = loaded?.default ?? loaded
|
|
41
|
+
if (hasCompilerApi(ts)) {
|
|
42
|
+
return ts
|
|
43
|
+
}
|
|
44
|
+
rejected.push(
|
|
45
|
+
`${candidate.label}: found TypeScript ${ts?.version ?? 'of an unknown version'}, which does not export the TypeScript 5/6 ` +
|
|
46
|
+
'compiler API (createSourceFile, getScriptKindFromFileName, ScriptKind) the registry build needs'
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
throw errorWithLines([
|
|
51
|
+
'Parsing a source file for the registry build requires the TypeScript 5 or 6 compiler API, but no candidate provided it:',
|
|
52
|
+
...rejected.map(reason => ` - ${reason}`),
|
|
53
|
+
])
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const modulePromises = new Map()
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The TypeScript compiler, resolved from core first and then from `projectRoot`:
|
|
60
|
+
* it is a dependency of core (#195), so it is always found there regardless of
|
|
61
|
+
* the TypeScript version the project itself has installed; the project is a
|
|
62
|
+
* fallback for setups where core's own copy is not reachable from the caller's
|
|
63
|
+
* location on disk. Cached per project root so repeated calls in the same
|
|
64
|
+
* build don't re-resolve the module.
|
|
65
|
+
*/
|
|
66
|
+
export function loadTypeScriptFor(projectRoot) {
|
|
67
|
+
if (!modulePromises.has(projectRoot)) {
|
|
68
|
+
modulePromises.set(
|
|
69
|
+
projectRoot,
|
|
70
|
+
selectTypeScriptModule([
|
|
71
|
+
{ label: '@nextsparkjs/core', load: () => import('typescript') },
|
|
72
|
+
{ label: `the project at ${projectRoot}`, load: async () => createRequire(join(projectRoot, 'package.json'))('typescript') },
|
|
73
|
+
])
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
return modulePromises.get(projectRoot)
|
|
77
|
+
}
|
|
@@ -6,19 +6,23 @@
|
|
|
6
6
|
|
|
7
7
|
import { describe, it } from 'node:test'
|
|
8
8
|
import assert from 'node:assert'
|
|
9
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
10
|
+
import { tmpdir } from 'node:os'
|
|
11
|
+
import { join } from 'node:path'
|
|
9
12
|
import { validateEnvironment } from './config.mjs'
|
|
10
13
|
|
|
11
14
|
describe('validateEnvironment', () => {
|
|
12
15
|
it('should return valid when .env exists and activeTheme is set', () => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const projectRoot = mkdtempSync(join(tmpdir(), 'nextspark-validate-env-test-'))
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
writeFileSync(join(projectRoot, '.env'), '')
|
|
20
|
+
const result = validateEnvironment({ projectRoot, activeTheme: 'default' })
|
|
21
|
+
assert.strictEqual(result.valid, true)
|
|
22
|
+
assert.strictEqual(result.errors.length, 0)
|
|
23
|
+
} finally {
|
|
24
|
+
rmSync(projectRoot, { recursive: true, force: true })
|
|
17
25
|
}
|
|
18
|
-
|
|
19
|
-
const result = validateEnvironment(config)
|
|
20
|
-
assert.strictEqual(result.valid, true)
|
|
21
|
-
assert.strictEqual(result.errors.length, 0)
|
|
22
26
|
})
|
|
23
27
|
|
|
24
28
|
it('should return error when .env file is missing', () => {
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
import { existsSync, watch } from 'fs'
|
|
10
10
|
import { join } from 'path'
|
|
11
11
|
|
|
12
|
-
import { log
|
|
12
|
+
import { log } from '../../utils/index.mjs'
|
|
13
13
|
import { CONFIG } from './config.mjs'
|
|
14
|
-
import { cleanupDeletedTemplate } from './post-build/route-cleanup.mjs'
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Start watching contents directory for changes
|
|
@@ -29,35 +28,6 @@ export async function watchContents(buildRegistries) {
|
|
|
29
28
|
]
|
|
30
29
|
|
|
31
30
|
let debounceTimer = null
|
|
32
|
-
const templateFileTracker = new Map() // Track existing template files
|
|
33
|
-
|
|
34
|
-
// Initialize template file tracker
|
|
35
|
-
for (const watchPath of watchPaths) {
|
|
36
|
-
if (existsSync(watchPath) && watchPath.includes('themes')) {
|
|
37
|
-
const { readdir } = await import('fs/promises')
|
|
38
|
-
try {
|
|
39
|
-
const trackTemplates = async (dir, basePath = '') => {
|
|
40
|
-
const entries = await readdir(dir, { withFileTypes: true })
|
|
41
|
-
for (const entry of entries) {
|
|
42
|
-
const fullPath = join(dir, entry.name)
|
|
43
|
-
const relativePath = join(basePath, entry.name)
|
|
44
|
-
|
|
45
|
-
if (entry.isDirectory()) {
|
|
46
|
-
await trackTemplates(fullPath, relativePath)
|
|
47
|
-
} else if (entry.isFile() && relativePath.includes('/templates/') &&
|
|
48
|
-
(entry.name.endsWith('.tsx') || entry.name.endsWith('.ts'))) {
|
|
49
|
-
templateFileTracker.set(relativePath, true)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
await trackTemplates(watchPath)
|
|
55
|
-
verbose(`Tracking ${templateFileTracker.size} template files for deletion detection`)
|
|
56
|
-
} catch (error) {
|
|
57
|
-
verbose(`Failed to initialize template tracker: ${error.message}`)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
31
|
|
|
62
32
|
for (const watchPath of watchPaths) {
|
|
63
33
|
if (existsSync(watchPath)) {
|
|
@@ -81,7 +51,8 @@ export async function watchContents(buildRegistries) {
|
|
|
81
51
|
return // Skip rebuild for test artifacts
|
|
82
52
|
}
|
|
83
53
|
|
|
84
|
-
//
|
|
54
|
+
// A deleted template needs nothing of its own here: the rebuild leaves its
|
|
55
|
+
// route out of app/(templates) and backs the old file up.
|
|
85
56
|
const shouldRebuild = !filename || // Always rebuild if filename is null (deletions)
|
|
86
57
|
filename.endsWith('.config.ts') ||
|
|
87
58
|
filename.endsWith('route.ts') ||
|
|
@@ -90,27 +61,6 @@ export async function watchContents(buildRegistries) {
|
|
|
90
61
|
filename.includes('/templates/') || // Any change in templates directory
|
|
91
62
|
eventType === 'rename' // Catch rename events (often deletions)
|
|
92
63
|
|
|
93
|
-
// Handle template file deletions
|
|
94
|
-
if (filename && filename.includes('/templates/') &&
|
|
95
|
-
(filename.endsWith('.tsx') || filename.endsWith('.ts'))) {
|
|
96
|
-
|
|
97
|
-
const fullTemplatePath = join(watchPath, filename)
|
|
98
|
-
const wasTracked = templateFileTracker.has(filename)
|
|
99
|
-
const currentlyExists = existsSync(fullTemplatePath)
|
|
100
|
-
|
|
101
|
-
// File was deleted (was tracked but no longer exists)
|
|
102
|
-
if (wasTracked && !currentlyExists) {
|
|
103
|
-
log(`Template deleted: ${filename}`, 'info')
|
|
104
|
-
await cleanupDeletedTemplate(fullTemplatePath, CONFIG)
|
|
105
|
-
templateFileTracker.delete(filename)
|
|
106
|
-
}
|
|
107
|
-
// File was added (exists but wasn't tracked)
|
|
108
|
-
else if (!wasTracked && currentlyExists) {
|
|
109
|
-
templateFileTracker.set(filename, true)
|
|
110
|
-
verbose(`Template added to tracker: ${filename}`)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
64
|
if (shouldRebuild) {
|
|
115
65
|
// Debounce rebuilds
|
|
116
66
|
clearTimeout(debounceTimer)
|