bsmnt 0.4.3 → 0.6.0
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/README.md +1 -0
- package/dist/application/add-hooks/index.d.ts.map +1 -1
- package/dist/application/add-hooks/index.js +1 -0
- package/dist/application/add-hooks/index.js.map +1 -1
- package/dist/application/add-integration/index.d.ts +33 -8
- package/dist/application/add-integration/index.d.ts.map +1 -1
- package/dist/application/add-integration/index.js +221 -90
- package/dist/application/add-integration/index.js.map +1 -1
- package/dist/application/create-project/build-context.d.ts +3 -1
- package/dist/application/create-project/build-context.d.ts.map +1 -1
- package/dist/application/create-project/build-context.js +2 -1
- package/dist/application/create-project/build-context.js.map +1 -1
- package/dist/application/create-project/index.d.ts +3 -1
- package/dist/application/create-project/index.d.ts.map +1 -1
- package/dist/application/create-project/index.js +4 -2
- package/dist/application/create-project/index.js.map +1 -1
- package/dist/application/create-project/map-selection-to-registry.js +1 -1
- package/dist/application/create-project/map-selection-to-registry.js.map +1 -1
- package/dist/application/install-skills/index.js +1 -1
- package/dist/application/install-skills/index.js.map +1 -1
- package/dist/application/shared/project-detection.d.ts +2 -2
- package/dist/application/shared/project-detection.d.ts.map +1 -1
- package/dist/application/shared/project-detection.js +2 -2
- package/dist/application/shared/project-detection.js.map +1 -1
- package/dist/core/create/execute-plan.d.ts +4 -0
- package/dist/core/create/execute-plan.d.ts.map +1 -1
- package/dist/core/create/execute-plan.js +8 -0
- package/dist/core/create/execute-plan.js.map +1 -1
- package/dist/core/create/internal-ids.d.ts +4 -1
- package/dist/core/create/internal-ids.d.ts.map +1 -1
- package/dist/core/create/internal-ids.js +6 -1
- package/dist/core/create/internal-ids.js.map +1 -1
- package/dist/core/create/types.d.ts +2 -0
- package/dist/core/create/types.d.ts.map +1 -1
- package/dist/domain/cms.d.ts +0 -7
- package/dist/domain/cms.d.ts.map +1 -1
- package/dist/domain/cms.js.map +1 -1
- package/dist/domain/forms.d.ts +17 -0
- package/dist/domain/forms.d.ts.map +1 -0
- package/dist/domain/forms.js +13 -0
- package/dist/domain/forms.js.map +1 -0
- package/dist/domain/integration.d.ts +30 -0
- package/dist/domain/integration.d.ts.map +1 -0
- package/dist/domain/integration.js +12 -0
- package/dist/domain/integration.js.map +1 -0
- package/dist/domain/skills.d.ts +58 -0
- package/dist/domain/skills.d.ts.map +1 -1
- package/dist/domain/skills.js +52 -0
- package/dist/domain/skills.js.map +1 -1
- package/dist/index.js +114 -38
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/agents/register-sanity-mcp.js +9 -6
- package/dist/infrastructure/agents/register-sanity-mcp.js.map +1 -1
- package/dist/infrastructure/create/apply-package-json.d.ts.map +1 -1
- package/dist/infrastructure/create/apply-package-json.js +19 -0
- package/dist/infrastructure/create/apply-package-json.js.map +1 -1
- package/dist/infrastructure/create/executor.d.ts.map +1 -1
- package/dist/infrastructure/create/executor.js +5 -0
- package/dist/infrastructure/create/executor.js.map +1 -1
- package/dist/infrastructure/create/install-dependencies.d.ts.map +1 -1
- package/dist/infrastructure/create/install-dependencies.js +4 -0
- package/dist/infrastructure/create/install-dependencies.js.map +1 -1
- package/dist/infrastructure/create/lifecycle-registry.d.ts.map +1 -1
- package/dist/infrastructure/create/lifecycle-registry.js +2 -0
- package/dist/infrastructure/create/lifecycle-registry.js.map +1 -1
- package/dist/infrastructure/create/merge-registry.d.ts.map +1 -1
- package/dist/infrastructure/create/merge-registry.js +8 -0
- package/dist/infrastructure/create/merge-registry.js.map +1 -1
- package/dist/infrastructure/create/setup-agent.d.ts +2 -0
- package/dist/infrastructure/create/setup-agent.d.ts.map +1 -1
- package/dist/infrastructure/create/setup-agent.js +32 -8
- package/dist/infrastructure/create/setup-agent.js.map +1 -1
- package/dist/infrastructure/create/setup-dotenvx.d.ts +41 -0
- package/dist/infrastructure/create/setup-dotenvx.d.ts.map +1 -0
- package/dist/infrastructure/create/setup-dotenvx.js +502 -0
- package/dist/infrastructure/create/setup-dotenvx.js.map +1 -0
- package/dist/infrastructure/create/setup-sanity.d.ts +13 -1
- package/dist/infrastructure/create/setup-sanity.d.ts.map +1 -1
- package/dist/infrastructure/create/setup-sanity.js +74 -31
- package/dist/infrastructure/create/setup-sanity.js.map +1 -1
- package/dist/infrastructure/integrations/inject-integration.d.ts +3 -3
- package/dist/infrastructure/integrations/inject-integration.d.ts.map +1 -1
- package/dist/infrastructure/integrations/inject-integration.js +81 -37
- package/dist/infrastructure/integrations/inject-integration.js.map +1 -1
- package/dist/modules/features/cms/sanity/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/config.js +13 -6
- package/dist/modules/features/cms/sanity/config.js.map +1 -1
- package/dist/modules/features/cms/sanity/index.js +8 -2
- package/dist/modules/features/cms/sanity/index.js.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.d.ts +13 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.d.ts.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.js +38 -0
- package/dist/modules/features/cms/sanity/mergers/ci-workflow.js.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/knip.d.ts +12 -0
- package/dist/modules/features/cms/sanity/mergers/knip.d.ts.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/knip.js +38 -0
- package/dist/modules/features/cms/sanity/mergers/knip.js.map +1 -0
- package/dist/modules/features/cms/sanity/mergers/layout.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/layout.js +17 -3
- package/dist/modules/features/cms/sanity/mergers/layout.js.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts +3 -3
- package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity/mergers/sitemap.js +48 -62
- package/dist/modules/features/cms/sanity/mergers/sitemap.js.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/config.js +8 -5
- package/dist/modules/features/cms/sanity-pagebuilder/config.js.map +1 -1
- package/dist/modules/features/cms/sanity-pagebuilder/index.js +2 -2
- package/dist/modules/features/cms/sanity-pagebuilder/index.js.map +1 -1
- package/dist/modules/features/env/dotenvx/config.d.ts +13 -0
- package/dist/modules/features/env/dotenvx/config.d.ts.map +1 -0
- package/dist/modules/features/env/dotenvx/config.js +47 -0
- package/dist/modules/features/env/dotenvx/config.js.map +1 -0
- package/dist/modules/features/forms/hubspot/config.d.ts +31 -0
- package/dist/modules/features/forms/hubspot/config.d.ts.map +1 -0
- package/dist/modules/features/forms/hubspot/config.js +25 -0
- package/dist/modules/features/forms/hubspot/config.js.map +1 -0
- package/dist/paths.d.ts +16 -0
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +16 -0
- package/dist/paths.js.map +1 -1
- package/package.json +21 -9
- package/src/agent-skills/json-ld/SKILL.md +85 -0
- package/src/agent-skills/manage-env/SKILL.md +67 -0
- package/src/assets/check-node-version.mjs +22 -0
- package/src/modules/features/cms/sanity/files/app/blog/[slug]/page.tsx +48 -21
- package/src/modules/features/cms/sanity/files/app/blog/page.tsx +54 -0
- package/src/modules/features/cms/sanity/files/app/feed.xml/route.ts +36 -0
- package/src/modules/features/cms/sanity/files/components/sanity/structured-data.tsx +83 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/components/disable-draft-mode.tsx +3 -3
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/queries.ts +14 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/sanity.config.ts +19 -3
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/sanity.types.ts +1 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/article.ts +7 -7
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/index.ts +36 -1
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/metadata.ts +12 -1
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/structured-data-blocks.ts +416 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/schemas/structured-data.ts +100 -0
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/structure.ts +37 -2
- package/src/modules/features/cms/sanity/files/lib/integrations/sanity/utils/page-json-ld.ts +208 -0
- package/src/modules/features/cms/sanity/files/lib/scripts/setup-ci-secrets.ts +117 -0
- package/src/modules/features/cms/sanity/files/lib/utils/rss.ts +96 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/.knip.json +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/[[...slug]]/route.ts +100 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/draft-mode/disable/route.ts +7 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/draft-mode/enable/route.ts +20 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/api/revalidate/route.ts +126 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/feed.xml/route.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/sitemap.md/route.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/app/studio/[[...tool]]/page.tsx +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/draft-mode-toggle.tsx +27 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/rich-text.tsx +87 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/visual-editing.tsx +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/components/ui/sanity-image/index.tsx +41 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/check-integration.ts +5 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/client.ts +27 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/disable-draft-mode.tsx +23 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-builder-input.tsx +39 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/page-category-input.tsx +50 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/same-as-input.tsx +66 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/slug-field.tsx +18 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/components/slug-input.tsx +14 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/confirm-publish-action.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/env.ts +34 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/fetchers/layout.ts +67 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/fetchers/redirects.ts +17 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/icons.ts +79 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/live/index.tsx +88 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/markdown-proxy.config.ts +50 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-builder-config.ts +130 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-category.ts +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/page-tree-pane.tsx +420 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/pinned-pages.ts +54 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/presentation.ts +119 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/queries.ts +407 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.cli.ts +29 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/sanity.config.ts +113 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/index.ts +4 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +89 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/description.ts +29 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/reusable/hero.ts +28 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/components/singleton/content-collection.ts +45 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/content/author.ts +70 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/content/blog-category.ts +55 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/index.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/company-data.ts +70 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/footer.ts +79 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/navbar.ts +75 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/redirect.ts +120 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/layout/structured-data.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/link.ts +125 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/logo-field.ts +9 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/metadata.ts +79 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/nav-objects.ts +192 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page-builder.ts +39 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page-folder.ts +124 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/page.ts +242 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/richText.ts +63 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/schemas/shared/structured-data-blocks.ts +436 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/singletons.ts +51 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/structure.ts +330 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/image.ts +8 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/link.ts +140 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/page-builder-markdown.ts +81 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/integrations/sanity/utils/page-json-ld.ts +208 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/scripts/sanity-typegen.ts +45 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/check-redirect.ts +30 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/json-ld.tsx +521 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/metadata.ts +167 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/rss.ts +96 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/lib/utils/sitemap.ts +40 -0
- package/src/modules/features/cms/sanity-pagebuilder/files/proxy.ts +81 -0
- package/src/modules/features/env/dotenvx/files/decrypt-env.mjs +45 -0
- package/src/modules/features/env/dotenvx/files/gitleaks.yml +25 -0
- package/src/modules/features/env/dotenvx/files/instrumentation.ts +14 -0
- package/src/modules/features/env/dotenvx/files/push-keys.mjs +129 -0
- package/src/modules/features/env/dotenvx/files/save-key.mjs +108 -0
- package/src/modules/features/env/dotenvx/files/setup-env.mjs +67 -0
- package/src/modules/features/env/dotenvx/files/vercelignore +4 -0
- package/src/modules/features/env/dotenvx/files/write-env.mjs +47 -0
- package/src/templates/next-default/.env.example +14 -6
- package/src/templates/next-default/.github/workflows/ci.yml +83 -0
- package/src/templates/next-default/.vscode/extensions.json +3 -0
- package/src/templates/next-default/README.md +53 -0
- package/src/templates/next-default/knip.json +14 -0
- package/src/templates/next-default/lefthook.yml +5 -0
- package/src/templates/next-default/lib/utils/json-ld.tsx +327 -21
- package/src/templates/next-default/next.config.ts +6 -0
- package/src/templates/next-default/package.json +8 -4
- package/src/templates/next-experiments/.env.example +14 -6
- package/src/templates/next-experiments/.github/workflows/ci.yml +83 -0
- package/src/templates/next-experiments/.vscode/extensions.json +3 -0
- package/src/templates/next-experiments/README.md +53 -0
- package/src/templates/next-experiments/knip.json +14 -0
- package/src/templates/next-experiments/lefthook.yml +30 -0
- package/src/templates/next-experiments/lib/utils/json-ld.tsx +327 -21
- package/src/templates/next-experiments/next.config.ts +6 -0
- package/src/templates/next-experiments/package.json +10 -2
- package/src/templates/next-pagebuilder/.env.example +19 -1
- package/src/templates/next-pagebuilder/.github/workflows/ci.yml +90 -0
- package/src/templates/next-pagebuilder/.vscode/extensions.json +3 -0
- package/src/templates/next-pagebuilder/README.md +65 -0
- package/src/templates/next-pagebuilder/app/(content)/[[...slug]]/page.tsx +6 -1
- package/src/templates/next-pagebuilder/app/(content)/layout.tsx +3 -12
- package/src/templates/next-pagebuilder/components/layout/footer/index.tsx +11 -10
- package/src/templates/next-pagebuilder/components/layout/header/index.tsx +5 -3
- package/src/templates/next-pagebuilder/components/layout/json-ld/index.tsx +38 -26
- package/src/templates/next-pagebuilder/components/layout/wrapper/index.tsx +3 -11
- package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/index.tsx +1 -1
- package/src/templates/next-pagebuilder/components/page-document/index.tsx +38 -0
- package/src/templates/next-pagebuilder/knip.json +27 -0
- package/src/templates/next-pagebuilder/lefthook.yml +5 -0
- package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.types.ts +36 -2
- package/src/templates/next-pagebuilder/lib/scripts/setup-ci-secrets.ts +117 -0
- package/src/templates/next-pagebuilder/next.config.ts +6 -0
- package/src/templates/next-pagebuilder/package.json +9 -3
- package/src/templates/next-webgl/.env.example +14 -6
- package/src/templates/next-webgl/.github/workflows/ci.yml +83 -0
- package/src/templates/next-webgl/.vscode/extensions.json +3 -0
- package/src/templates/next-webgl/README.md +53 -0
- package/src/templates/next-webgl/knip.json +13 -0
- package/src/templates/next-webgl/lefthook.yml +5 -0
- package/src/templates/next-webgl/lib/utils/json-ld.tsx +327 -21
- package/src/templates/next-webgl/next.config.ts +6 -0
- package/src/templates/next-webgl/package.json +8 -4
- package/src/modules/features/cms/sanity/files/lib/utils/json-ld.tsx +0 -244
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { revalidatePath, revalidateTag } from "next/cache";
|
|
2
|
+
import { type NextRequest, NextResponse } from "next/server";
|
|
3
|
+
import { parseBody } from "next-sanity/webhook";
|
|
4
|
+
import { client } from "@/lib/integrations/sanity/client";
|
|
5
|
+
import { SANITY_LAYOUT_TAGS } from "@/lib/integrations/sanity/fetchers/layout";
|
|
6
|
+
import { SANITY_REDIRECTS_TAG } from "@/lib/integrations/sanity/fetchers/redirects";
|
|
7
|
+
import { pageBuilderReferenceMembers as pbrm } from "@/lib/integrations/sanity/page-builder-config";
|
|
8
|
+
import {
|
|
9
|
+
P_REF_PB_COMP_QUERY,
|
|
10
|
+
P_REV_SLUGS_QUERY,
|
|
11
|
+
} from "@/lib/integrations/sanity/queries";
|
|
12
|
+
import type { P_REF_PB_COMP_QUERY_RESULT } from "@/lib/integrations/sanity/sanity.types";
|
|
13
|
+
import { getPagePath } from "@/lib/utils/sitemap";
|
|
14
|
+
|
|
15
|
+
const ERRORS = {
|
|
16
|
+
BAD_REQ: ["Bad Request", { status: 400 }],
|
|
17
|
+
INVALID_SIG: ["Invalid signature", { status: 401 }],
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
type WebhookSlug = {
|
|
21
|
+
current?: string | null;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type WebhookDocument = {
|
|
25
|
+
_id: string;
|
|
26
|
+
_type: string;
|
|
27
|
+
resolvedSlug?: string | null;
|
|
28
|
+
slug?: WebhookSlug | null;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
type MutationOperation = "create" | "update" | "delete";
|
|
32
|
+
|
|
33
|
+
type RevalidateWebhookBody = WebhookDocument & {
|
|
34
|
+
operation?: MutationOperation;
|
|
35
|
+
before?: Partial<WebhookDocument> | null;
|
|
36
|
+
after?: Partial<WebhookDocument> | null;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const pageBuilderComponent = new Set<string>(pbrm.map((m) => m.documentType));
|
|
40
|
+
|
|
41
|
+
const normalizeRevalidationSlug = (slug: string | null | undefined) => {
|
|
42
|
+
if (slug === undefined) return null;
|
|
43
|
+
if (slug === null) return "/";
|
|
44
|
+
return `/${slug}`;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const getCanonicalPageSlug = async (documentId: string) => {
|
|
48
|
+
if (!client) return null;
|
|
49
|
+
|
|
50
|
+
const pageSlugs = await client.fetch<Array<{ slug: string | null }>>(
|
|
51
|
+
P_REV_SLUGS_QUERY,
|
|
52
|
+
{ documentIds: [documentId] },
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return normalizeRevalidationSlug(
|
|
56
|
+
pageSlugs.find((page) => page.slug !== undefined)?.slug,
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const getPagesThatReferenceComp = async (documentId: string) => {
|
|
61
|
+
if (!client) return [];
|
|
62
|
+
|
|
63
|
+
const pages = await client.fetch<P_REF_PB_COMP_QUERY_RESULT>(
|
|
64
|
+
P_REF_PB_COMP_QUERY,
|
|
65
|
+
{
|
|
66
|
+
documentId,
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return (pages ?? []).map((page) => normalizeRevalidationSlug(page.slug));
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const getAffectedPageSlugsForWebhook = async (body: RevalidateWebhookBody) => {
|
|
74
|
+
const pages: Array<string | null> = [];
|
|
75
|
+
|
|
76
|
+
if (body.operation === "delete" && body?.before?.slug?.current) {
|
|
77
|
+
revalidateTag(body.before.slug.current, "max");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// If the document is a page, get its slug
|
|
81
|
+
if (body._type === "page") {
|
|
82
|
+
const data = await getCanonicalPageSlug(body._id);
|
|
83
|
+
if (data !== null) pages.push(data);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If the document is a page builder component, get the page slugs that reference it
|
|
87
|
+
if (pageBuilderComponent.has(body._type)) {
|
|
88
|
+
const data = await getPagesThatReferenceComp(body._id);
|
|
89
|
+
pages.push(...data);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return pages.filter((page): page is string => page !== null);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export async function POST(request: NextRequest) {
|
|
96
|
+
try {
|
|
97
|
+
const { body, isValidSignature } = await parseBody<RevalidateWebhookBody>(
|
|
98
|
+
request,
|
|
99
|
+
process.env.SANITY_REVALIDATE_SECRET,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (!isValidSignature) return new Response(...ERRORS.INVALID_SIG);
|
|
103
|
+
if (!(body?._type && body._id)) return new Response(...ERRORS.BAD_REQ);
|
|
104
|
+
if (body._id.startsWith("drafts."))
|
|
105
|
+
return NextResponse.json({ status: 200, now: Date.now(), skipped: true });
|
|
106
|
+
|
|
107
|
+
const affectedPageSlugs = await getAffectedPageSlugsForWebhook(body);
|
|
108
|
+
|
|
109
|
+
for (const slug of affectedPageSlugs) {
|
|
110
|
+
revalidatePath(getPagePath(slug));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (SANITY_LAYOUT_TAGS.includes(body?._type)) {
|
|
114
|
+
revalidateTag(body._type, "max");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (body._type === SANITY_REDIRECTS_TAG) {
|
|
118
|
+
revalidateTag(SANITY_REDIRECTS_TAG, "max");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return NextResponse.json({ status: 200, now: Date.now() });
|
|
122
|
+
} catch (error) {
|
|
123
|
+
console.error("Revalidation error:", error);
|
|
124
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ALL_BLOG_ARTICLES_QUERY } from "@/lib/integrations/sanity/queries";
|
|
2
|
+
import { generateRssFeed, rssErrorResponse } from "@/lib/utils/rss";
|
|
3
|
+
import { getPageUrl, getSitemapBaseUrl } from "@/lib/utils/sitemap";
|
|
4
|
+
|
|
5
|
+
export const dynamic = "force-dynamic";
|
|
6
|
+
|
|
7
|
+
export async function GET() {
|
|
8
|
+
const baseUrl = getSitemapBaseUrl();
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const sanityModule = await import("@/lib/integrations/sanity/client");
|
|
12
|
+
const client = sanityModule?.client;
|
|
13
|
+
if (!client) return rssErrorResponse();
|
|
14
|
+
|
|
15
|
+
const articles = await client.fetch(ALL_BLOG_ARTICLES_QUERY);
|
|
16
|
+
|
|
17
|
+
const items = (articles ?? [])
|
|
18
|
+
.filter((article) => article.resolvedSlug && !article.noIndex)
|
|
19
|
+
.map((article) => ({
|
|
20
|
+
title: article.title ?? "Untitled",
|
|
21
|
+
link: getPageUrl(baseUrl, article.resolvedSlug),
|
|
22
|
+
description: article.metadata?.metaDescription ?? undefined,
|
|
23
|
+
pubDate: article.blogContent?.date ?? undefined,
|
|
24
|
+
authors: article.blogContent?.author?.name
|
|
25
|
+
? [article.blogContent.author.name]
|
|
26
|
+
: undefined,
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
return generateRssFeed({
|
|
30
|
+
title: `${new URL(baseUrl).hostname} Blog`,
|
|
31
|
+
link: `${baseUrl}/blog`,
|
|
32
|
+
description: "Latest articles",
|
|
33
|
+
feedUrl: `${baseUrl}/feed.xml`,
|
|
34
|
+
items,
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error("Error generating RSS feed:", error);
|
|
38
|
+
return rssErrorResponse();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { isSanityConfigured } from "@/lib/integrations/check-integration";
|
|
3
|
+
import type { PAGE_SITEMAP_QUERY_RESULT } from "@/lib/integrations/sanity/sanity.types";
|
|
4
|
+
import {
|
|
5
|
+
getMarkdownPath,
|
|
6
|
+
getSitemap,
|
|
7
|
+
getSitemapBaseUrl,
|
|
8
|
+
} from "@/lib/utils/sitemap";
|
|
9
|
+
|
|
10
|
+
export const dynamic = "force-dynamic";
|
|
11
|
+
|
|
12
|
+
type PageDoc = PAGE_SITEMAP_QUERY_RESULT[number];
|
|
13
|
+
|
|
14
|
+
const ROOT_GROUP = "__root__";
|
|
15
|
+
|
|
16
|
+
const getFolderGroup = (slug: string | null) => {
|
|
17
|
+
if (!slug) return ROOT_GROUP;
|
|
18
|
+
|
|
19
|
+
const segments = slug.split("/").filter(Boolean);
|
|
20
|
+
|
|
21
|
+
if (segments.length <= 1) return ROOT_GROUP;
|
|
22
|
+
|
|
23
|
+
return segments.slice(0, -1).join("/");
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const getGroupHeading = (group: string) => {
|
|
27
|
+
if (group === ROOT_GROUP) return "### Root Pages";
|
|
28
|
+
|
|
29
|
+
return `### /${group}`;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const sortPages = (left: PageDoc, right: PageDoc) => {
|
|
33
|
+
const leftLabel = left.title || left.slug || "Homepage";
|
|
34
|
+
const rightLabel = right.title || right.slug || "Homepage";
|
|
35
|
+
|
|
36
|
+
return leftLabel.localeCompare(rightLabel);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const GET = async () => {
|
|
40
|
+
const baseUrl = getSitemapBaseUrl();
|
|
41
|
+
|
|
42
|
+
if (!isSanityConfigured()) {
|
|
43
|
+
return new NextResponse(
|
|
44
|
+
[
|
|
45
|
+
"# Sitemap",
|
|
46
|
+
"",
|
|
47
|
+
"## Pages",
|
|
48
|
+
"",
|
|
49
|
+
`- [Homepage](${baseUrl}/index.md)`,
|
|
50
|
+
"",
|
|
51
|
+
"CMS not configured. No additional content available.",
|
|
52
|
+
].join("\n"),
|
|
53
|
+
{
|
|
54
|
+
headers: { "Content-Type": "text/markdown; charset=utf-8" },
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const allPages = await getSitemap();
|
|
61
|
+
|
|
62
|
+
if (!allPages) {
|
|
63
|
+
return new NextResponse("# Sitemap\n\nUnable to connect to CMS.", {
|
|
64
|
+
status: 503,
|
|
65
|
+
headers: { "Content-Type": "text/markdown; charset=utf-8" },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const pages = (allPages ?? []).filter((page) => !page.noIndex);
|
|
70
|
+
const pageGroups = new Map<string, PageDoc[]>();
|
|
71
|
+
|
|
72
|
+
for (const page of pages) {
|
|
73
|
+
const group = getFolderGroup(page.slug ?? null);
|
|
74
|
+
const groupedPages = pageGroups.get(group) ?? [];
|
|
75
|
+
|
|
76
|
+
groupedPages.push(page);
|
|
77
|
+
pageGroups.set(group, groupedPages);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const sortedGroupNames = [...pageGroups.keys()].sort((left, right) => {
|
|
81
|
+
if (left === ROOT_GROUP) return -1;
|
|
82
|
+
if (right === ROOT_GROUP) return 1;
|
|
83
|
+
|
|
84
|
+
return left.localeCompare(right);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const parts = [
|
|
88
|
+
`# ${new URL(baseUrl).hostname} - Content Sitemap`,
|
|
89
|
+
"",
|
|
90
|
+
"> This sitemap lists all available markdown content for AI agents.",
|
|
91
|
+
"",
|
|
92
|
+
"## Pages",
|
|
93
|
+
"",
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
if (pages.length > 0) {
|
|
97
|
+
for (const groupName of sortedGroupNames) {
|
|
98
|
+
const groupedPages = (pageGroups.get(groupName) ?? []).sort(sortPages);
|
|
99
|
+
|
|
100
|
+
if (groupedPages.length === 0) continue;
|
|
101
|
+
|
|
102
|
+
parts.push(getGroupHeading(groupName), "");
|
|
103
|
+
|
|
104
|
+
for (const page of groupedPages) {
|
|
105
|
+
parts.push(
|
|
106
|
+
`- [${page.title || page.slug || "Homepage"}](${getMarkdownPath(baseUrl, page.slug ?? null)})`,
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
parts.push("");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (pages.length === 0) parts.push("No content published yet.", "");
|
|
115
|
+
|
|
116
|
+
return new NextResponse(parts.join("\n"));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error("Error generating sitemap.md:", error);
|
|
119
|
+
return new NextResponse("# Sitemap\n\nError fetching content.", {
|
|
120
|
+
status: 500,
|
|
121
|
+
headers: { "Content-Type": "text/markdown; charset=utf-8" },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/draft-mode-toggle.tsx
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useRouter } from "next/navigation";
|
|
4
|
+
import { useTransition } from "react";
|
|
5
|
+
|
|
6
|
+
export function DraftModeToggle() {
|
|
7
|
+
const router = useRouter();
|
|
8
|
+
const [isPending, startTransition] = useTransition();
|
|
9
|
+
|
|
10
|
+
const handleDisable = () => {
|
|
11
|
+
startTransition(async () => {
|
|
12
|
+
await fetch("/api/draft-mode/disable");
|
|
13
|
+
router.refresh();
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<button
|
|
19
|
+
type="button"
|
|
20
|
+
onClick={handleDisable}
|
|
21
|
+
disabled={isPending}
|
|
22
|
+
className="fixed bottom-4 left-1/2 z-50 -translate-x-1/2 rounded-full border border-white/10 bg-black/80 px-2 py-1 font-medium text-sm text-white shadow-lg backdrop-blur-sm transition-colors hover:bg-black/90 disabled:opacity-50"
|
|
23
|
+
>
|
|
24
|
+
{isPending ? "Disabling..." : "Disable Draft Mode"}
|
|
25
|
+
</button>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { PortableText, type PortableTextProps } from "@portabletext/react";
|
|
2
|
+
import { Link } from "@/components/ui/link";
|
|
3
|
+
import { SanityImage } from "@/components/ui/sanity-image";
|
|
4
|
+
import {
|
|
5
|
+
getLinkAttributes,
|
|
6
|
+
urlForReference,
|
|
7
|
+
} from "../../lib/integrations/sanity/utils/link";
|
|
8
|
+
|
|
9
|
+
interface RichTextProps {
|
|
10
|
+
content: PortableTextProps["value"];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type LinkMarkProps = {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
value?: unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const LinkMark = ({ children, value }: LinkMarkProps) => {
|
|
19
|
+
const href = urlForReference(value as Parameters<typeof urlForReference>[0]);
|
|
20
|
+
const attrs = getLinkAttributes(
|
|
21
|
+
value as Parameters<typeof getLinkAttributes>[0],
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Link
|
|
26
|
+
href={href}
|
|
27
|
+
target={attrs.target}
|
|
28
|
+
rel={attrs.rel}
|
|
29
|
+
data-sanity-edit-target
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</Link>
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const RichText = ({ content }: RichTextProps) => {
|
|
37
|
+
if (!content) return null;
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<PortableText
|
|
41
|
+
value={content}
|
|
42
|
+
components={{
|
|
43
|
+
types: {
|
|
44
|
+
image: ({ value }) => <SanityImage image={value} maxWidth={1920} />,
|
|
45
|
+
table: ({ value }) => {
|
|
46
|
+
const rows = value?.rows as
|
|
47
|
+
| Array<{ _key?: string; cells?: string[] }>
|
|
48
|
+
| undefined;
|
|
49
|
+
if (!rows?.length) return null;
|
|
50
|
+
return (
|
|
51
|
+
<table>
|
|
52
|
+
<tbody>
|
|
53
|
+
{rows.map((row, i) => (
|
|
54
|
+
<tr key={row._key ?? `row-${i}`}>
|
|
55
|
+
{row.cells?.map((cell) => {
|
|
56
|
+
const cellKey = `${row._key}-${cell}`;
|
|
57
|
+
return i === 0 ? (
|
|
58
|
+
<th key={cellKey}>{cell}</th>
|
|
59
|
+
) : (
|
|
60
|
+
<td key={cellKey}>{cell}</td>
|
|
61
|
+
);
|
|
62
|
+
})}
|
|
63
|
+
</tr>
|
|
64
|
+
))}
|
|
65
|
+
</tbody>
|
|
66
|
+
</table>
|
|
67
|
+
);
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
marks: {
|
|
71
|
+
link: LinkMark,
|
|
72
|
+
pageReference: LinkMark,
|
|
73
|
+
externalLink: LinkMark,
|
|
74
|
+
},
|
|
75
|
+
block: {
|
|
76
|
+
h1: ({ children }) => <h1 className="h1">{children}</h1>,
|
|
77
|
+
h2: ({ children }) => <h2 className="h2">{children}</h2>,
|
|
78
|
+
h3: ({ children }) => <h3 className="h3">{children}</h3>,
|
|
79
|
+
h4: ({ children }) => <h4 className="h4">{children}</h4>,
|
|
80
|
+
h5: ({ children }) => <h5 className="h5">{children}</h5>,
|
|
81
|
+
h6: ({ children }) => <h6 className="h6">{children}</h6>,
|
|
82
|
+
normal: ({ children }) => <p className="p">{children}</p>,
|
|
83
|
+
},
|
|
84
|
+
}}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
};
|
package/src/modules/features/cms/sanity-pagebuilder/files/components/sanity/visual-editing.tsx
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { draftMode } from "next/headers";
|
|
2
|
+
import { VisualEditing } from "next-sanity/visual-editing";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
import { refreshAction } from "@/app/actions/refresh";
|
|
5
|
+
import { DraftModeToggle } from "@/components/sanity/draft-mode-toggle";
|
|
6
|
+
import { isSanityConfigured } from "@/lib/integrations/check-integration";
|
|
7
|
+
import { SanityLive } from "@/lib/integrations/sanity/live";
|
|
8
|
+
|
|
9
|
+
async function VisualEditingInner() {
|
|
10
|
+
const { isEnabled: isDraftMode } = await draftMode();
|
|
11
|
+
const sanityConfigured = isSanityConfigured();
|
|
12
|
+
|
|
13
|
+
if (!(sanityConfigured && isDraftMode)) return null;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<DraftModeToggle />
|
|
18
|
+
<VisualEditing />
|
|
19
|
+
<SanityLive action={refreshAction} />
|
|
20
|
+
</>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const SanityVisualEditing = () => (
|
|
25
|
+
<Suspense fallback={null}>
|
|
26
|
+
<VisualEditingInner />
|
|
27
|
+
</Suspense>
|
|
28
|
+
);
|
package/src/modules/features/cms/sanity-pagebuilder/files/components/ui/sanity-image/index.tsx
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getImageDimensions } from "@sanity/asset-utils";
|
|
2
|
+
import { Image, type ImageProps } from "@/components/ui/image";
|
|
3
|
+
import { urlForImage } from "@/lib/integrations/sanity/utils/image";
|
|
4
|
+
|
|
5
|
+
interface SanityImageProps extends Omit<ImageProps, "src" | "aspectRatio"> {
|
|
6
|
+
image: {
|
|
7
|
+
asset?: {
|
|
8
|
+
_ref: string;
|
|
9
|
+
_type: "reference";
|
|
10
|
+
};
|
|
11
|
+
alt?: string;
|
|
12
|
+
hotspot?: object;
|
|
13
|
+
crop?: object;
|
|
14
|
+
};
|
|
15
|
+
maxWidth?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function SanityImage({
|
|
19
|
+
image,
|
|
20
|
+
maxWidth = 1920,
|
|
21
|
+
alt,
|
|
22
|
+
fill,
|
|
23
|
+
...props
|
|
24
|
+
}: SanityImageProps) {
|
|
25
|
+
if (!image?.asset) return null;
|
|
26
|
+
|
|
27
|
+
const { width, height } = getImageDimensions(image.asset);
|
|
28
|
+
const aspectRatio = width / height;
|
|
29
|
+
|
|
30
|
+
const imageProps = fill ? { fill: true } : { width, height };
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<Image
|
|
34
|
+
src={urlForImage(image).width(maxWidth).url()}
|
|
35
|
+
alt={alt || image.alt || ""}
|
|
36
|
+
aspectRatio={aspectRatio}
|
|
37
|
+
{...imageProps}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createClient, type SanityClient } from "next-sanity";
|
|
2
|
+
import { isSanityConfigured } from "@/lib/integrations/check-integration";
|
|
3
|
+
import { apiVersion, dataset, projectId, sanityToken, studioUrl } from "./env";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sanity client instance
|
|
7
|
+
*
|
|
8
|
+
* Returns null if Sanity is not configured (missing env vars).
|
|
9
|
+
* Always check with isSanityConfigured() before using.
|
|
10
|
+
*/
|
|
11
|
+
export const client: SanityClient | null = isSanityConfigured()
|
|
12
|
+
? createClient({
|
|
13
|
+
projectId,
|
|
14
|
+
dataset,
|
|
15
|
+
apiVersion,
|
|
16
|
+
useCdn: true,
|
|
17
|
+
perspective: "published",
|
|
18
|
+
token: sanityToken,
|
|
19
|
+
stega: {
|
|
20
|
+
studioUrl,
|
|
21
|
+
filter: (props) => {
|
|
22
|
+
if (props.sourcePath.at(-1) === "title") return true;
|
|
23
|
+
return props.filterDefault(props);
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
: null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { usePathname } from "next/navigation";
|
|
5
|
+
import { useIsPresentationTool } from "next-sanity/hooks";
|
|
6
|
+
|
|
7
|
+
export function DisableDraftMode() {
|
|
8
|
+
const isPresentationTool = useIsPresentationTool();
|
|
9
|
+
const pathname = usePathname();
|
|
10
|
+
|
|
11
|
+
if (isPresentationTool) return null;
|
|
12
|
+
if (pathname.startsWith("/studio")) return null;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<Link
|
|
16
|
+
href="/api/draft-mode/disable"
|
|
17
|
+
scroll={false}
|
|
18
|
+
className="dr-p-4 fixed top-safe right-safe z-50 bg-red font-mono text-primary text-sm uppercase"
|
|
19
|
+
>
|
|
20
|
+
Disable Draft Mode
|
|
21
|
+
</Link>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type ArrayOfObjectsInputProps, useFormValue } from "sanity";
|
|
2
|
+
import {
|
|
3
|
+
getVisiblePageBuilderInsertMenuGroups,
|
|
4
|
+
getVisiblePageBuilderReferenceMembers,
|
|
5
|
+
type PageBuilderGroupName,
|
|
6
|
+
} from "@/lib/integrations/sanity/page-builder-config";
|
|
7
|
+
|
|
8
|
+
export function PageBuilderInput(props: ArrayOfObjectsInputProps) {
|
|
9
|
+
const pageTypeValue = useFormValue(["type"]);
|
|
10
|
+
const pageType =
|
|
11
|
+
typeof pageTypeValue === "string"
|
|
12
|
+
? (pageTypeValue as PageBuilderGroupName)
|
|
13
|
+
: undefined;
|
|
14
|
+
|
|
15
|
+
const visibleMemberNames = new Set(
|
|
16
|
+
getVisiblePageBuilderReferenceMembers(pageType).map(
|
|
17
|
+
(member) => member.name,
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return props.renderDefault({
|
|
22
|
+
...props,
|
|
23
|
+
schemaType: {
|
|
24
|
+
...props.schemaType,
|
|
25
|
+
of: props.schemaType.of.filter(
|
|
26
|
+
(member) =>
|
|
27
|
+
typeof member.name === "string" &&
|
|
28
|
+
visibleMemberNames.has(member.name),
|
|
29
|
+
),
|
|
30
|
+
options: {
|
|
31
|
+
...props.schemaType.options,
|
|
32
|
+
insertMenu: {
|
|
33
|
+
...props.schemaType.options?.insertMenu,
|
|
34
|
+
groups: getVisiblePageBuilderInsertMenuGroups(pageType),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Select } from "@sanity/ui";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { type StringInputProps, set, setIfMissing } from "sanity";
|
|
4
|
+
|
|
5
|
+
type PageCategoryOption = {
|
|
6
|
+
title: string;
|
|
7
|
+
value: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const isPageCategoryOption = (option: unknown): option is PageCategoryOption =>
|
|
11
|
+
typeof option === "object" &&
|
|
12
|
+
option !== null &&
|
|
13
|
+
"title" in option &&
|
|
14
|
+
"value" in option &&
|
|
15
|
+
typeof option.title === "string" &&
|
|
16
|
+
typeof option.value === "string";
|
|
17
|
+
|
|
18
|
+
export function PageCategoryInput(props: StringInputProps) {
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (props.value === undefined) {
|
|
21
|
+
props.onChange(setIfMissing("generic"));
|
|
22
|
+
}
|
|
23
|
+
}, [props.onChange, props.value]);
|
|
24
|
+
|
|
25
|
+
const options = Array.isArray(props.schemaType.options?.list)
|
|
26
|
+
? props.schemaType.options.list.filter(isPageCategoryOption)
|
|
27
|
+
: [];
|
|
28
|
+
|
|
29
|
+
if (options.length === 0) {
|
|
30
|
+
return props.renderDefault({ ...props, value: props.value ?? "generic" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Select
|
|
35
|
+
{...props.elementProps}
|
|
36
|
+
disabled={props.readOnly}
|
|
37
|
+
onChange={(event) => props.onChange(set(event.currentTarget.value))}
|
|
38
|
+
value={props.value ?? "generic"}
|
|
39
|
+
{...(props.validationError
|
|
40
|
+
? { customValidity: props.validationError }
|
|
41
|
+
: {})}
|
|
42
|
+
>
|
|
43
|
+
{options.map((option) => (
|
|
44
|
+
<option key={option.value} value={option.value}>
|
|
45
|
+
{option.title}
|
|
46
|
+
</option>
|
|
47
|
+
))}
|
|
48
|
+
</Select>
|
|
49
|
+
);
|
|
50
|
+
}
|