@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
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
* @module core/scripts/build/registry/generators/docs-registry
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import { existsSync, readdirSync } from 'fs'
|
|
11
11
|
import path from 'path'
|
|
12
|
-
import { existsSync } from 'fs'
|
|
13
12
|
import { CONFIG } from '../config.mjs'
|
|
14
13
|
|
|
15
14
|
// Get config values - use themesDir which correctly handles monorepo mode
|
|
@@ -59,7 +58,7 @@ function scanDocsDirectory(docsPath, source) {
|
|
|
59
58
|
}
|
|
60
59
|
|
|
61
60
|
const sections = []
|
|
62
|
-
const items =
|
|
61
|
+
const items = readdirSync(docsPath, { withFileTypes: true })
|
|
63
62
|
|
|
64
63
|
for (const item of items) {
|
|
65
64
|
if (!item.isDirectory()) continue
|
|
@@ -70,7 +69,7 @@ function scanDocsDirectory(docsPath, source) {
|
|
|
70
69
|
const title = slugToTitle(slug)
|
|
71
70
|
|
|
72
71
|
const pages = []
|
|
73
|
-
const files =
|
|
72
|
+
const files = readdirSync(sectionPath)
|
|
74
73
|
|
|
75
74
|
for (const file of files) {
|
|
76
75
|
if (!file.endsWith('.md')) continue
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* @module core/scripts/build/registry/generators/testing-registry
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { readFileSync,
|
|
16
|
+
import { readFileSync, existsSync } from 'fs'
|
|
17
17
|
import { join } from 'path'
|
|
18
18
|
import { discoverTestTags, validateTags } from '../discovery/test-tags.mjs'
|
|
19
19
|
|
|
@@ -10,7 +10,7 @@ import { readFile } from 'fs/promises'
|
|
|
10
10
|
import { join, dirname } from 'path'
|
|
11
11
|
import { fileURLToPath } from 'url'
|
|
12
12
|
|
|
13
|
-
import { log, verbose } from '../../../utils/index.mjs'
|
|
13
|
+
import { errorWithLines, log, verbose } from '../../../utils/index.mjs'
|
|
14
14
|
|
|
15
15
|
const __filename = fileURLToPath(import.meta.url)
|
|
16
16
|
const __dirname = dirname(__filename)
|
|
@@ -187,7 +187,7 @@ export async function generatePermissionsRegistry(permissionsConfig, entities, c
|
|
|
187
187
|
errorLines.push(' the "slug" field in the corresponding entity.config.ts')
|
|
188
188
|
errorLines.push('')
|
|
189
189
|
|
|
190
|
-
throw
|
|
190
|
+
throw errorWithLines(errorLines)
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
log(' ✅ All permission entity keys validated against discovered entities', 'info')
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
canOverrideComponent
|
|
16
16
|
} from '../../../../dist/config/protected-paths.js'
|
|
17
17
|
import { convertCorePath } from '../config.mjs'
|
|
18
|
+
import { analyzeTemplates, routeFileAction, templateAnalysisFor } from '../post-build/page-generator.mjs'
|
|
18
19
|
|
|
19
20
|
const __filename = fileURLToPath(import.meta.url)
|
|
20
21
|
const __dirname = dirname(__filename)
|
|
@@ -23,13 +24,22 @@ const __dirname = dirname(__filename)
|
|
|
23
24
|
const rootDir = join(__dirname, '../../../../../..')
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* @returns {string} Generated TypeScript content
|
|
27
|
+
* The analysis a generator works from: the one the registry build passes in,
|
|
28
|
+
* or - for a caller using the signature without it - one taken for this call,
|
|
29
|
+
* against the project root template files are resolved from here.
|
|
30
30
|
*/
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
async function analysisFor(templates, config, analysis) {
|
|
32
|
+
return analysis ?? analyzeTemplates(templates, { projectRoot: config?.projectRoot || rootDir })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Group templates by app path (highest priority first), each with whether its
|
|
37
|
+
* highest-priority template has a default export. That answer comes from
|
|
38
|
+
* `analyzeTemplates`, which parsed the template once for the whole build: the
|
|
39
|
+
* server registry, the client registry and the page generator all take it
|
|
40
|
+
* from there, so none of them can see a different version of the file.
|
|
41
|
+
*/
|
|
42
|
+
function resolveTemplateEntries(templates, analysis) {
|
|
33
43
|
const templatesByPath = {}
|
|
34
44
|
|
|
35
45
|
templates.forEach(template => {
|
|
@@ -39,16 +49,36 @@ export function generateTemplateRegistry(templates, config) {
|
|
|
39
49
|
templatesByPath[template.appPath].push(template)
|
|
40
50
|
})
|
|
41
51
|
|
|
42
|
-
// Sort templates by priority (higher priority first)
|
|
43
52
|
Object.keys(templatesByPath).forEach(appPath => {
|
|
44
53
|
templatesByPath[appPath].sort((a, b) => b.priority - a.priority)
|
|
45
54
|
})
|
|
46
55
|
|
|
56
|
+
// A template whose route file would break is rejected here too, whoever built the analysis
|
|
57
|
+
for (const template of templates) {
|
|
58
|
+
routeFileAction(template, templateAnalysisFor(analysis, template))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return Object.entries(templatesByPath).map(([appPath, pathTemplates]) => {
|
|
62
|
+
const highestPriorityTemplate = pathTemplates[0]
|
|
63
|
+
const { hasDefaultExport } = templateAnalysisFor(analysis, highestPriorityTemplate)
|
|
64
|
+
return { appPath, pathTemplates, highestPriorityTemplate, hasDefaultExport }
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generate the template registry file
|
|
70
|
+
* @param {Array} templates - Discovered templates
|
|
71
|
+
* @param {object} config - Configuration object from getConfig()
|
|
72
|
+
* @param {Map} [analysis] - What `analyzeTemplates` read from these templates; taken for this call when omitted
|
|
73
|
+
* @returns {Promise<string>} Generated TypeScript content
|
|
74
|
+
*/
|
|
75
|
+
export async function generateTemplateRegistry(templates, config, analysis = null) {
|
|
76
|
+
const entries = resolveTemplateEntries(templates, await analysisFor(templates, config, analysis))
|
|
77
|
+
|
|
47
78
|
// Generate registry entries. Each component is a deferred import, so a route
|
|
48
79
|
// pulls in the template it renders and no others.
|
|
49
|
-
const registryEntries =
|
|
50
|
-
.map((
|
|
51
|
-
const highestPriorityTemplate = pathTemplates[0]
|
|
80
|
+
const registryEntries = entries
|
|
81
|
+
.map(({ appPath, pathTemplates, highestPriorityTemplate, hasDefaultExport }) => {
|
|
52
82
|
// Strip .tsx/.ts extension - Next.js resolves extensions automatically on all platforms
|
|
53
83
|
let templatePath = highestPriorityTemplate.templatePath
|
|
54
84
|
if (templatePath.endsWith('.tsx')) {
|
|
@@ -57,12 +87,12 @@ export function generateTemplateRegistry(templates, config) {
|
|
|
57
87
|
templatePath = templatePath.slice(0, -3)
|
|
58
88
|
}
|
|
59
89
|
|
|
60
|
-
// Metadata-only templates (PROTECTED_RENDER
|
|
61
|
-
// no component to load
|
|
90
|
+
// Metadata-only templates (PROTECTED_RENDER, standalone .meta.ts, or a
|
|
91
|
+
// template with no default export) have no component to load
|
|
62
92
|
const isMetaOnly = highestPriorityTemplate.fileName?.endsWith('.meta.ts')
|
|
63
|
-
const componentRef =
|
|
64
|
-
? '
|
|
65
|
-
:
|
|
93
|
+
const componentRef = canOverrideComponent(appPath) && !isMetaOnly && hasDefaultExport
|
|
94
|
+
? `lazyTemplate('${appPath}', () => import('${templatePath}'))`
|
|
95
|
+
: 'null'
|
|
66
96
|
|
|
67
97
|
return ` '${appPath}': {
|
|
68
98
|
appPath: '${appPath}',
|
|
@@ -74,7 +104,7 @@ export function generateTemplateRegistry(templates, config) {
|
|
|
74
104
|
.join(',\n')
|
|
75
105
|
|
|
76
106
|
// Generate utility functions for template resolution
|
|
77
|
-
const templatePaths =
|
|
107
|
+
const templatePaths = entries.map(({ appPath }) => appPath)
|
|
78
108
|
const templateTypeMap = {}
|
|
79
109
|
|
|
80
110
|
templates.forEach(template => {
|
|
@@ -220,40 +250,27 @@ async function hasServerOnlyExports(filePath) {
|
|
|
220
250
|
* Excludes templates with server-only exports (generateMetadata, revalidate, etc.)
|
|
221
251
|
* @param {Array} templates - Discovered templates
|
|
222
252
|
* @param {object} config - Configuration object from getConfig()
|
|
253
|
+
* @param {Map} [analysis] - What `analyzeTemplates` read from these templates; taken for this call when omitted
|
|
223
254
|
* @returns {Promise<string>} Generated TypeScript content
|
|
224
255
|
*/
|
|
225
|
-
export async function generateTemplateRegistryClient(templates, config) {
|
|
256
|
+
export async function generateTemplateRegistryClient(templates, config, analysis = null) {
|
|
226
257
|
const outputFilePath = join(config.outputDir, 'template-registry.client.ts')
|
|
227
|
-
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
templates
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
})
|
|
241
|
-
|
|
242
|
-
// Filter for client-compatible templates (pages only, not layouts)
|
|
243
|
-
// Also exclude templates with server-only exports
|
|
244
|
-
const clientCompatibleTemplatesPromises = Object.entries(templatesByPath)
|
|
245
|
-
.filter(([appPath, pathTemplates]) => {
|
|
246
|
-
const template = pathTemplates[0]
|
|
247
|
-
// Only include page templates (not layouts) that can override components
|
|
248
|
-
return (template.templateType === 'page' || template.templateType === 'layout') && canOverrideComponent(appPath)
|
|
249
|
-
})
|
|
250
|
-
.map(async ([appPath, pathTemplates]) => {
|
|
251
|
-
const template = pathTemplates[0]
|
|
258
|
+
const projectRoot = config.projectRoot || rootDir
|
|
259
|
+
const entries = resolveTemplateEntries(templates, await analysisFor(templates, config, analysis))
|
|
260
|
+
|
|
261
|
+
// Filter for client-compatible templates: pages and layouts, not protected,
|
|
262
|
+
// with a default export according to the build's analysis - the same answer
|
|
263
|
+
// the server registry uses. Also exclude templates with server-only exports.
|
|
264
|
+
const clientCompatibleTemplatesPromises = entries
|
|
265
|
+
.filter(({ appPath, highestPriorityTemplate, hasDefaultExport }) =>
|
|
266
|
+
(highestPriorityTemplate.templateType === 'page' || highestPriorityTemplate.templateType === 'layout') &&
|
|
267
|
+
canOverrideComponent(appPath) &&
|
|
268
|
+
hasDefaultExport
|
|
269
|
+
)
|
|
270
|
+
.map(async ({ appPath, highestPriorityTemplate }) => {
|
|
252
271
|
// Get actual file path from template path
|
|
253
272
|
// Template paths may or may not have extension, ensure we check the .tsx file
|
|
254
|
-
|
|
255
|
-
const projectRoot = config.projectRoot || rootDir
|
|
256
|
-
let actualFilePath = template.templatePath.replace('@/', projectRoot + '/')
|
|
273
|
+
let actualFilePath = highestPriorityTemplate.templatePath.replace('@/', projectRoot + '/')
|
|
257
274
|
// If path doesn't end with .tsx or .ts, add .tsx
|
|
258
275
|
if (!actualFilePath.endsWith('.tsx') && !actualFilePath.endsWith('.ts')) {
|
|
259
276
|
actualFilePath += '.tsx'
|
|
@@ -265,7 +282,7 @@ export async function generateTemplateRegistryClient(templates, config) {
|
|
|
265
282
|
verbose(`Excluding ${appPath} from client registry (has server-only exports)`)
|
|
266
283
|
return null
|
|
267
284
|
}
|
|
268
|
-
return
|
|
285
|
+
return { appPath, highestPriorityTemplate }
|
|
269
286
|
})
|
|
270
287
|
|
|
271
288
|
const clientCompatibleTemplatesResults = await Promise.all(clientCompatibleTemplatesPromises)
|
|
@@ -274,10 +291,9 @@ export async function generateTemplateRegistryClient(templates, config) {
|
|
|
274
291
|
// Generate registry entries as deferred imports, so a route loads the
|
|
275
292
|
// template it renders and no others
|
|
276
293
|
const registryEntries = clientCompatibleTemplates
|
|
277
|
-
.map((
|
|
278
|
-
const template = pathTemplates[0]
|
|
294
|
+
.map(({ appPath, highestPriorityTemplate }) => {
|
|
279
295
|
// Strip .tsx/.ts extension - Next.js resolves extensions automatically on all platforms
|
|
280
|
-
let templatePath =
|
|
296
|
+
let templatePath = highestPriorityTemplate.templatePath
|
|
281
297
|
if (templatePath.endsWith('.tsx')) {
|
|
282
298
|
templatePath = templatePath.slice(0, -4)
|
|
283
299
|
} else if (templatePath.endsWith('.ts')) {
|
|
@@ -29,7 +29,6 @@ export {
|
|
|
29
29
|
|
|
30
30
|
// Generators
|
|
31
31
|
export {
|
|
32
|
-
generateAll,
|
|
33
32
|
generatePluginRegistry,
|
|
34
33
|
generatePluginRegistryClient,
|
|
35
34
|
generateEntityRegistry,
|
|
@@ -52,7 +51,7 @@ export {
|
|
|
52
51
|
|
|
53
52
|
// Post-build tasks
|
|
54
53
|
export {
|
|
55
|
-
|
|
54
|
+
analyzeTemplates,
|
|
56
55
|
generateMissingPages,
|
|
57
56
|
generateTemplatePage,
|
|
58
57
|
displayTreeStructure,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @module core/scripts/build/registry/post-build
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
export { generateMissingPages, generateTemplatePage } from './page-generator.mjs'
|
|
9
|
+
export { analyzeTemplates, generateMissingPages, generateTemplatePage } from './page-generator.mjs'
|
|
10
10
|
export { displayTreeStructure } from './tree-display.mjs'
|
|
11
11
|
export { generateTestEntitiesJson, generateTestBlocksJson, extractEntityTestData } from './test-fixtures.mjs'
|
|
12
12
|
export {
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The .gitignore files nextspark keeps in the two directories none of whose
|
|
3
|
+
* content has a place in git: .nextspark/backups, where each backup of a file
|
|
4
|
+
* the registry build or `nextspark sync:app` replaces or removes goes into a
|
|
5
|
+
* directory named as it is created, and .nextspark/registries, which the
|
|
6
|
+
* registry build writes again on every run. A .gitignore in a directory that
|
|
7
|
+
* ignores everything in it covers all of it, named however and holding any
|
|
8
|
+
* .gitignore of its own: git takes the patterns of the deepest .gitignore over
|
|
9
|
+
* those of any other, the repository's exclude file and core.excludesFile, and
|
|
10
|
+
* doesn't look into a directory it ignores. So what goes there that git does
|
|
11
|
+
* not track yet stays out of git whatever command writes it and whatever the
|
|
12
|
+
* project's rules say. What git already tracks there - registries committed
|
|
13
|
+
* before - a .gitignore leaves tracked: each build that rewrites them leaves
|
|
14
|
+
* them modified in git, and says so, with how to stop tracking them.
|
|
15
|
+
*
|
|
16
|
+
* `nextspark sync:app` reads them, and writes the one for backups, through this
|
|
17
|
+
* module, loaded from the core installed in the project.
|
|
18
|
+
*
|
|
19
|
+
* @module core/scripts/build/registry/post-build/own-gitignores
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { execFileSync } from 'child_process'
|
|
23
|
+
import { lstatSync, readFileSync } from 'fs'
|
|
24
|
+
import { lstat } from 'fs/promises'
|
|
25
|
+
import { join, posix } from 'path'
|
|
26
|
+
import { projectFiles } from '../../safe-fs.mjs'
|
|
27
|
+
|
|
28
|
+
export const BACKUPS_GITIGNORE = '.nextspark/backups/.gitignore'
|
|
29
|
+
|
|
30
|
+
export const REGISTRIES_GITIGNORE = '.nextspark/registries/.gitignore'
|
|
31
|
+
|
|
32
|
+
export const BACKUPS_GITIGNORE_CONTENT = '# Backups nextspark keeps on this machine: none of them belongs in git\n*\n'
|
|
33
|
+
|
|
34
|
+
export const REGISTRIES_GITIGNORE_CONTENT = '# Registries the nextspark registry build writes again on every run: none of them belongs in git\n*\n'
|
|
35
|
+
|
|
36
|
+
const CONTENTS = {
|
|
37
|
+
[BACKUPS_GITIGNORE]: BACKUPS_GITIGNORE_CONTENT,
|
|
38
|
+
[REGISTRIES_GITIGNORE]: REGISTRIES_GITIGNORE_CONTENT,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A .gitignore line's pattern as git takes it: without a closing carriage
|
|
43
|
+
* return, or the spaces that end it unless a backslash escapes the last one.
|
|
44
|
+
*/
|
|
45
|
+
function patternAsGitReadsIt(line) {
|
|
46
|
+
const withoutReturn = line.replace(/\r$/, '')
|
|
47
|
+
let end = withoutReturn.length
|
|
48
|
+
let lastSpace = -1
|
|
49
|
+
for (let index = 0; index < withoutReturn.length; index++) {
|
|
50
|
+
const character = withoutReturn[index]
|
|
51
|
+
if (character === ' ') {
|
|
52
|
+
if (lastSpace === -1) lastSpace = index
|
|
53
|
+
} else {
|
|
54
|
+
if (character === '\\') index++
|
|
55
|
+
lastSpace = -1
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (lastSpace !== -1) end = lastSpace
|
|
59
|
+
return withoutReturn.slice(0, end)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* What one of those .gitignore files is: absent; in place, when `*` is the only
|
|
64
|
+
* pattern git reads in it, whatever its comments; a symlink, which git does not
|
|
65
|
+
* read; not a file; a file that can't be read, which may hold anything; or a
|
|
66
|
+
* file with other patterns, which can take back what is beside it.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} rootDir - The project root
|
|
69
|
+
* @param {string} path - BACKUPS_GITIGNORE or REGISTRIES_GITIGNORE
|
|
70
|
+
* @returns {'missing' | 'in place' | 'symlink' | 'not a file' | 'unreadable' | 'other'}
|
|
71
|
+
*/
|
|
72
|
+
export function ownGitignoreState(rootDir, path) {
|
|
73
|
+
const absolute = join(rootDir, path)
|
|
74
|
+
let stat
|
|
75
|
+
try {
|
|
76
|
+
stat = lstatSync(absolute)
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return error.code === 'ENOENT' || error.code === 'ENOTDIR' ? 'missing' : 'unreadable'
|
|
79
|
+
}
|
|
80
|
+
if (stat.isSymbolicLink()) return 'symlink'
|
|
81
|
+
if (!stat.isFile()) return 'not a file'
|
|
82
|
+
|
|
83
|
+
let content
|
|
84
|
+
try {
|
|
85
|
+
content = readFileSync(absolute, 'utf8')
|
|
86
|
+
} catch {
|
|
87
|
+
return 'unreadable'
|
|
88
|
+
}
|
|
89
|
+
const patterns = content
|
|
90
|
+
.replace(/^\uFEFF/, '')
|
|
91
|
+
.split('\n')
|
|
92
|
+
.map(patternAsGitReadsIt)
|
|
93
|
+
.filter(line => line !== '' && !line.startsWith('#'))
|
|
94
|
+
return patterns.length === 1 && patterns[0] === '*' ? 'in place' : 'other'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* What .nextspark/backups/.gitignore is, as `ownGitignoreState` reads it.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} rootDir - The project root
|
|
101
|
+
*/
|
|
102
|
+
export function backupsGitignoreState(rootDir) {
|
|
103
|
+
return ownGitignoreState(rootDir, BACKUPS_GITIGNORE)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* What is wrong with one of those .gitignore files for keeping its directory
|
|
108
|
+
* out of git, by its state, and what to do about it; a state missing here is none.
|
|
109
|
+
*/
|
|
110
|
+
export const OWN_GITIGNORE_PROBLEMS = {
|
|
111
|
+
symlink: 'is a symlink, which git does not read, so git would pick up what is beside it: make it a file with * as its only pattern, or remove it for nextspark to write it',
|
|
112
|
+
'not a file': 'is not a file: remove it for nextspark to write it',
|
|
113
|
+
unreadable: "can't be read, so nothing says it keeps what is beside it out of git: make it readable, with * as its only pattern",
|
|
114
|
+
other: 'has patterns other than *, which can take what is beside it back into git: leave * as its only pattern, or remove it for nextspark to write it',
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Why nothing can be written beside one of those .gitignore files with git kept
|
|
119
|
+
* out of it, and what to do about it, or null when it can.
|
|
120
|
+
*/
|
|
121
|
+
async function ownGitignoreBlocker(rootDir, path) {
|
|
122
|
+
for (const directory of ['.nextspark', posix.dirname(path)]) {
|
|
123
|
+
let stat
|
|
124
|
+
try {
|
|
125
|
+
stat = await lstat(join(rootDir, directory))
|
|
126
|
+
} catch {
|
|
127
|
+
break
|
|
128
|
+
}
|
|
129
|
+
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
130
|
+
return stat.isSymbolicLink()
|
|
131
|
+
? `${directory} is a symlink: what is written through it lands wherever it points, where no .gitignore of the project keeps it out of git. Make ${directory} a directory of its own.`
|
|
132
|
+
: `${directory} is not a directory. Make it one.`
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const problem = OWN_GITIGNORE_PROBLEMS[ownGitignoreState(rootDir, path)]
|
|
137
|
+
return problem ? `${path} ${problem}.` : null
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Give a directory the .gitignore of its own, before anything is written in it.
|
|
142
|
+
* One already there is never written over: what it holds is the project's. When
|
|
143
|
+
* it can't keep the directory out of git - a symlink, not a file, unreadable,
|
|
144
|
+
* other patterns - or .nextspark or the directory is a symlink or not a
|
|
145
|
+
* directory, this throws, starting with `refusal`, so nothing is written there.
|
|
146
|
+
*/
|
|
147
|
+
async function ensureOwnGitignore(rootDir, path, refusal) {
|
|
148
|
+
const blocker = await ownGitignoreBlocker(rootDir, path)
|
|
149
|
+
if (blocker) throw new Error(`${refusal}: ${blocker}`)
|
|
150
|
+
if (ownGitignoreState(rootDir, path) === 'in place') return false
|
|
151
|
+
|
|
152
|
+
const files = projectFiles(rootDir)
|
|
153
|
+
await files.mkdir(join(rootDir, posix.dirname(path)), { recursive: true })
|
|
154
|
+
try {
|
|
155
|
+
await files.writeFile(join(rootDir, path), CONTENTS[path], { flag: 'wx' })
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error.code !== 'EEXIST') throw error
|
|
158
|
+
// Another run wrote one in the meantime, which counts only if it is one that works
|
|
159
|
+
const blockerNow = await ownGitignoreBlocker(rootDir, path)
|
|
160
|
+
if (blockerNow) throw new Error(`${refusal}: ${blockerNow}`)
|
|
161
|
+
return false
|
|
162
|
+
}
|
|
163
|
+
return true
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The files git tracks under `directory` of the project, as git names them from
|
|
168
|
+
* the project root; none when the project is not in a git repository or git is
|
|
169
|
+
* not installed.
|
|
170
|
+
*
|
|
171
|
+
* @param {string} rootDir - The project root
|
|
172
|
+
* @param {string} directory - A directory from the project root
|
|
173
|
+
* @returns {string[]}
|
|
174
|
+
*/
|
|
175
|
+
export function trackedFilesUnder(rootDir, directory) {
|
|
176
|
+
try {
|
|
177
|
+
return execFileSync('git', ['ls-files', '-z', '--', directory], {
|
|
178
|
+
cwd: rootDir,
|
|
179
|
+
encoding: 'utf8',
|
|
180
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
181
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
182
|
+
}).split('\0').filter(Boolean)
|
|
183
|
+
} catch {
|
|
184
|
+
return []
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* What to say when git tracks registries: that the build rewrites them and
|
|
190
|
+
* their .gitignore can't keep them out, and how to stop tracking them.
|
|
191
|
+
*
|
|
192
|
+
* @param {number} count - How many files git tracks under .nextspark/registries
|
|
193
|
+
* @returns {string[]} One line each
|
|
194
|
+
*/
|
|
195
|
+
export function trackedRegistriesLines(count) {
|
|
196
|
+
return [
|
|
197
|
+
`.nextspark/registries is tracked by git (${count} file(s)), but every registry build rewrites it: its .gitignore keeps out only what git does not track yet, so each build leaves those files modified in git.`,
|
|
198
|
+
'To stop tracking it: git rm -r --cached .nextspark/registries',
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Give .nextspark/backups its .gitignore before the first backup is written.
|
|
204
|
+
*
|
|
205
|
+
* @param {string} rootDir - The project root
|
|
206
|
+
* @returns {Promise<boolean>} Whether it was written
|
|
207
|
+
*/
|
|
208
|
+
export function ensureBackupsGitignore(rootDir) {
|
|
209
|
+
return ensureOwnGitignore(rootDir, BACKUPS_GITIGNORE, 'Nothing is backed up under .nextspark/backups')
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Give .nextspark/registries its .gitignore before the first registry is written.
|
|
214
|
+
*
|
|
215
|
+
* @param {string} rootDir - The project root
|
|
216
|
+
* @returns {Promise<boolean>} Whether it was written
|
|
217
|
+
*/
|
|
218
|
+
export function ensureRegistriesGitignore(rootDir) {
|
|
219
|
+
return ensureOwnGitignore(rootDir, REGISTRIES_GITIGNORE, 'No registry is written under .nextspark/registries')
|
|
220
|
+
}
|