@wildo-ai/saas-website 1.1.1
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/LICENSE +34 -0
- package/dist/esm/.builder.pid +9 -0
- package/dist/esm/astro/blog-post-bridge.d.ts +324 -0
- package/dist/esm/astro/blog-post-bridge.d.ts.map +1 -0
- package/dist/esm/astro/blog-post-bridge.js +57 -0
- package/dist/esm/astro/blog-post-bridge.js.map +1 -0
- package/dist/esm/astro/blog-post-head.renderer.d.ts +129 -0
- package/dist/esm/astro/blog-post-head.renderer.d.ts.map +1 -0
- package/dist/esm/astro/blog-post-head.renderer.js +139 -0
- package/dist/esm/astro/blog-post-head.renderer.js.map +1 -0
- package/dist/esm/astro/bridge-runtime.d.ts +224 -0
- package/dist/esm/astro/bridge-runtime.d.ts.map +1 -0
- package/dist/esm/astro/bridge-runtime.js +30 -0
- package/dist/esm/astro/bridge-runtime.js.map +1 -0
- package/dist/esm/astro/collect-expected-label-keys.d.ts +65 -0
- package/dist/esm/astro/collect-expected-label-keys.d.ts.map +1 -0
- package/dist/esm/astro/collect-expected-label-keys.js +101 -0
- package/dist/esm/astro/collect-expected-label-keys.js.map +1 -0
- package/dist/esm/astro/headers-renderer.d.ts +32 -0
- package/dist/esm/astro/headers-renderer.d.ts.map +1 -0
- package/dist/esm/astro/headers-renderer.js +64 -0
- package/dist/esm/astro/headers-renderer.js.map +1 -0
- package/dist/esm/astro/i18n-routing.helper.d.ts +91 -0
- package/dist/esm/astro/i18n-routing.helper.d.ts.map +1 -0
- package/dist/esm/astro/i18n-routing.helper.js +23 -0
- package/dist/esm/astro/i18n-routing.helper.js.map +1 -0
- package/dist/esm/astro/internal/html-escape.d.ts +31 -0
- package/dist/esm/astro/internal/html-escape.d.ts.map +1 -0
- package/dist/esm/astro/internal/html-escape.js +40 -0
- package/dist/esm/astro/internal/html-escape.js.map +1 -0
- package/dist/esm/astro/label-pack-loader.d.ts +134 -0
- package/dist/esm/astro/label-pack-loader.d.ts.map +1 -0
- package/dist/esm/astro/label-pack-loader.js +298 -0
- package/dist/esm/astro/label-pack-loader.js.map +1 -0
- package/dist/esm/astro/llms-txt-server.d.ts +28 -0
- package/dist/esm/astro/llms-txt-server.d.ts.map +1 -0
- package/dist/esm/astro/llms-txt-server.js +33 -0
- package/dist/esm/astro/llms-txt-server.js.map +1 -0
- package/dist/esm/astro/pick-labels-for-page.d.ts +63 -0
- package/dist/esm/astro/pick-labels-for-page.d.ts.map +1 -0
- package/dist/esm/astro/pick-labels-for-page.js +73 -0
- package/dist/esm/astro/pick-labels-for-page.js.map +1 -0
- package/dist/esm/astro/robots-renderer.d.ts +85 -0
- package/dist/esm/astro/robots-renderer.d.ts.map +1 -0
- package/dist/esm/astro/robots-renderer.js +157 -0
- package/dist/esm/astro/robots-renderer.js.map +1 -0
- package/dist/esm/astro/sitemap-coverage.d.ts +101 -0
- package/dist/esm/astro/sitemap-coverage.d.ts.map +1 -0
- package/dist/esm/astro/sitemap-coverage.js +67 -0
- package/dist/esm/astro/sitemap-coverage.js.map +1 -0
- package/dist/esm/astro/structured-data.renderer.d.ts +21 -0
- package/dist/esm/astro/structured-data.renderer.d.ts.map +1 -0
- package/dist/esm/astro/structured-data.renderer.js +142 -0
- package/dist/esm/astro/structured-data.renderer.js.map +1 -0
- package/dist/esm/astro/website-page-head.renderer.d.ts +93 -0
- package/dist/esm/astro/website-page-head.renderer.d.ts.map +1 -0
- package/dist/esm/astro/website-page-head.renderer.js +184 -0
- package/dist/esm/astro/website-page-head.renderer.js.map +1 -0
- package/dist/esm/astro/website-page-runtime.helper.d.ts +112 -0
- package/dist/esm/astro/website-page-runtime.helper.d.ts.map +1 -0
- package/dist/esm/astro/website-page-runtime.helper.js +60 -0
- package/dist/esm/astro/website-page-runtime.helper.js.map +1 -0
- package/dist/esm/astro/website-site-context.d.ts +126 -0
- package/dist/esm/astro/website-site-context.d.ts.map +1 -0
- package/dist/esm/astro/website-site-context.js +37 -0
- package/dist/esm/astro/website-site-context.js.map +1 -0
- package/dist/esm/astro-island.d.ts +56 -0
- package/dist/esm/astro-island.d.ts.map +1 -0
- package/dist/esm/astro-island.js +61 -0
- package/dist/esm/astro-island.js.map +1 -0
- package/dist/esm/astro.d.ts +151 -0
- package/dist/esm/astro.d.ts.map +1 -0
- package/dist/esm/astro.js +151 -0
- package/dist/esm/astro.js.map +1 -0
- package/dist/esm/companion-exports.d.ts +38 -0
- package/dist/esm/companion-exports.d.ts.map +1 -0
- package/dist/esm/companion-exports.js +38 -0
- package/dist/esm/companion-exports.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteButton.d.ts +73 -0
- package/dist/esm/components/low-level/WebsiteButton.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteButton.js +68 -0
- package/dist/esm/components/low-level/WebsiteButton.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteHeading.d.ts +78 -0
- package/dist/esm/components/low-level/WebsiteHeading.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteHeading.js +41 -0
- package/dist/esm/components/low-level/WebsiteHeading.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteImage.d.ts +73 -0
- package/dist/esm/components/low-level/WebsiteImage.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteImage.js +21 -0
- package/dist/esm/components/low-level/WebsiteImage.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteInternalButton.d.ts +90 -0
- package/dist/esm/components/low-level/WebsiteInternalButton.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteInternalButton.js +47 -0
- package/dist/esm/components/low-level/WebsiteInternalButton.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteInternalLink.d.ts +99 -0
- package/dist/esm/components/low-level/WebsiteInternalLink.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteInternalLink.js +68 -0
- package/dist/esm/components/low-level/WebsiteInternalLink.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteLink.d.ts +50 -0
- package/dist/esm/components/low-level/WebsiteLink.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteLink.js +22 -0
- package/dist/esm/components/low-level/WebsiteLink.js.map +1 -0
- package/dist/esm/components/low-level/WebsiteText.d.ts +57 -0
- package/dist/esm/components/low-level/WebsiteText.d.ts.map +1 -0
- package/dist/esm/components/low-level/WebsiteText.js +57 -0
- package/dist/esm/components/low-level/WebsiteText.js.map +1 -0
- package/dist/esm/config/define-website-config.d.ts +83 -0
- package/dist/esm/config/define-website-config.d.ts.map +1 -0
- package/dist/esm/config/define-website-config.js +126 -0
- package/dist/esm/config/define-website-config.js.map +1 -0
- package/dist/esm/config/index.d.ts +38 -0
- package/dist/esm/config/index.d.ts.map +1 -0
- package/dist/esm/config/index.js +38 -0
- package/dist/esm/config/index.js.map +1 -0
- package/dist/esm/config/load-website-config.d.ts +136 -0
- package/dist/esm/config/load-website-config.d.ts.map +1 -0
- package/dist/esm/config/load-website-config.js +177 -0
- package/dist/esm/config/load-website-config.js.map +1 -0
- package/dist/esm/config/wildo-website-config.schemas.d.ts +251 -0
- package/dist/esm/config/wildo-website-config.schemas.d.ts.map +1 -0
- package/dist/esm/config/wildo-website-config.schemas.js +302 -0
- package/dist/esm/config/wildo-website-config.schemas.js.map +1 -0
- package/dist/esm/config-loader.d.ts +35 -0
- package/dist/esm/config-loader.d.ts.map +1 -0
- package/dist/esm/config-loader.js +35 -0
- package/dist/esm/config-loader.js.map +1 -0
- package/dist/esm/core/anonymous-session/InboundContactForm.d.ts +38 -0
- package/dist/esm/core/anonymous-session/InboundContactForm.d.ts.map +1 -0
- package/dist/esm/core/anonymous-session/InboundContactForm.js +77 -0
- package/dist/esm/core/anonymous-session/InboundContactForm.js.map +1 -0
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.d.ts +41 -0
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.d.ts.map +1 -0
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.js +58 -0
- package/dist/esm/core/anonymous-session/inbound-contact-form.schema.js.map +1 -0
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.d.ts +81 -0
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.d.ts.map +1 -0
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.js +177 -0
- package/dist/esm/core/anonymous-session/website-anonymous-session-client.js.map +1 -0
- package/dist/esm/core/contexts/WebsitePageContext.d.ts +40 -0
- package/dist/esm/core/contexts/WebsitePageContext.d.ts.map +1 -0
- package/dist/esm/core/contexts/WebsitePageContext.js +8 -0
- package/dist/esm/core/contexts/WebsitePageContext.js.map +1 -0
- package/dist/esm/core/contexts/WebsiteRuntimeContext.d.ts +162 -0
- package/dist/esm/core/contexts/WebsiteRuntimeContext.d.ts.map +1 -0
- package/dist/esm/core/contexts/WebsiteRuntimeContext.js +22 -0
- package/dist/esm/core/contexts/WebsiteRuntimeContext.js.map +1 -0
- package/dist/esm/core/contexts/WebsiteSectionContext.d.ts +47 -0
- package/dist/esm/core/contexts/WebsiteSectionContext.d.ts.map +1 -0
- package/dist/esm/core/contexts/WebsiteSectionContext.js +8 -0
- package/dist/esm/core/contexts/WebsiteSectionContext.js.map +1 -0
- package/dist/esm/core/contexts/useWebsitePage.d.ts +13 -0
- package/dist/esm/core/contexts/useWebsitePage.d.ts.map +1 -0
- package/dist/esm/core/contexts/useWebsitePage.js +22 -0
- package/dist/esm/core/contexts/useWebsitePage.js.map +1 -0
- package/dist/esm/core/contexts/useWebsiteRuntime.d.ts +19 -0
- package/dist/esm/core/contexts/useWebsiteRuntime.d.ts.map +1 -0
- package/dist/esm/core/contexts/useWebsiteRuntime.js +28 -0
- package/dist/esm/core/contexts/useWebsiteRuntime.js.map +1 -0
- package/dist/esm/core/contexts/useWebsiteSection.d.ts +12 -0
- package/dist/esm/core/contexts/useWebsiteSection.d.ts.map +1 -0
- package/dist/esm/core/contexts/useWebsiteSection.js +22 -0
- package/dist/esm/core/contexts/useWebsiteSection.js.map +1 -0
- package/dist/esm/core/external-providers/frontend-provider-registry.website.d.ts +17 -0
- package/dist/esm/core/external-providers/frontend-provider-registry.website.d.ts.map +1 -0
- package/dist/esm/core/external-providers/frontend-provider-registry.website.js +23 -0
- package/dist/esm/core/external-providers/frontend-provider-registry.website.js.map +1 -0
- package/dist/esm/core/factories/define-website-page-manifest.d.ts +70 -0
- package/dist/esm/core/factories/define-website-page-manifest.d.ts.map +1 -0
- package/dist/esm/core/factories/define-website-page-manifest.js +51 -0
- package/dist/esm/core/factories/define-website-page-manifest.js.map +1 -0
- package/dist/esm/core/factories/define-website-section.d.ts +101 -0
- package/dist/esm/core/factories/define-website-section.d.ts.map +1 -0
- package/dist/esm/core/factories/define-website-section.js +71 -0
- package/dist/esm/core/factories/define-website-section.js.map +1 -0
- package/dist/esm/core/hooks/useWebsiteDesignTokens.d.ts +23 -0
- package/dist/esm/core/hooks/useWebsiteDesignTokens.d.ts.map +1 -0
- package/dist/esm/core/hooks/useWebsiteDesignTokens.js +25 -0
- package/dist/esm/core/hooks/useWebsiteDesignTokens.js.map +1 -0
- package/dist/esm/core/hooks/useWebsiteLabel.d.ts +68 -0
- package/dist/esm/core/hooks/useWebsiteLabel.d.ts.map +1 -0
- package/dist/esm/core/hooks/useWebsiteLabel.js +103 -0
- package/dist/esm/core/hooks/useWebsiteLabel.js.map +1 -0
- package/dist/esm/core/layouts/WebsitePageLayout.d.ts +87 -0
- package/dist/esm/core/layouts/WebsitePageLayout.d.ts.map +1 -0
- package/dist/esm/core/layouts/WebsitePageLayout.js +170 -0
- package/dist/esm/core/layouts/WebsitePageLayout.js.map +1 -0
- package/dist/esm/core/layouts/WebsiteSection.d.ts +91 -0
- package/dist/esm/core/layouts/WebsiteSection.d.ts.map +1 -0
- package/dist/esm/core/layouts/WebsiteSection.js +26 -0
- package/dist/esm/core/layouts/WebsiteSection.js.map +1 -0
- package/dist/esm/core/routing/internal-routing.utils.d.ts +65 -0
- package/dist/esm/core/routing/internal-routing.utils.d.ts.map +1 -0
- package/dist/esm/core/routing/internal-routing.utils.js +14 -0
- package/dist/esm/core/routing/internal-routing.utils.js.map +1 -0
- package/dist/esm/index.d.ts +129 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +129 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/mdx/BlogPost.d.ts +193 -0
- package/dist/esm/mdx/BlogPost.d.ts.map +1 -0
- package/dist/esm/mdx/BlogPost.js +161 -0
- package/dist/esm/mdx/BlogPost.js.map +1 -0
- package/dist/esm/mdx/blog-post-collection.config.d.ts +139 -0
- package/dist/esm/mdx/blog-post-collection.config.d.ts.map +1 -0
- package/dist/esm/mdx/blog-post-collection.config.js +27 -0
- package/dist/esm/mdx/blog-post-collection.config.js.map +1 -0
- package/dist/esm/mdx/blog-post-frontmatter-source.d.ts +12 -0
- package/dist/esm/mdx/blog-post-frontmatter-source.d.ts.map +1 -0
- package/dist/esm/mdx/blog-post-frontmatter-source.js +13 -0
- package/dist/esm/mdx/blog-post-frontmatter-source.js.map +1 -0
- package/dist/esm/mdx/index.d.ts +22 -0
- package/dist/esm/mdx/index.d.ts.map +1 -0
- package/dist/esm/mdx/index.js +22 -0
- package/dist/esm/mdx/index.js.map +1 -0
- package/dist/esm/mdx/website-mdx-provider.d.ts +90 -0
- package/dist/esm/mdx/website-mdx-provider.d.ts.map +1 -0
- package/dist/esm/mdx/website-mdx-provider.js +8 -0
- package/dist/esm/mdx/website-mdx-provider.js.map +1 -0
- package/dist/esm/mdx.d.ts +38 -0
- package/dist/esm/mdx.d.ts.map +1 -0
- package/dist/esm/mdx.js +38 -0
- package/dist/esm/mdx.js.map +1 -0
- package/dist/esm/schemas/blog/blog-post-frontmatter.shared.schemas.d.ts +75 -0
- package/dist/esm/schemas/blog/blog-post-frontmatter.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/blog/blog-post-frontmatter.shared.schemas.js +85 -0
- package/dist/esm/schemas/blog/blog-post-frontmatter.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/design-tokens/website-design-tokens.shared.schemas.d.ts +120 -0
- package/dist/esm/schemas/design-tokens/website-design-tokens.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/design-tokens/website-design-tokens.shared.schemas.js +152 -0
- package/dist/esm/schemas/design-tokens/website-design-tokens.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/label-keys/website-label-key.schemas.d.ts +73 -0
- package/dist/esm/schemas/label-keys/website-label-key.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/label-keys/website-label-key.schemas.js +76 -0
- package/dist/esm/schemas/label-keys/website-label-key.schemas.js.map +1 -0
- package/dist/esm/schemas/manifests/website-page-manifest.shared.schemas.d.ts +209 -0
- package/dist/esm/schemas/manifests/website-page-manifest.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/manifests/website-page-manifest.shared.schemas.js +218 -0
- package/dist/esm/schemas/manifests/website-page-manifest.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/manifests/website-root-config.shared.schemas.d.ts +431 -0
- package/dist/esm/schemas/manifests/website-root-config.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/manifests/website-root-config.shared.schemas.js +438 -0
- package/dist/esm/schemas/manifests/website-root-config.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/refs/page-ref.schemas.d.ts +40 -0
- package/dist/esm/schemas/refs/page-ref.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/refs/page-ref.schemas.js +43 -0
- package/dist/esm/schemas/refs/page-ref.schemas.js.map +1 -0
- package/dist/esm/schemas/refs/section-ref.schemas.d.ts +41 -0
- package/dist/esm/schemas/refs/section-ref.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/refs/section-ref.schemas.js +44 -0
- package/dist/esm/schemas/refs/section-ref.schemas.js.map +1 -0
- package/dist/esm/schemas/sections/website-section-category.shared.d.ts +63 -0
- package/dist/esm/schemas/sections/website-section-category.shared.d.ts.map +1 -0
- package/dist/esm/schemas/sections/website-section-category.shared.js +64 -0
- package/dist/esm/schemas/sections/website-section-category.shared.js.map +1 -0
- package/dist/esm/schemas/sections/website-section-definition.shared.schemas.d.ts +114 -0
- package/dist/esm/schemas/sections/website-section-definition.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/sections/website-section-definition.shared.schemas.js +69 -0
- package/dist/esm/schemas/sections/website-section-definition.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/structured-data/structured-data-reconciliation.shared.d.ts +100 -0
- package/dist/esm/schemas/structured-data/structured-data-reconciliation.shared.d.ts.map +1 -0
- package/dist/esm/schemas/structured-data/structured-data-reconciliation.shared.js +355 -0
- package/dist/esm/schemas/structured-data/structured-data-reconciliation.shared.js.map +1 -0
- package/dist/esm/schemas/structured-data/website-structured-data.shared.schemas.d.ts +58 -0
- package/dist/esm/schemas/structured-data/website-structured-data.shared.schemas.d.ts.map +1 -0
- package/dist/esm/schemas/structured-data/website-structured-data.shared.schemas.js +2 -0
- package/dist/esm/schemas/structured-data/website-structured-data.shared.schemas.js.map +1 -0
- package/dist/esm/schemas/validators/label-pack.validator.d.ts +144 -0
- package/dist/esm/schemas/validators/label-pack.validator.d.ts.map +1 -0
- package/dist/esm/schemas/validators/label-pack.validator.js +100 -0
- package/dist/esm/schemas/validators/label-pack.validator.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +143 -0
- package/src/__tests__/bundle-isolation.test.ts +607 -0
- package/src/astro/__tests__/blog-post-bridge.test.tsx +288 -0
- package/src/astro/__tests__/blog-post-head.renderer.test.ts +249 -0
- package/src/astro/__tests__/bridge-runtime.test.tsx +198 -0
- package/src/astro/__tests__/collect-expected-label-keys.test.ts +69 -0
- package/src/astro/__tests__/headers-renderer.test.ts +143 -0
- package/src/astro/__tests__/i18n-routing.helper.test.ts +116 -0
- package/src/astro/__tests__/label-pack-loader.test.ts +305 -0
- package/src/astro/__tests__/llms-txt-server.test.ts +127 -0
- package/src/astro/__tests__/pick-labels-for-page.test.ts +60 -0
- package/src/astro/__tests__/robots-renderer.test.ts +228 -0
- package/src/astro/__tests__/sitemap-coverage.test.ts +230 -0
- package/src/astro/__tests__/structured-data.renderer.test.ts +172 -0
- package/src/astro/__tests__/website-page-head.renderer.test.ts +424 -0
- package/src/astro/__tests__/website-page-runtime.helper.test.ts +157 -0
- package/src/astro/__tests__/website-site-context.test.ts +121 -0
- package/src/astro/blog-post-bridge.tsx +404 -0
- package/src/astro/blog-post-head.renderer.ts +293 -0
- package/src/astro/bridge-runtime.tsx +270 -0
- package/src/astro/collect-expected-label-keys.ts +113 -0
- package/src/astro/headers-renderer.ts +82 -0
- package/src/astro/i18n-routing.helper.ts +116 -0
- package/src/astro/internal/html-escape.ts +41 -0
- package/src/astro/label-pack-loader.ts +385 -0
- package/src/astro/llms-txt-server.ts +56 -0
- package/src/astro/pick-labels-for-page.ts +85 -0
- package/src/astro/robots-renderer.ts +171 -0
- package/src/astro/sitemap-coverage.ts +186 -0
- package/src/astro/structured-data.renderer.ts +171 -0
- package/src/astro/website-page-head.renderer.ts +279 -0
- package/src/astro/website-page-runtime.helper.ts +188 -0
- package/src/astro/website-site-context.ts +136 -0
- package/src/astro-island.ts +61 -0
- package/src/astro.ts +151 -0
- package/src/companion-exports.ts +38 -0
- package/src/components/low-level/WebsiteButton.tsx +118 -0
- package/src/components/low-level/WebsiteHeading.tsx +96 -0
- package/src/components/low-level/WebsiteImage.tsx +96 -0
- package/src/components/low-level/WebsiteInternalButton.tsx +172 -0
- package/src/components/low-level/WebsiteInternalLink.tsx +193 -0
- package/src/components/low-level/WebsiteLink.tsx +71 -0
- package/src/components/low-level/WebsiteText.tsx +75 -0
- package/src/components/low-level/__tests__/WebsiteInternalButton.test.tsx +169 -0
- package/src/components/low-level/__tests__/WebsiteInternalLink.test.tsx +202 -0
- package/src/components/low-level/__tests__/primitives.test.tsx +141 -0
- package/src/config/__tests__/define-website-config.test.ts +231 -0
- package/src/config/__tests__/load-website-config.test.ts +215 -0
- package/src/config/define-website-config.ts +134 -0
- package/src/config/index.ts +38 -0
- package/src/config/load-website-config.ts +229 -0
- package/src/config/wildo-website-config.schemas.ts +322 -0
- package/src/config-loader.ts +35 -0
- package/src/core/__tests__/WebsitePageLayout.test.tsx +184 -0
- package/src/core/__tests__/WebsiteSection.test.tsx +85 -0
- package/src/core/__tests__/contexts.test.tsx +133 -0
- package/src/core/__tests__/core-boundary.test.ts +85 -0
- package/src/core/__tests__/define-website-page-manifest.test.tsx +111 -0
- package/src/core/__tests__/define-website-section.test.tsx +89 -0
- package/src/core/__tests__/useWebsiteDesignTokens.test.tsx +41 -0
- package/src/core/__tests__/useWebsiteLabel.test.tsx +117 -0
- package/src/core/anonymous-session/InboundContactForm.tsx +157 -0
- package/src/core/anonymous-session/__tests__/inbound-contact-form.schema.test.ts +44 -0
- package/src/core/anonymous-session/inbound-contact-form.schema.ts +62 -0
- package/src/core/anonymous-session/website-anonymous-session-client.ts +194 -0
- package/src/core/contexts/WebsitePageContext.tsx +52 -0
- package/src/core/contexts/WebsiteRuntimeContext.tsx +175 -0
- package/src/core/contexts/WebsiteSectionContext.tsx +59 -0
- package/src/core/contexts/useWebsitePage.ts +28 -0
- package/src/core/contexts/useWebsiteRuntime.ts +34 -0
- package/src/core/contexts/useWebsiteSection.ts +28 -0
- package/src/core/external-providers/frontend-provider-registry.website.ts +62 -0
- package/src/core/factories/define-website-page-manifest.ts +102 -0
- package/src/core/factories/define-website-section.ts +128 -0
- package/src/core/hooks/useWebsiteDesignTokens.ts +26 -0
- package/src/core/hooks/useWebsiteLabel.ts +121 -0
- package/src/core/layouts/WebsitePageLayout.tsx +311 -0
- package/src/core/layouts/WebsiteSection.tsx +139 -0
- package/src/core/routing/__tests__/internal-routing.utils.test.ts +134 -0
- package/src/core/routing/internal-routing.utils.ts +77 -0
- package/src/index.ts +132 -0
- package/src/mdx/BlogPost.tsx +296 -0
- package/src/mdx/__tests__/BlogPost.test.tsx +218 -0
- package/src/mdx/__tests__/blog-post-collection.config.test.ts +127 -0
- package/src/mdx/__tests__/website-mdx-provider.test.tsx +82 -0
- package/src/mdx/blog-post-collection.config.ts +177 -0
- package/src/mdx/blog-post-frontmatter-source.ts +31 -0
- package/src/mdx/index.ts +39 -0
- package/src/mdx/website-mdx-provider.tsx +95 -0
- package/src/mdx.ts +38 -0
- package/src/schemas/__tests__/blog-frontmatter.test.ts +50 -0
- package/src/schemas/__tests__/companion-exports-react-free.test.ts +51 -0
- package/src/schemas/__tests__/design-tokens.test.ts +163 -0
- package/src/schemas/__tests__/label-key.test.ts +46 -0
- package/src/schemas/__tests__/label-pack-validator.test.ts +146 -0
- package/src/schemas/__tests__/page-manifest.test.ts +66 -0
- package/src/schemas/__tests__/refs.test.ts +37 -0
- package/src/schemas/__tests__/root-config.test.ts +292 -0
- package/src/schemas/__tests__/section-definition.test.ts +47 -0
- package/src/schemas/__tests__/structured-data-reconciliation.test.ts +543 -0
- package/src/schemas/blog/blog-post-frontmatter.shared.schemas.ts +111 -0
- package/src/schemas/design-tokens/website-design-tokens.shared.schemas.ts +166 -0
- package/src/schemas/label-keys/website-label-key.schemas.ts +88 -0
- package/src/schemas/manifests/website-page-manifest.shared.schemas.ts +266 -0
- package/src/schemas/manifests/website-root-config.shared.schemas.ts +504 -0
- package/src/schemas/refs/page-ref.schemas.ts +49 -0
- package/src/schemas/refs/section-ref.schemas.ts +50 -0
- package/src/schemas/sections/website-section-category.shared.ts +65 -0
- package/src/schemas/sections/website-section-definition.shared.schemas.ts +120 -0
- package/src/schemas/structured-data/structured-data-reconciliation.shared.ts +579 -0
- package/src/schemas/structured-data/website-structured-data.shared.schemas.ts +62 -0
- package/src/schemas/validators/label-pack.validator.ts +201 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AvailableLanguage } from '@wildo-ai/saas-models/public-runtime';
|
|
3
|
+
import { useWebsiteRuntime } from '../../core/contexts/useWebsiteRuntime.js';
|
|
4
|
+
import { buildLocalizedRoutePath } from '../../core/routing/internal-routing.utils.js';
|
|
5
|
+
import { WebsiteButton, } from './WebsiteButton.js';
|
|
6
|
+
/**
|
|
7
|
+
* Pre-computed set of every known locale code; mirrors the guard in
|
|
8
|
+
* `WebsiteInternalLink` (kept duplicated rather than shared so each
|
|
9
|
+
* primitive's audit surface stays self-contained — the set is tiny).
|
|
10
|
+
*/
|
|
11
|
+
const ALL_LOCALE_CODES = new Set(Object.values(AvailableLanguage));
|
|
12
|
+
function detectAccidentalLocalePrefix(routePath) {
|
|
13
|
+
const slashIdx = routePath.indexOf('/', 1);
|
|
14
|
+
const firstSegment = slashIdx === -1 ? routePath.slice(1) : routePath.slice(1, slashIdx);
|
|
15
|
+
if (firstSegment === '')
|
|
16
|
+
return null;
|
|
17
|
+
return ALL_LOCALE_CODES.has(firstSegment) ? firstSegment : null;
|
|
18
|
+
}
|
|
19
|
+
export function WebsiteInternalButton({ routePath, variant, size, className, style, id, ariaLabel, children, }) {
|
|
20
|
+
const runtime = useWebsiteRuntime();
|
|
21
|
+
if (!routePath.startsWith('/')) {
|
|
22
|
+
throw new Error(`[WebsiteInternalButton] routePath="${routePath}" must start with "/" ` +
|
|
23
|
+
`(framework-relative path). Anchors ("#..."), URL schemes ` +
|
|
24
|
+
`("mailto:" / "tel:"), and fully-qualified external URLs are ` +
|
|
25
|
+
`NOT supported by this primitive — use <WebsiteButton href={...} external={true}> ` +
|
|
26
|
+
`(or omit \`external\` for in-app anchors and scheme links). ` +
|
|
27
|
+
`For NAVIGATION links (not styled as a CTA), see <WebsiteInternalLink routePath={...}>.`);
|
|
28
|
+
}
|
|
29
|
+
const accidentalPrefix = detectAccidentalLocalePrefix(routePath);
|
|
30
|
+
if (accidentalPrefix !== null) {
|
|
31
|
+
throw new Error(`[WebsiteInternalButton] routePath="${routePath}" begins with the ` +
|
|
32
|
+
`locale segment "/${accidentalPrefix}" — the framework prefixes ` +
|
|
33
|
+
`the active locale automatically, so passing a pre-prefixed path ` +
|
|
34
|
+
`would render as "/${accidentalPrefix}${routePath}" on non-default ` +
|
|
35
|
+
`locale pages (double-prefix) or silently break locale routing on ` +
|
|
36
|
+
`default-locale pages. Pass the locale-NEUTRAL path instead ` +
|
|
37
|
+
`(eg. "/pricing", not "/${accidentalPrefix}/pricing").`);
|
|
38
|
+
}
|
|
39
|
+
const href = buildLocalizedRoutePath({
|
|
40
|
+
locale: runtime.locale,
|
|
41
|
+
defaultLocale: runtime.defaultLocale,
|
|
42
|
+
routePath,
|
|
43
|
+
});
|
|
44
|
+
return (_jsx(WebsiteButton, { href: href, external: false, variant: variant, size: size, className: className, style: style, id: id, ariaLabel: ariaLabel, children: children }));
|
|
45
|
+
}
|
|
46
|
+
WebsiteInternalButton.displayName = 'WebsiteInternalButton';
|
|
47
|
+
//# sourceMappingURL=WebsiteInternalButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteInternalButton.js","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteInternalButton.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,OAAO,EACL,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CACnD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAsB,CACtD,CAAC;AAEF,SAAS,4BAA4B,CAAC,SAAiB;IACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3C,MAAM,YAAY,GAChB,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtE,IAAI,YAAY,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAqFD,MAAM,UAAU,qBAAqB,CAAC,EACpC,SAAS,EACT,OAAO,EACP,IAAI,EACJ,SAAS,EACT,KAAK,EACL,EAAE,EACF,SAAS,EACT,QAAQ,GACmB;IAC3B,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,sCAAsC,SAAS,wBAAwB;YACrE,2DAA2D;YAC3D,8DAA8D;YAC9D,mFAAmF;YACnF,8DAA8D;YAC9D,wFAAwF,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,sCAAsC,SAAS,oBAAoB;YACjE,oBAAoB,gBAAgB,6BAA6B;YACjE,kEAAkE;YAClE,qBAAqB,gBAAgB,GAAG,SAAS,mBAAmB;YACpE,mEAAmE;YACnE,6DAA6D;YAC7D,0BAA0B,gBAAgB,aAAa,CAC1D,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,uBAAuB,CAAC;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,SAAS;KACV,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,aAAa,IACZ,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,KAAK,EACf,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,EAAE,EACN,SAAS,EAAE,SAAS,YAEnB,QAAQ,GACK,CACjB,CAAC;AACJ,CAAC;AACD,qBAAqB,CAAC,WAAW,GAAG,uBAAuB,CAAC","sourcesContent":["import React, { type CSSProperties, type ReactNode } from 'react';\n\nimport { AvailableLanguage } from '@wildo-ai/saas-models/public-runtime';\n\nimport { useWebsiteRuntime } from '../../core/contexts/useWebsiteRuntime';\nimport { buildLocalizedRoutePath } from '../../core/routing/internal-routing.utils';\n\nimport {\n WebsiteButton,\n type WebsiteButtonSize,\n type WebsiteButtonVariant,\n} from './WebsiteButton';\n\n/**\n * Pre-computed set of every known locale code; mirrors the guard in\n * `WebsiteInternalLink` (kept duplicated rather than shared so each\n * primitive's audit surface stays self-contained — the set is tiny).\n */\nconst ALL_LOCALE_CODES: ReadonlySet<string> = new Set(\n Object.values(AvailableLanguage) as readonly string[],\n);\n\nfunction detectAccidentalLocalePrefix(routePath: string): string | null {\n const slashIdx = routePath.indexOf('/', 1);\n const firstSegment =\n slashIdx === -1 ? routePath.slice(1) : routePath.slice(1, slashIdx);\n if (firstSegment === '') return null;\n return ALL_LOCALE_CODES.has(firstSegment) ? firstSegment : null;\n}\n\n/**\n * @wildo_source:part:start saas.website.primitives.internal-button facet:layer:components facet:family:website\n *\n * `WebsiteInternalButton` — L1 marketing-site CTA primitive for\n * INTERNAL anchor-mode buttons (CTAs that navigate to another route\n * served by the same Astro build, e.g. \"Get in touch\" → `/contact`).\n *\n * **The architectural problem this solves** (Phase 6 fourth audit fix\n * H-Φ): the H-β fix shipped `WebsiteInternalLink` for header/footer\n * navigation links but `WebsiteButton` consumers in section bodies\n * (hero / features / pricing / contact) continued to write\n * `<WebsiteButton href=\"/contact\">` with raw locale-neutral paths. On\n * `/fr/…` pages those CTAs navigated to the EN-default `/contact`\n * URL — exactly the cross-locale leak H-β was meant to kill, just on\n * the page body instead of the chrome. Authors had to know the\n * routing rule and call `buildLocalizedRoutePath` manually on every\n * CTA they shipped, and the audit confirmed they did not.\n *\n * **Why a parallel primitive** (mirrors the H-β reasoning, NOT a\n * `routePath` flag on `WebsiteButton`):\n * 1. The two primitives have different authoring contracts —\n * `WebsiteButton`'s `href` is a fully-qualified URL the author\n * already commits to (or an anchor `#section`, or external);\n * this primitive's `routePath` is a raw locale-neutral path that\n * the framework prefixes. Mixing both shapes behind one prop\n * forces the author to think about a routing rule on every CTA\n * they place; mixing them without a type-system signal invites\n * the wrong shape on the wrong branch.\n * 2. Internal CTAs REQUIRE the runtime context; external/anchor\n * CTAs do not. Forcing every external-link `WebsiteButton`\n * consumer to wrap in `<WebsiteRuntimeContextProvider>` is wrong.\n * Two primitives keep the dependency surface honest.\n * 3. Symmetric with `WebsiteInternalLink` — section authors learn\n * one rule (\"use the `Internal` variant for app-served paths,\n * the bare variant for external/scheme/anchor URLs\") and apply\n * it identically to both link and button shapes.\n *\n * **Button-only render mode**: this primitive is anchor-mode-only by\n * construction (every internal target is a route → an anchor element\n * with appropriate href). Consumers who need a real `<button>` (no\n * navigation, just an `onClick` handler) keep using `<WebsiteButton>`\n * directly — there is no `routePath`-based real-button concept.\n *\n * **Anchor-only links** (`routePath=\"#features\"`) and URL schemes\n * (`mailto:`/`tel:`) are rejected at runtime: those targets do NOT\n * benefit from locale prefixing, and surfacing them through this\n * primitive would invite the SAME confusion that motivated splitting\n * `WebsiteInternalLink` from `WebsiteLink` in the first place. Use\n * `<WebsiteButton href=\"...\" external={true}>` for those cases.\n *\n * **Boundary**: this component MUST stay in the React-island bundle\n * tier (`components/low-level/`). It depends on `useWebsiteRuntime`\n * (which throws when called outside a `<WebsiteRuntimeContextProvider>`)\n * — the throw is the contract that prevents body CTAs from being\n * rendered outside a bridged page accidentally.\n *\n * @example\n * ```tsx\n * // Hero CTA — auto-prefixes the active locale\n * // (`/contact` on EN pages, `/fr/contact` on FR pages):\n * <WebsiteInternalButton routePath=\"/contact\" variant={WebsiteButtonVariant.PRIMARY}>\n * {useWebsiteLabel('cta.primary')}\n * </WebsiteInternalButton>\n * ```\n */\nexport interface WebsiteInternalButtonProps {\n /**\n * The locale-NEUTRAL route path. Must match a value the consumer's\n * Astro build serves (typically a `WebsitePageManifest.routePath`).\n * MUST start with `/` — anchor-only `#section` and URL schemes\n * (`mailto:` / `tel:`) are rejected (use `<WebsiteButton href={...}>`\n * for those cases).\n */\n routePath: string;\n variant?: WebsiteButtonVariant;\n size?: WebsiteButtonSize;\n className?: string;\n style?: CSSProperties;\n id?: string;\n ariaLabel?: string;\n children: ReactNode;\n}\n\nexport function WebsiteInternalButton({\n routePath,\n variant,\n size,\n className,\n style,\n id,\n ariaLabel,\n children,\n}: WebsiteInternalButtonProps): ReactNode {\n const runtime = useWebsiteRuntime();\n\n if (!routePath.startsWith('/')) {\n throw new Error(\n `[WebsiteInternalButton] routePath=\"${routePath}\" must start with \"/\" ` +\n `(framework-relative path). Anchors (\"#...\"), URL schemes ` +\n `(\"mailto:\" / \"tel:\"), and fully-qualified external URLs are ` +\n `NOT supported by this primitive — use <WebsiteButton href={...} external={true}> ` +\n `(or omit \\`external\\` for in-app anchors and scheme links). ` +\n `For NAVIGATION links (not styled as a CTA), see <WebsiteInternalLink routePath={...}>.`,\n );\n }\n\n const accidentalPrefix = detectAccidentalLocalePrefix(routePath);\n if (accidentalPrefix !== null) {\n throw new Error(\n `[WebsiteInternalButton] routePath=\"${routePath}\" begins with the ` +\n `locale segment \"/${accidentalPrefix}\" — the framework prefixes ` +\n `the active locale automatically, so passing a pre-prefixed path ` +\n `would render as \"/${accidentalPrefix}${routePath}\" on non-default ` +\n `locale pages (double-prefix) or silently break locale routing on ` +\n `default-locale pages. Pass the locale-NEUTRAL path instead ` +\n `(eg. \"/pricing\", not \"/${accidentalPrefix}/pricing\").`,\n );\n }\n\n const href = buildLocalizedRoutePath({\n locale: runtime.locale,\n defaultLocale: runtime.defaultLocale,\n routePath,\n });\n\n return (\n <WebsiteButton\n href={href}\n external={false}\n variant={variant}\n size={size}\n className={className}\n style={style}\n id={id}\n ariaLabel={ariaLabel}\n >\n {children}\n </WebsiteButton>\n );\n}\nWebsiteInternalButton.displayName = 'WebsiteInternalButton';\n/** @wildo_source:part:end saas.website.primitives.internal-button */\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @wildo_source:part:start saas.website.primitives.internal-link facet:layer:components facet:family:website
|
|
4
|
+
*
|
|
5
|
+
* `WebsiteInternalLink` — L1 marketing-site link primitive for
|
|
6
|
+
* INTERNAL routes (any path served by the same Astro build).
|
|
7
|
+
*
|
|
8
|
+
* **The architectural problem this solves** (Phase 6 third audit fix
|
|
9
|
+
* H-β): the marketing site mounts the default locale at the
|
|
10
|
+
* un-prefixed path (`/`, `/pricing`) and every other locale under
|
|
11
|
+
* `/<locale>/…` (`/fr/`, `/fr/pricing`). A naive `<a href="/pricing">`
|
|
12
|
+
* authored in the chrome therefore works on EN pages and SILENTLY
|
|
13
|
+
* BREAKS on FR pages — the visitor falls out of their locale on every
|
|
14
|
+
* navigation. The dist-HTML audit confirmed the regression.
|
|
15
|
+
*
|
|
16
|
+
* **Why a dedicated primitive** (parallel to `WebsiteLink`, not a flag
|
|
17
|
+
* on it):
|
|
18
|
+
* 1. The two primitives have different authoring contracts — an
|
|
19
|
+
* external link's `href` is a fully-qualified URL the author
|
|
20
|
+
* already commits to; an internal link's `href` is a raw
|
|
21
|
+
* `routePath` (`'/pricing'`) that the framework prefixes. Mixing
|
|
22
|
+
* both shapes behind one `external?` prop forces the author to
|
|
23
|
+
* think about a routing rule on every link they place; mixing
|
|
24
|
+
* them behind one component invites the wrong shape on the wrong
|
|
25
|
+
* branch (an internal href passed with `external` set, or vice
|
|
26
|
+
* versa) without a type-system signal.
|
|
27
|
+
* 2. Internal links REQUIRE the runtime context; external links do
|
|
28
|
+
* not. Forcing every external-link consumer to wrap in
|
|
29
|
+
* `<WebsiteRuntimeContextProvider>` (or pay the
|
|
30
|
+
* throw-on-missing-context cost) is wrong. Two primitives keep
|
|
31
|
+
* the dependency surface honest.
|
|
32
|
+
* 3. The framework can layer additional internal-link concerns
|
|
33
|
+
* later (active-route highlighting, prefetch directives,
|
|
34
|
+
* router-aware navigation when the consumer overrides
|
|
35
|
+
* `WebsiteLink`) without complicating the external-link
|
|
36
|
+
* contract.
|
|
37
|
+
*
|
|
38
|
+
* **Why `routePath` is a string and NOT `WebsitePageRef`**:
|
|
39
|
+
* - Many internal targets are NOT pages (anchor links to a section
|
|
40
|
+
* within the current page: `'#features'`; same-locale subroutes
|
|
41
|
+
* served by the consumer's Astro build but not registered as
|
|
42
|
+
* `WebsitePageManifest` entries: `'/blog/launch'`). A `pageRef`
|
|
43
|
+
* prop would force every link target to be a registered manifest,
|
|
44
|
+
* which is too restrictive for chrome.
|
|
45
|
+
* - The consumer's chrome typically links to a small fixed set of
|
|
46
|
+
* `routePath` values they author once. The boilerplate cost of
|
|
47
|
+
* looking up the matching manifest by ref is non-trivial; the
|
|
48
|
+
* payoff (typo protection on `'/pricing'`) is small.
|
|
49
|
+
* - We DO validate at runtime that `routePath` starts with `/` and
|
|
50
|
+
* does not double-prefix (a path already starting with `/<locale>/`
|
|
51
|
+
* would otherwise become `/fr/fr/pricing` on a FR page) — see the
|
|
52
|
+
* in-render guard below.
|
|
53
|
+
*
|
|
54
|
+
* **Anchor-only links** (`href="#features"`) are passed through
|
|
55
|
+
* verbatim: they navigate within the current page, no locale prefix
|
|
56
|
+
* applies. Same for `mailto:` / `tel:` — recognized by colon presence
|
|
57
|
+
* and forwarded as-is.
|
|
58
|
+
*
|
|
59
|
+
* **Boundary**: this component MUST stay in the React-island bundle
|
|
60
|
+
* tier (`components/low-level/`). It depends on `useWebsiteRuntime`
|
|
61
|
+
* (which throws when called outside a `<WebsiteRuntimeContextProvider>`)
|
|
62
|
+
* — the throw is the contract that prevents the chrome from being
|
|
63
|
+
* rendered outside a bridged page accidentally.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```tsx
|
|
67
|
+
* // In HeaderComponent.tsx — the framework computes the right URL
|
|
68
|
+
* // automatically (`/pricing` on EN pages, `/fr/pricing` on FR
|
|
69
|
+
* // pages):
|
|
70
|
+
* <WebsiteInternalLink routePath="/pricing">
|
|
71
|
+
* <WebsiteText variant={WebsiteTextVariant.BODY}>Pricing</WebsiteText>
|
|
72
|
+
* </WebsiteInternalLink>
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export interface WebsiteInternalLinkProps {
|
|
76
|
+
/**
|
|
77
|
+
* The locale-NEUTRAL route path. Must match a value the consumer's
|
|
78
|
+
* Astro build serves (typically a `WebsitePageManifest.routePath`,
|
|
79
|
+
* but anchor-only `#section` and same-page subroutes are also
|
|
80
|
+
* accepted). MUST start with `/` (or `#` for in-page anchors, or
|
|
81
|
+
* include `:` for `mailto:` / `tel:`).
|
|
82
|
+
*/
|
|
83
|
+
routePath: string;
|
|
84
|
+
className?: string;
|
|
85
|
+
style?: CSSProperties;
|
|
86
|
+
id?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Optional `aria-label` for icon-only links (where the link text
|
|
89
|
+
* is a glyph or sr-only).
|
|
90
|
+
*/
|
|
91
|
+
ariaLabel?: string;
|
|
92
|
+
children: ReactNode;
|
|
93
|
+
}
|
|
94
|
+
export declare function WebsiteInternalLink({ routePath, className, style, id, ariaLabel, children, }: WebsiteInternalLinkProps): ReactNode;
|
|
95
|
+
export declare namespace WebsiteInternalLink {
|
|
96
|
+
var displayName: string;
|
|
97
|
+
}
|
|
98
|
+
/** @wildo_source:part:end saas.website.primitives.internal-link */
|
|
99
|
+
//# sourceMappingURL=WebsiteInternalLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteInternalLink.d.ts","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteInternalLink.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AASlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAqCD,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,SAAS,EACT,KAAK,EACL,EAAE,EACF,SAAS,EACT,QAAQ,GACT,EAAE,wBAAwB,GAAG,SAAS,CA8CtC;yBArDe,mBAAmB;;;AAuDnC,mEAAmE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { AvailableLanguage } from '@wildo-ai/saas-models/public-runtime';
|
|
3
|
+
import { useWebsiteRuntime } from '../../core/contexts/useWebsiteRuntime.js';
|
|
4
|
+
import { buildLocalizedRoutePath } from '../../core/routing/internal-routing.utils.js';
|
|
5
|
+
import { WebsiteLink } from './WebsiteLink.js';
|
|
6
|
+
function isAnchorOrUrlScheme(routePath) {
|
|
7
|
+
return routePath.startsWith('#') || routePath.includes(':');
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Pre-computed set of every known locale code (`'en'`, `'fr'`,
|
|
11
|
+
* `'en-GB'`, …). Built ONCE at module load from `AvailableLanguage`
|
|
12
|
+
* so the per-render double-prefix guard below is an O(1) Set.has
|
|
13
|
+
* check rather than an Object.values() walk on every link render.
|
|
14
|
+
*/
|
|
15
|
+
const ALL_LOCALE_CODES = new Set(Object.values(AvailableLanguage));
|
|
16
|
+
/**
|
|
17
|
+
* Defensive in-render guard: rejects route paths whose first segment
|
|
18
|
+
* matches a known locale code. The marketing-site convention is that
|
|
19
|
+
* the consumer authors locale-NEUTRAL paths and the framework
|
|
20
|
+
* prefixes them; an already-prefixed path would either render as a
|
|
21
|
+
* `/<locale>/<locale>/pricing` double-prefix on non-default-locale
|
|
22
|
+
* pages or silently work on default-locale pages and break on other
|
|
23
|
+
* locales — both are silent regressions. Throwing here makes the
|
|
24
|
+
* misuse loud at first render.
|
|
25
|
+
*
|
|
26
|
+
* Returns the offending locale segment if the path is misused, or
|
|
27
|
+
* `null` if the path is well-formed.
|
|
28
|
+
*/
|
|
29
|
+
function detectAccidentalLocalePrefix(routePath) {
|
|
30
|
+
const slashIdx = routePath.indexOf('/', 1);
|
|
31
|
+
const firstSegment = slashIdx === -1 ? routePath.slice(1) : routePath.slice(1, slashIdx);
|
|
32
|
+
if (firstSegment === '')
|
|
33
|
+
return null;
|
|
34
|
+
return ALL_LOCALE_CODES.has(firstSegment) ? firstSegment : null;
|
|
35
|
+
}
|
|
36
|
+
export function WebsiteInternalLink({ routePath, className, style, id, ariaLabel, children, }) {
|
|
37
|
+
const runtime = useWebsiteRuntime();
|
|
38
|
+
let href;
|
|
39
|
+
if (isAnchorOrUrlScheme(routePath)) {
|
|
40
|
+
href = routePath;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
if (!routePath.startsWith('/')) {
|
|
44
|
+
throw new Error(`[WebsiteInternalLink] routePath="${routePath}" must start with "/" ` +
|
|
45
|
+
`(framework-relative path), "#" (in-page anchor) or include ":" ` +
|
|
46
|
+
`(URL scheme like mailto:/tel:). Use <WebsiteLink href={...} external={true}> ` +
|
|
47
|
+
`for fully-qualified external URLs.`);
|
|
48
|
+
}
|
|
49
|
+
const accidentalPrefix = detectAccidentalLocalePrefix(routePath);
|
|
50
|
+
if (accidentalPrefix !== null) {
|
|
51
|
+
throw new Error(`[WebsiteInternalLink] routePath="${routePath}" begins with the ` +
|
|
52
|
+
`locale segment "/${accidentalPrefix}" — the framework prefixes ` +
|
|
53
|
+
`the active locale automatically, so passing a pre-prefixed path ` +
|
|
54
|
+
`would render as "/${accidentalPrefix}${routePath}" on non-default ` +
|
|
55
|
+
`locale pages (double-prefix) or silently break locale routing on ` +
|
|
56
|
+
`default-locale pages. Pass the locale-NEUTRAL path instead ` +
|
|
57
|
+
`(eg. "/pricing", not "/${accidentalPrefix}/pricing").`);
|
|
58
|
+
}
|
|
59
|
+
href = buildLocalizedRoutePath({
|
|
60
|
+
locale: runtime.locale,
|
|
61
|
+
defaultLocale: runtime.defaultLocale,
|
|
62
|
+
routePath,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return (_jsx(WebsiteLink, { href: href, external: false, className: className, style: style, id: id, ariaLabel: ariaLabel, children: children }));
|
|
66
|
+
}
|
|
67
|
+
WebsiteInternalLink.displayName = 'WebsiteInternalLink';
|
|
68
|
+
//# sourceMappingURL=WebsiteInternalLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteInternalLink.js","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteInternalLink.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEpF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA+F5C,SAAS,mBAAmB,CAAC,SAAiB;IAC5C,OAAO,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CACnD,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAsB,CACtD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,SAAS,4BAA4B,CAAC,SAAiB;IACrD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3C,MAAM,YAAY,GAChB,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtE,IAAI,YAAY,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACrC,OAAO,gBAAgB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAClC,SAAS,EACT,SAAS,EACT,KAAK,EACL,EAAE,EACF,SAAS,EACT,QAAQ,GACiB;IACzB,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,IAAI,IAAY,CAAC;IACjB,IAAI,mBAAmB,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,oCAAoC,SAAS,wBAAwB;gBACnE,iEAAiE;gBACjE,+EAA+E;gBAC/E,oCAAoC,CACvC,CAAC;QACJ,CAAC;QACD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC,SAAS,CAAC,CAAC;QACjE,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,oCAAoC,SAAS,oBAAoB;gBAC/D,oBAAoB,gBAAgB,6BAA6B;gBACjE,kEAAkE;gBAClE,qBAAqB,gBAAgB,GAAG,SAAS,mBAAmB;gBACpE,mEAAmE;gBACnE,6DAA6D;gBAC7D,0BAA0B,gBAAgB,aAAa,CAC1D,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,uBAAuB,CAAC;YAC7B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CACL,KAAC,WAAW,IACV,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,KAAK,EACf,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,EAAE,EACN,SAAS,EAAE,SAAS,YAEnB,QAAQ,GACG,CACf,CAAC;AACJ,CAAC;AACD,mBAAmB,CAAC,WAAW,GAAG,qBAAqB,CAAC","sourcesContent":["import React, { type CSSProperties, type ReactNode } from 'react';\n\nimport { AvailableLanguage } from '@wildo-ai/saas-models/public-runtime';\n\nimport { useWebsiteRuntime } from '../../core/contexts/useWebsiteRuntime';\nimport { buildLocalizedRoutePath } from '../../core/routing/internal-routing.utils';\n\nimport { WebsiteLink } from './WebsiteLink';\n\n/**\n * @wildo_source:part:start saas.website.primitives.internal-link facet:layer:components facet:family:website\n *\n * `WebsiteInternalLink` — L1 marketing-site link primitive for\n * INTERNAL routes (any path served by the same Astro build).\n *\n * **The architectural problem this solves** (Phase 6 third audit fix\n * H-β): the marketing site mounts the default locale at the\n * un-prefixed path (`/`, `/pricing`) and every other locale under\n * `/<locale>/…` (`/fr/`, `/fr/pricing`). A naive `<a href=\"/pricing\">`\n * authored in the chrome therefore works on EN pages and SILENTLY\n * BREAKS on FR pages — the visitor falls out of their locale on every\n * navigation. The dist-HTML audit confirmed the regression.\n *\n * **Why a dedicated primitive** (parallel to `WebsiteLink`, not a flag\n * on it):\n * 1. The two primitives have different authoring contracts — an\n * external link's `href` is a fully-qualified URL the author\n * already commits to; an internal link's `href` is a raw\n * `routePath` (`'/pricing'`) that the framework prefixes. Mixing\n * both shapes behind one `external?` prop forces the author to\n * think about a routing rule on every link they place; mixing\n * them behind one component invites the wrong shape on the wrong\n * branch (an internal href passed with `external` set, or vice\n * versa) without a type-system signal.\n * 2. Internal links REQUIRE the runtime context; external links do\n * not. Forcing every external-link consumer to wrap in\n * `<WebsiteRuntimeContextProvider>` (or pay the\n * throw-on-missing-context cost) is wrong. Two primitives keep\n * the dependency surface honest.\n * 3. The framework can layer additional internal-link concerns\n * later (active-route highlighting, prefetch directives,\n * router-aware navigation when the consumer overrides\n * `WebsiteLink`) without complicating the external-link\n * contract.\n *\n * **Why `routePath` is a string and NOT `WebsitePageRef`**:\n * - Many internal targets are NOT pages (anchor links to a section\n * within the current page: `'#features'`; same-locale subroutes\n * served by the consumer's Astro build but not registered as\n * `WebsitePageManifest` entries: `'/blog/launch'`). A `pageRef`\n * prop would force every link target to be a registered manifest,\n * which is too restrictive for chrome.\n * - The consumer's chrome typically links to a small fixed set of\n * `routePath` values they author once. The boilerplate cost of\n * looking up the matching manifest by ref is non-trivial; the\n * payoff (typo protection on `'/pricing'`) is small.\n * - We DO validate at runtime that `routePath` starts with `/` and\n * does not double-prefix (a path already starting with `/<locale>/`\n * would otherwise become `/fr/fr/pricing` on a FR page) — see the\n * in-render guard below.\n *\n * **Anchor-only links** (`href=\"#features\"`) are passed through\n * verbatim: they navigate within the current page, no locale prefix\n * applies. Same for `mailto:` / `tel:` — recognized by colon presence\n * and forwarded as-is.\n *\n * **Boundary**: this component MUST stay in the React-island bundle\n * tier (`components/low-level/`). It depends on `useWebsiteRuntime`\n * (which throws when called outside a `<WebsiteRuntimeContextProvider>`)\n * — the throw is the contract that prevents the chrome from being\n * rendered outside a bridged page accidentally.\n *\n * @example\n * ```tsx\n * // In HeaderComponent.tsx — the framework computes the right URL\n * // automatically (`/pricing` on EN pages, `/fr/pricing` on FR\n * // pages):\n * <WebsiteInternalLink routePath=\"/pricing\">\n * <WebsiteText variant={WebsiteTextVariant.BODY}>Pricing</WebsiteText>\n * </WebsiteInternalLink>\n * ```\n */\nexport interface WebsiteInternalLinkProps {\n /**\n * The locale-NEUTRAL route path. Must match a value the consumer's\n * Astro build serves (typically a `WebsitePageManifest.routePath`,\n * but anchor-only `#section` and same-page subroutes are also\n * accepted). MUST start with `/` (or `#` for in-page anchors, or\n * include `:` for `mailto:` / `tel:`).\n */\n routePath: string;\n className?: string;\n style?: CSSProperties;\n id?: string;\n /**\n * Optional `aria-label` for icon-only links (where the link text\n * is a glyph or sr-only).\n */\n ariaLabel?: string;\n children: ReactNode;\n}\n\nfunction isAnchorOrUrlScheme(routePath: string): boolean {\n return routePath.startsWith('#') || routePath.includes(':');\n}\n\n/**\n * Pre-computed set of every known locale code (`'en'`, `'fr'`,\n * `'en-GB'`, …). Built ONCE at module load from `AvailableLanguage`\n * so the per-render double-prefix guard below is an O(1) Set.has\n * check rather than an Object.values() walk on every link render.\n */\nconst ALL_LOCALE_CODES: ReadonlySet<string> = new Set(\n Object.values(AvailableLanguage) as readonly string[],\n);\n\n/**\n * Defensive in-render guard: rejects route paths whose first segment\n * matches a known locale code. The marketing-site convention is that\n * the consumer authors locale-NEUTRAL paths and the framework\n * prefixes them; an already-prefixed path would either render as a\n * `/<locale>/<locale>/pricing` double-prefix on non-default-locale\n * pages or silently work on default-locale pages and break on other\n * locales — both are silent regressions. Throwing here makes the\n * misuse loud at first render.\n *\n * Returns the offending locale segment if the path is misused, or\n * `null` if the path is well-formed.\n */\nfunction detectAccidentalLocalePrefix(routePath: string): string | null {\n const slashIdx = routePath.indexOf('/', 1);\n const firstSegment =\n slashIdx === -1 ? routePath.slice(1) : routePath.slice(1, slashIdx);\n if (firstSegment === '') return null;\n return ALL_LOCALE_CODES.has(firstSegment) ? firstSegment : null;\n}\n\nexport function WebsiteInternalLink({\n routePath,\n className,\n style,\n id,\n ariaLabel,\n children,\n}: WebsiteInternalLinkProps): ReactNode {\n const runtime = useWebsiteRuntime();\n\n let href: string;\n if (isAnchorOrUrlScheme(routePath)) {\n href = routePath;\n } else {\n if (!routePath.startsWith('/')) {\n throw new Error(\n `[WebsiteInternalLink] routePath=\"${routePath}\" must start with \"/\" ` +\n `(framework-relative path), \"#\" (in-page anchor) or include \":\" ` +\n `(URL scheme like mailto:/tel:). Use <WebsiteLink href={...} external={true}> ` +\n `for fully-qualified external URLs.`,\n );\n }\n const accidentalPrefix = detectAccidentalLocalePrefix(routePath);\n if (accidentalPrefix !== null) {\n throw new Error(\n `[WebsiteInternalLink] routePath=\"${routePath}\" begins with the ` +\n `locale segment \"/${accidentalPrefix}\" — the framework prefixes ` +\n `the active locale automatically, so passing a pre-prefixed path ` +\n `would render as \"/${accidentalPrefix}${routePath}\" on non-default ` +\n `locale pages (double-prefix) or silently break locale routing on ` +\n `default-locale pages. Pass the locale-NEUTRAL path instead ` +\n `(eg. \"/pricing\", not \"/${accidentalPrefix}/pricing\").`,\n );\n }\n href = buildLocalizedRoutePath({\n locale: runtime.locale,\n defaultLocale: runtime.defaultLocale,\n routePath,\n });\n }\n\n return (\n <WebsiteLink\n href={href}\n external={false}\n className={className}\n style={style}\n id={id}\n ariaLabel={ariaLabel}\n >\n {children}\n </WebsiteLink>\n );\n}\nWebsiteInternalLink.displayName = 'WebsiteInternalLink';\n/** @wildo_source:part:end saas.website.primitives.internal-link */\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @wildo_source:part:start saas.website.primitives.link facet:layer:components facet:family:website
|
|
4
|
+
*
|
|
5
|
+
* `WebsiteLink` — L1 marketing-site link primitive.
|
|
6
|
+
*
|
|
7
|
+
* **Status (Phase 2 / D18)**: minimal placeholder. Renders a plain
|
|
8
|
+
* `<a>` with `data-website-primitive="link"` and forwards href +
|
|
9
|
+
* standard link attributes. Consumers override at the L1 boundary
|
|
10
|
+
* to wire in their preferred client-side router (Astro `<a>` does
|
|
11
|
+
* full navigation by default; consumers using View Transitions or
|
|
12
|
+
* a router-aware link wrap that here).
|
|
13
|
+
*
|
|
14
|
+
* **Why `external` is an explicit prop** (vs. inferred from the
|
|
15
|
+
* href shape): inference is unreliable (relative paths from a CMS
|
|
16
|
+
* may resolve to external; protocol-relative URLs are external but
|
|
17
|
+
* don't start with `http`). An explicit prop forces the section
|
|
18
|
+
* author to decide. When `external === true`, the primitive applies
|
|
19
|
+
* `rel="noopener noreferrer"` and `target="_blank"` automatically
|
|
20
|
+
* — security best-practice baked in.
|
|
21
|
+
*
|
|
22
|
+
* **Why no `variant`**: link visual variants (button-like CTA,
|
|
23
|
+
* inline-text link, icon-only) are too tightly coupled to the
|
|
24
|
+
* design system to be useful as a placeholder vocabulary. The
|
|
25
|
+
* override implementation defines its own variants; the
|
|
26
|
+
* placeholder ships only the security-correct attribute defaults.
|
|
27
|
+
*/
|
|
28
|
+
export interface WebsiteLinkProps {
|
|
29
|
+
href: string;
|
|
30
|
+
/**
|
|
31
|
+
* Marks the link as external. Adds `target="_blank"` and
|
|
32
|
+
* `rel="noopener noreferrer"`. Defaults to `false`.
|
|
33
|
+
*/
|
|
34
|
+
external?: boolean;
|
|
35
|
+
className?: string;
|
|
36
|
+
style?: CSSProperties;
|
|
37
|
+
id?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Optional `aria-label` for icon-only links (where the link text
|
|
40
|
+
* is a glyph or sr-only).
|
|
41
|
+
*/
|
|
42
|
+
ariaLabel?: string;
|
|
43
|
+
children: ReactNode;
|
|
44
|
+
}
|
|
45
|
+
export declare function WebsiteLink({ href, external, className, style, id, ariaLabel, children, }: WebsiteLinkProps): ReactNode;
|
|
46
|
+
export declare namespace WebsiteLink {
|
|
47
|
+
var displayName: string;
|
|
48
|
+
}
|
|
49
|
+
/** @wildo_source:part:end saas.website.primitives.link */
|
|
50
|
+
//# sourceMappingURL=WebsiteLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteLink.d.ts","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteLink.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAgB,EAChB,SAAS,EACT,KAAK,EACL,EAAE,EACF,SAAS,EACT,QAAQ,GACT,EAAE,gBAAgB,GAAG,SAAS,CAc9B;yBAtBe,WAAW;;;AAwB3B,0DAA0D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export function WebsiteLink({ href, external = false, className, style, id, ariaLabel, children, }) {
|
|
3
|
+
const attrs = {
|
|
4
|
+
'data-website-primitive': 'link',
|
|
5
|
+
href,
|
|
6
|
+
};
|
|
7
|
+
if (external) {
|
|
8
|
+
attrs.target = '_blank';
|
|
9
|
+
attrs.rel = 'noopener noreferrer';
|
|
10
|
+
}
|
|
11
|
+
if (className !== undefined)
|
|
12
|
+
attrs.className = className;
|
|
13
|
+
if (style !== undefined)
|
|
14
|
+
attrs.style = style;
|
|
15
|
+
if (id !== undefined)
|
|
16
|
+
attrs.id = id;
|
|
17
|
+
if (ariaLabel !== undefined)
|
|
18
|
+
attrs['aria-label'] = ariaLabel;
|
|
19
|
+
return _jsx("a", { ...attrs, children: children });
|
|
20
|
+
}
|
|
21
|
+
WebsiteLink.displayName = 'WebsiteLink';
|
|
22
|
+
//# sourceMappingURL=WebsiteLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteLink.js","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteLink.tsx"],"names":[],"mappings":";AA8CA,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,KAAK,EACL,EAAE,EACF,SAAS,EACT,QAAQ,GACS;IACjB,MAAM,KAAK,GAA4B;QACrC,wBAAwB,EAAE,MAAM;QAChC,IAAI;KACL,CAAC;IACF,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC;QACxB,KAAK,CAAC,GAAG,GAAG,qBAAqB,CAAC;IACpC,CAAC;IACD,IAAI,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IACzD,IAAI,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IAC7C,IAAI,EAAE,KAAK,SAAS;QAAE,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACpC,IAAI,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;IAC7D,OAAO,eAAO,KAAK,YAAG,QAAQ,GAAK,CAAC;AACtC,CAAC;AACD,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC","sourcesContent":["import React, { type CSSProperties, type ReactNode } from 'react';\n\n/**\n * @wildo_source:part:start saas.website.primitives.link facet:layer:components facet:family:website\n *\n * `WebsiteLink` — L1 marketing-site link primitive.\n *\n * **Status (Phase 2 / D18)**: minimal placeholder. Renders a plain\n * `<a>` with `data-website-primitive=\"link\"` and forwards href +\n * standard link attributes. Consumers override at the L1 boundary\n * to wire in their preferred client-side router (Astro `<a>` does\n * full navigation by default; consumers using View Transitions or\n * a router-aware link wrap that here).\n *\n * **Why `external` is an explicit prop** (vs. inferred from the\n * href shape): inference is unreliable (relative paths from a CMS\n * may resolve to external; protocol-relative URLs are external but\n * don't start with `http`). An explicit prop forces the section\n * author to decide. When `external === true`, the primitive applies\n * `rel=\"noopener noreferrer\"` and `target=\"_blank\"` automatically\n * — security best-practice baked in.\n *\n * **Why no `variant`**: link visual variants (button-like CTA,\n * inline-text link, icon-only) are too tightly coupled to the\n * design system to be useful as a placeholder vocabulary. The\n * override implementation defines its own variants; the\n * placeholder ships only the security-correct attribute defaults.\n */\nexport interface WebsiteLinkProps {\n href: string;\n /**\n * Marks the link as external. Adds `target=\"_blank\"` and\n * `rel=\"noopener noreferrer\"`. Defaults to `false`.\n */\n external?: boolean;\n className?: string;\n style?: CSSProperties;\n id?: string;\n /**\n * Optional `aria-label` for icon-only links (where the link text\n * is a glyph or sr-only).\n */\n ariaLabel?: string;\n children: ReactNode;\n}\n\nexport function WebsiteLink({\n href,\n external = false,\n className,\n style,\n id,\n ariaLabel,\n children,\n}: WebsiteLinkProps): ReactNode {\n const attrs: Record<string, unknown> = {\n 'data-website-primitive': 'link',\n href,\n };\n if (external) {\n attrs.target = '_blank';\n attrs.rel = 'noopener noreferrer';\n }\n if (className !== undefined) attrs.className = className;\n if (style !== undefined) attrs.style = style;\n if (id !== undefined) attrs.id = id;\n if (ariaLabel !== undefined) attrs['aria-label'] = ariaLabel;\n return <a {...attrs}>{children}</a>;\n}\nWebsiteLink.displayName = 'WebsiteLink';\n/** @wildo_source:part:end saas.website.primitives.link */\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* @wildo_source:part:start saas.website.primitives.text facet:layer:components facet:family:website
|
|
4
|
+
*
|
|
5
|
+
* `WebsiteText` — L1 marketing-site body-text primitive.
|
|
6
|
+
*
|
|
7
|
+
* Same Phase 2 / D18 status as `WebsiteHeading` — minimal,
|
|
8
|
+
* self-contained placeholder; consumers override at the L1 boundary
|
|
9
|
+
* via barrel re-export. The skill-driven authoring path will require
|
|
10
|
+
* an override before shipping a public marketing site.
|
|
11
|
+
*
|
|
12
|
+
* **Why `variant` (lead vs. body vs. caption) is shipped here**:
|
|
13
|
+
* marketing-site body copy has a distinct typographic scale from
|
|
14
|
+
* in-app body copy (looser line-height for scannability, larger
|
|
15
|
+
* `lead` paragraphs under headlines, smaller `caption` under
|
|
16
|
+
* pricing tier features). The variant slot exists at the
|
|
17
|
+
* placeholder level so section authors call the same prop the
|
|
18
|
+
* override implementation honors.
|
|
19
|
+
*
|
|
20
|
+
* **Why default tag is `<p>`**: the overwhelming majority of
|
|
21
|
+
* marketing copy is a paragraph. The `as` prop allows escaping to
|
|
22
|
+
* `<span>` (inline copy inside a heading), `<strong>` (emphatic
|
|
23
|
+
* inline), or `<em>` (italicized inline) without compromising the
|
|
24
|
+
* paragraph default.
|
|
25
|
+
*/
|
|
26
|
+
export declare enum WebsiteTextVariant {
|
|
27
|
+
/**
|
|
28
|
+
* Lead paragraph immediately under a section headline (slightly
|
|
29
|
+
* larger / less dense than body).
|
|
30
|
+
*/
|
|
31
|
+
LEAD = "lead",
|
|
32
|
+
/**
|
|
33
|
+
* Standard body copy. The default.
|
|
34
|
+
*/
|
|
35
|
+
BODY = "body",
|
|
36
|
+
/**
|
|
37
|
+
* Small / supporting copy (footnotes, captions, fine print).
|
|
38
|
+
*/
|
|
39
|
+
CAPTION = "caption"
|
|
40
|
+
}
|
|
41
|
+
export type WebsiteTextElement = 'p' | 'span' | 'strong' | 'em' | 'div';
|
|
42
|
+
export interface WebsiteTextProps {
|
|
43
|
+
/** Visual variant. Defaults to `BODY`. */
|
|
44
|
+
variant?: WebsiteTextVariant;
|
|
45
|
+
/** Rendered tag. Defaults to `'p'`. */
|
|
46
|
+
as?: WebsiteTextElement;
|
|
47
|
+
className?: string;
|
|
48
|
+
style?: CSSProperties;
|
|
49
|
+
id?: string;
|
|
50
|
+
children: ReactNode;
|
|
51
|
+
}
|
|
52
|
+
export declare function WebsiteText({ variant, as, className, style, id, children, }: WebsiteTextProps): ReactNode;
|
|
53
|
+
export declare namespace WebsiteText {
|
|
54
|
+
var displayName: string;
|
|
55
|
+
}
|
|
56
|
+
/** @wildo_source:part:end saas.website.primitives.text */
|
|
57
|
+
//# sourceMappingURL=WebsiteText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteText.d.ts","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteText.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,oBAAY,kBAAkB;IAC5B;;;OAGG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,IAAI,SAAS;IACb;;OAEG;IACH,OAAO,YAAY;CACpB;AAED,MAAM,MAAM,kBAAkB,GAAG,GAAG,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC/B,0CAA0C;IAC1C,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,uCAAuC;IACvC,EAAE,CAAC,EAAE,kBAAkB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAiC,EACjC,EAAQ,EACR,SAAS,EACT,KAAK,EACL,EAAE,EACF,QAAQ,GACT,EAAE,gBAAgB,GAAG,SAAS,CAU9B;yBAjBe,WAAW;;;AAmB3B,0DAA0D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @wildo_source:part:start saas.website.primitives.text facet:layer:components facet:family:website
|
|
4
|
+
*
|
|
5
|
+
* `WebsiteText` — L1 marketing-site body-text primitive.
|
|
6
|
+
*
|
|
7
|
+
* Same Phase 2 / D18 status as `WebsiteHeading` — minimal,
|
|
8
|
+
* self-contained placeholder; consumers override at the L1 boundary
|
|
9
|
+
* via barrel re-export. The skill-driven authoring path will require
|
|
10
|
+
* an override before shipping a public marketing site.
|
|
11
|
+
*
|
|
12
|
+
* **Why `variant` (lead vs. body vs. caption) is shipped here**:
|
|
13
|
+
* marketing-site body copy has a distinct typographic scale from
|
|
14
|
+
* in-app body copy (looser line-height for scannability, larger
|
|
15
|
+
* `lead` paragraphs under headlines, smaller `caption` under
|
|
16
|
+
* pricing tier features). The variant slot exists at the
|
|
17
|
+
* placeholder level so section authors call the same prop the
|
|
18
|
+
* override implementation honors.
|
|
19
|
+
*
|
|
20
|
+
* **Why default tag is `<p>`**: the overwhelming majority of
|
|
21
|
+
* marketing copy is a paragraph. The `as` prop allows escaping to
|
|
22
|
+
* `<span>` (inline copy inside a heading), `<strong>` (emphatic
|
|
23
|
+
* inline), or `<em>` (italicized inline) without compromising the
|
|
24
|
+
* paragraph default.
|
|
25
|
+
*/
|
|
26
|
+
export var WebsiteTextVariant;
|
|
27
|
+
(function (WebsiteTextVariant) {
|
|
28
|
+
/**
|
|
29
|
+
* Lead paragraph immediately under a section headline (slightly
|
|
30
|
+
* larger / less dense than body).
|
|
31
|
+
*/
|
|
32
|
+
WebsiteTextVariant["LEAD"] = "lead";
|
|
33
|
+
/**
|
|
34
|
+
* Standard body copy. The default.
|
|
35
|
+
*/
|
|
36
|
+
WebsiteTextVariant["BODY"] = "body";
|
|
37
|
+
/**
|
|
38
|
+
* Small / supporting copy (footnotes, captions, fine print).
|
|
39
|
+
*/
|
|
40
|
+
WebsiteTextVariant["CAPTION"] = "caption";
|
|
41
|
+
})(WebsiteTextVariant || (WebsiteTextVariant = {}));
|
|
42
|
+
export function WebsiteText({ variant = WebsiteTextVariant.BODY, as = 'p', className, style, id, children, }) {
|
|
43
|
+
const Tag = as;
|
|
44
|
+
const attrs = {
|
|
45
|
+
'data-website-primitive': 'text',
|
|
46
|
+
'data-website-text-variant': variant,
|
|
47
|
+
};
|
|
48
|
+
if (className !== undefined)
|
|
49
|
+
attrs.className = className;
|
|
50
|
+
if (style !== undefined)
|
|
51
|
+
attrs.style = style;
|
|
52
|
+
if (id !== undefined)
|
|
53
|
+
attrs.id = id;
|
|
54
|
+
return _jsx(Tag, { ...attrs, children: children });
|
|
55
|
+
}
|
|
56
|
+
WebsiteText.displayName = 'WebsiteText';
|
|
57
|
+
//# sourceMappingURL=WebsiteText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebsiteText.js","sourceRoot":"","sources":["../../../../../src/components/low-level/WebsiteText.tsx"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAN,IAAY,kBAcX;AAdD,WAAY,kBAAkB;IAC5B;;;OAGG;IACH,mCAAa,CAAA;IACb;;OAEG;IACH,mCAAa,CAAA;IACb;;OAEG;IACH,yCAAmB,CAAA;AACrB,CAAC,EAdW,kBAAkB,KAAlB,kBAAkB,QAc7B;AAeD,MAAM,UAAU,WAAW,CAAC,EAC1B,OAAO,GAAG,kBAAkB,CAAC,IAAI,EACjC,EAAE,GAAG,GAAG,EACR,SAAS,EACT,KAAK,EACL,EAAE,EACF,QAAQ,GACS;IACjB,MAAM,GAAG,GAAG,EAAE,CAAC;IACf,MAAM,KAAK,GAA4B;QACrC,wBAAwB,EAAE,MAAM;QAChC,2BAA2B,EAAE,OAAO;KACrC,CAAC;IACF,IAAI,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC;IACzD,IAAI,KAAK,KAAK,SAAS;QAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IAC7C,IAAI,EAAE,KAAK,SAAS;QAAE,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACpC,OAAO,KAAC,GAAG,OAAK,KAAK,YAAG,QAAQ,GAAO,CAAC;AAC1C,CAAC;AACD,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC","sourcesContent":["import React, { type CSSProperties, type ReactNode } from 'react';\n\n/**\n * @wildo_source:part:start saas.website.primitives.text facet:layer:components facet:family:website\n *\n * `WebsiteText` — L1 marketing-site body-text primitive.\n *\n * Same Phase 2 / D18 status as `WebsiteHeading` — minimal,\n * self-contained placeholder; consumers override at the L1 boundary\n * via barrel re-export. The skill-driven authoring path will require\n * an override before shipping a public marketing site.\n *\n * **Why `variant` (lead vs. body vs. caption) is shipped here**:\n * marketing-site body copy has a distinct typographic scale from\n * in-app body copy (looser line-height for scannability, larger\n * `lead` paragraphs under headlines, smaller `caption` under\n * pricing tier features). The variant slot exists at the\n * placeholder level so section authors call the same prop the\n * override implementation honors.\n *\n * **Why default tag is `<p>`**: the overwhelming majority of\n * marketing copy is a paragraph. The `as` prop allows escaping to\n * `<span>` (inline copy inside a heading), `<strong>` (emphatic\n * inline), or `<em>` (italicized inline) without compromising the\n * paragraph default.\n */\nexport enum WebsiteTextVariant {\n /**\n * Lead paragraph immediately under a section headline (slightly\n * larger / less dense than body).\n */\n LEAD = 'lead',\n /**\n * Standard body copy. The default.\n */\n BODY = 'body',\n /**\n * Small / supporting copy (footnotes, captions, fine print).\n */\n CAPTION = 'caption',\n}\n\nexport type WebsiteTextElement = 'p' | 'span' | 'strong' | 'em' | 'div';\n\nexport interface WebsiteTextProps {\n /** Visual variant. Defaults to `BODY`. */\n variant?: WebsiteTextVariant;\n /** Rendered tag. Defaults to `'p'`. */\n as?: WebsiteTextElement;\n className?: string;\n style?: CSSProperties;\n id?: string;\n children: ReactNode;\n}\n\nexport function WebsiteText({\n variant = WebsiteTextVariant.BODY,\n as = 'p',\n className,\n style,\n id,\n children,\n}: WebsiteTextProps): ReactNode {\n const Tag = as;\n const attrs: Record<string, unknown> = {\n 'data-website-primitive': 'text',\n 'data-website-text-variant': variant,\n };\n if (className !== undefined) attrs.className = className;\n if (style !== undefined) attrs.style = style;\n if (id !== undefined) attrs.id = id;\n return <Tag {...attrs}>{children}</Tag>;\n}\nWebsiteText.displayName = 'WebsiteText';\n/** @wildo_source:part:end saas.website.primitives.text */\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Author helper for `wildo.website.config.ts` files.
|
|
3
|
+
*
|
|
4
|
+
* `defineWebsiteConfig({...})` mirrors the `defineSaasConfig` /
|
|
5
|
+
* `defineInfraEnvConfig` helpers from `@wildo-ai/platform-config-lib`
|
|
6
|
+
* and `defineTechnicalDocConfig` from `@wildo-ai/saas-technical-doc`:
|
|
7
|
+
* it wraps `WildoMarketingWebsiteConfigSchema.parse(...)` with full
|
|
8
|
+
* IDE autocompletion on the input shape, and emits a parse-time
|
|
9
|
+
* stderr warning for any authored field that has no runtime
|
|
10
|
+
* consumer yet.
|
|
11
|
+
*
|
|
12
|
+
* # `@unimplemented` channel — current state
|
|
13
|
+
*
|
|
14
|
+
* The warner has ZERO branches today because every OPTIONAL field that
|
|
15
|
+
* exists is already wired (`csp?` now flows through the website-local
|
|
16
|
+
* CSP sync step) and the only unwired field left is `appOrigin`, which
|
|
17
|
+
* is REQUIRED. After the seam-collapse (`saas-website-seam-collapse.md`
|
|
18
|
+
* — SHIPPED), the routing/origin fields (`publicOrigin`,
|
|
19
|
+
* `defaultLocale`, `locales`) are consumed directly by every Astro
|
|
20
|
+
* engine helper via `WebsiteSiteContext`, so they are no longer
|
|
21
|
+
* candidates for a "deferred wiring" warning either. The
|
|
22
|
+
* `@unimplemented` warner is for fields that are parsed-but-unused AND
|
|
23
|
+
* opt-in — firing on every Astro build for a required field would drown
|
|
24
|
+
* the dev console.
|
|
25
|
+
*
|
|
26
|
+
* Two valid futures will trigger adding warner branches:
|
|
27
|
+
* 1. A future optional field lands (e.g. `seo?.{title,description}`,
|
|
28
|
+
* `structuredData?.organization`) whose runtime wiring ships
|
|
29
|
+
* in a later PR — that would get
|
|
30
|
+
* `if (config.seo !== undefined) warn('seo', ...)` until the
|
|
31
|
+
* renderer reads it.
|
|
32
|
+
* 2. A required field temporarily loses its consumer (e.g. a
|
|
33
|
+
* large refactor splits the SEO renderer into two PRs); the
|
|
34
|
+
* branch fires unconditionally for the duration.
|
|
35
|
+
*
|
|
36
|
+
* The scaffold is kept (and the no-warning contract is pinned by
|
|
37
|
+
* the test suite) so the moment either case lands, the warning
|
|
38
|
+
* channel is one branch addition away — matching the
|
|
39
|
+
* `defineTechnicalDocConfig` shape exactly so future authors
|
|
40
|
+
* grepping for `@unimplemented` find a uniform pattern.
|
|
41
|
+
*
|
|
42
|
+
* Why we don't reuse `platform-config-lib`'s
|
|
43
|
+
* `createUnimplementedFieldWarner`:
|
|
44
|
+
*
|
|
45
|
+
* `platform-config-lib` is the platform-level boundary; this engine
|
|
46
|
+
* package is downstream of it for everything else. Importing the
|
|
47
|
+
* warner from `platform-config-lib` would invert the dependency
|
|
48
|
+
* direction (engine → platform-config), creating the same architectural
|
|
49
|
+
* defect Step 7.5 set out to fix. The warning format is small and
|
|
50
|
+
* stable enough to inline here — kept structurally similar to the
|
|
51
|
+
* platform-config-lib warner so readers grepping for `@unimplemented`
|
|
52
|
+
* still find both surfaces.
|
|
53
|
+
*/
|
|
54
|
+
import { type WildoMarketingWebsiteConfig, type WildoMarketingWebsiteConfigInput } from './wildo-website-config.schemas';
|
|
55
|
+
/**
|
|
56
|
+
* Define a per-service marketing-website config. Provides full IDE
|
|
57
|
+
* autocompletion on the input shape, runs Zod validation (fail-closed
|
|
58
|
+
* on typos / unknown keys / out-of-range values / cross-field
|
|
59
|
+
* invariants like `defaultLocale ∈ locales`), and emits parse-time
|
|
60
|
+
* `@unimplemented` warnings for fields that are authored but have no
|
|
61
|
+
* runtime consumer yet.
|
|
62
|
+
*
|
|
63
|
+
* Throws on validation failure — same contract as `defineSaasConfig`
|
|
64
|
+
* and `defineTechnicalDocConfig`.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* import { AvailableLanguage } from '@wildo-ai/saas-models/public-runtime';
|
|
69
|
+
* import { defineWebsiteConfig } from '@wildo-ai/saas-website';
|
|
70
|
+
*
|
|
71
|
+
* export default defineWebsiteConfig({
|
|
72
|
+
* publicOrigin: 'https://wonder-todos.example.com',
|
|
73
|
+
* appOrigin: 'https://app.wonder-todos.example.com',
|
|
74
|
+
* defaultLocale: AvailableLanguage.EN,
|
|
75
|
+
* locales: [
|
|
76
|
+
* { locale: AvailableLanguage.EN, path: 'en' },
|
|
77
|
+
* { locale: AvailableLanguage.FR, path: 'fr' },
|
|
78
|
+
* ],
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function defineWebsiteConfig(config: WildoMarketingWebsiteConfigInput): WildoMarketingWebsiteConfig;
|
|
83
|
+
//# sourceMappingURL=define-website-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-website-config.d.ts","sourceRoot":"","sources":["../../../../src/config/define-website-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,OAAO,EAEL,KAAK,2BAA2B,EAChC,KAAK,gCAAgC,EACtC,MAAM,gCAAgC,CAAC;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gCAAgC,GACvC,2BAA2B,CAI7B"}
|