@shoalrun/cli 0.1.0-beta.1 → 1.1.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/CHANGELOG.md +36 -0
- package/CODE-REFERENCES.md +156 -0
- package/README.md +18 -6
- package/adapters/python/requirements.txt +1 -0
- package/adapters/python/shoalrun_reference.py +234 -0
- package/adapters/typescript/README.md +27 -0
- package/adapters/typescript/shoalrun-reference.mjs +260 -0
- package/agent-docs/.well-known/shoalrun/navigation/project-updates-50f26fe22670.txt +6 -2
- package/agent-docs/SNAPSHOT.json +5 -5
- package/agent-docs/about.md +3 -3
- package/agent-docs/api-docs/code-reference-settings.md +160 -0
- package/agent-docs/api-docs/code-reference-settings.sections/catalog-settings.md +50 -0
- package/agent-docs/api-docs/code-reference-settings.sections/complete-reference-page.md +46 -0
- package/agent-docs/api-docs/code-reference-settings.sections/converter-snapshot.md +58 -0
- package/agent-docs/api-docs/code-reference-settings.sections/descriptions-type-links-and-source-links.md +40 -0
- package/agent-docs/api-docs/code-reference-settings.sections/html-markdown-and-agents.md +38 -0
- package/agent-docs/api-docs/code-reference-settings.sections/metadata-and-selection.md +38 -0
- package/agent-docs/api-docs/code-reference-settings.sections/publication-sources.md +54 -0
- package/agent-docs/api-docs/code-reference-settings.sections/python-adapter-limits.md +38 -0
- package/agent-docs/api-docs/code-reference-settings.sections/related-reading.md +32 -0
- package/agent-docs/api-docs/code-reference-settings.sections/symbol-fields.md +56 -0
- package/agent-docs/api-docs/code-references.md +151 -0
- package/agent-docs/api-docs/code-references.sections/a-real-typescript-example.md +38 -0
- package/agent-docs/api-docs/code-references.sections/add-python-source.md +56 -0
- package/agent-docs/api-docs/code-references.sections/before-you-start.md +40 -0
- package/agent-docs/api-docs/code-references.sections/build-and-verify.md +47 -0
- package/agent-docs/api-docs/code-references.sections/choose-the-reading-layout.md +46 -0
- package/agent-docs/api-docs/code-references.sections/extract-and-validate-a-snapshot.md +52 -0
- package/agent-docs/api-docs/code-references.sections/html-markdown-and-agents.md +42 -0
- package/agent-docs/api-docs/code-references.sections/register-the-catalog-and-navigation.md +58 -0
- package/agent-docs/api-docs/code-references.sections/related-reading.md +40 -0
- package/agent-docs/api-docs/code-references.sections/versions-profiles-and-delivery.md +40 -0
- package/agent-docs/api-docs/typescript-references.md +93 -0
- package/agent-docs/author/agent-overview.md +2 -2
- package/agent-docs/author/components/for-facet.md +127 -0
- package/agent-docs/author/components/only.md +3 -1
- package/agent-docs/author/components.md +2 -1
- package/agent-docs/author/reader-views.md +2 -2
- package/agent-docs/author/reader-views.sections/configure-the-choices.md +2 -2
- package/agent-docs/author/reader-views.sections/connect-your-own-control.md +2 -2
- package/agent-docs/author/reader-views.sections/how-it-works-for-agents.md +2 -2
- package/agent-docs/author/reader-views.sections/mark-pages.md +2 -2
- package/agent-docs/author/reader-views.sections/mark-sections-and-add-an-entry-choice.md +2 -2
- package/agent-docs/author/reader-views.sections/place-filter-controls.md +2 -2
- package/agent-docs/author/reader-views.sections/try-the-controls-here.md +2 -2
- package/agent-docs/changelog/code-api-references.md +44 -0
- package/agent-docs/changelog/facet-typescript.md +54 -0
- package/agent-docs/changelog.md +17 -1
- package/agent-docs/cli.md +11 -1
- package/agent-docs/cli.sections/audit-a-project-and-api-sources.md +1 -1
- package/agent-docs/cli.sections/author-pages.md +1 -1
- package/agent-docs/cli.sections/build-and-serve.md +1 -1
- package/agent-docs/cli.sections/inspect-config-and-operations.md +1 -1
- package/agent-docs/cli.sections/npm-scripts-in-this-repository.md +1 -1
- package/agent-docs/cli.sections/related-reading.md +1 -1
- package/agent-docs/cli.sections/search-and-chat.md +1 -1
- package/agent-docs/cli.sections/start-a-project.md +1 -1
- package/agent-docs/cli.sections/validate-code-reference-snapshots.md +41 -0
- package/agent-docs/cli.sections/working-tree-authoring-tools.md +1 -1
- package/agent-docs/config/apis.md +5 -1
- package/agent-docs/config/examples.md +3 -3
- package/agent-docs/config/examples.sections/feature-showcase.md +3 -3
- package/agent-docs/config/examples.sections/minimal-site.md +2 -2
- package/agent-docs/config/examples.sections/multilingual-help-center.md +2 -2
- package/agent-docs/config/examples.sections/parcel-api-documentation.md +2 -2
- package/agent-docs/config/examples.sections/related-reading.md +2 -2
- package/agent-docs/config/examples.sections/shared-company-preset.md +2 -2
- package/agent-docs/config/outputs.md +12 -12
- package/agent-docs/config/outputs.sections/exports.md +12 -12
- package/agent-docs/config/outputs.sections/metadata.md +1 -1
- package/agent-docs/config/outputs.sections/pdf-output.md +1 -1
- package/agent-docs/config/outputs.sections/related-reading.md +1 -1
- package/agent-docs/config/site.md +17 -17
- package/agent-docs/config/site.sections/related-reading.md +1 -1
- package/agent-docs/config/site.sections/theme.md +1 -1
- package/agent-docs/config.md +2 -2
- package/agent-docs/configuration.md +2 -2
- package/agent-docs/configuration.sections/build-several-sites-from-shared-content.md +1 -1
- package/agent-docs/configuration.sections/change-inherited-lists-deliberately.md +1 -1
- package/agent-docs/configuration.sections/extract-a-section-with-include.md +1 -1
- package/agent-docs/configuration.sections/inspect-and-validate-changes.md +1 -1
- package/agent-docs/configuration.sections/related-reading.md +1 -1
- package/agent-docs/configuration.sections/separate-config-inheritance-from-page-metadata.md +1 -1
- package/agent-docs/configuration.sections/share-defaults-through-extends.md +1 -1
- package/agent-docs/configuration.sections/start-with-one-working-file.md +2 -2
- package/agent-docs/configuration.sections/understand-the-three-stages.md +1 -1
- package/agent-docs/configuration.sections/understand-where-paths-point.md +1 -1
- package/agent-docs/content-delivery/api.md +10 -2
- package/agent-docs/content-delivery/api.sections/errors.md +52 -0
- package/agent-docs/content-delivery/api.sections/generated-typescript-reference.md +36 -0
- package/agent-docs/content-delivery/api.sections/html-markdown-and-agents.md +36 -0
- package/agent-docs/content-delivery/api.sections/mount-html.md +42 -0
- package/agent-docs/content-delivery/api.sections/open-a-rest-source.md +55 -0
- package/agent-docs/content-delivery/api.sections/open-a-source.md +51 -0
- package/agent-docs/content-delivery/api.sections/read-a-snapshot.md +55 -0
- package/agent-docs/content-delivery/api.sections/related-reading.md +42 -0
- package/agent-docs/content-delivery/api.sections/validate-a-manifest.md +40 -0
- package/agent-docs/content-delivery/client.md +9 -1
- package/agent-docs/content-delivery/sdk/all.md +1772 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-exportedid.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-id.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-title.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentasset-mediatype.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentasset.md +40 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliveryerror-code.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliveryerror.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-manifestbytes.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-resourcebytes.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-resources.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contenterrorcode.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-bytes.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-digest.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-path.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentformat.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-asset.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-fragment.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-href.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-kind.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-query.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-ref.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink.md +52 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-assets.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-diagnostics.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-digest.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-files.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-kind.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-publicbase.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-resources.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-review.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest.md +68 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-anchors.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-links.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-unmount.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount.md +49 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-channel.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-language.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-product.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-version.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentref.md +43 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrefkey.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation-anchors.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation-links.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-assets.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-canonicalurl.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-externaldependencies.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-ref.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-representations.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-source.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-summary.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-title.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-type.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource.md +65 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresourcekey.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry-resource.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterror-error.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterror.md +43 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterrorcode.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-resources.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-revision.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-resource.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-revision.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-content.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-format.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-representation.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-resource.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-dispose.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-get.md +45 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-list.md +38 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot.md +47 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-fetch.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-limits.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-manifesturl.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-signal.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-mountcontent.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-openmanifestcontentsource.md +54 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-openrestcontentsource.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-baseurl.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-fetch.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-limits.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-signal.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions.md +50 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-validatecontentmanifest.md +45 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content.md +65 -0
- package/agent-docs/content-delivery/sdk/content-anchor/exported-id.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor/id.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor/title.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor.md +71 -0
- package/agent-docs/content-delivery/sdk/content-asset/media-type.md +25 -0
- package/agent-docs/content-delivery/sdk/content-asset.md +43 -0
- package/agent-docs/content-delivery/sdk/content-delivery-error/code.md +25 -0
- package/agent-docs/content-delivery/sdk/content-delivery-error.md +53 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/manifest-bytes.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/resource-bytes.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/resources.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits.md +77 -0
- package/agent-docs/content-delivery/sdk/content-error-code.md +23 -0
- package/agent-docs/content-delivery/sdk/content-file/bytes.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file/digest.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file/path.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file.md +71 -0
- package/agent-docs/content-delivery/sdk/content-format.md +23 -0
- package/agent-docs/content-delivery/sdk/content-link/asset.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/fragment.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/href.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/kind.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/query.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/ref.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link.md +127 -0
- package/agent-docs/content-delivery/sdk/content-manifest/assets.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/diagnostics.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/digest.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/files.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/kind.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/public-base.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/resources.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/review.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest.md +179 -0
- package/agent-docs/content-delivery/sdk/content-mount/anchors.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount/links.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount/unmount.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount.md +82 -0
- package/agent-docs/content-delivery/sdk/content-publication/channel.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/language.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/product.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication.md +85 -0
- package/agent-docs/content-delivery/sdk/content-ref-key.md +34 -0
- package/agent-docs/content-delivery/sdk/content-ref.md +40 -0
- package/agent-docs/content-delivery/sdk/content-representation/anchors.md +25 -0
- package/agent-docs/content-delivery/sdk/content-representation/links.md +25 -0
- package/agent-docs/content-delivery/sdk/content-representation.md +57 -0
- package/agent-docs/content-delivery/sdk/content-resource/assets.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/canonical-url.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/external-dependencies.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/ref.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/representations.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/source.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/summary.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/title.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/type.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource-key.md +34 -0
- package/agent-docs/content-delivery/sdk/content-resource.md +192 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry/resource.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry.md +57 -0
- package/agent-docs/content-delivery/sdk/content-rest-error/error.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-error-code.md +23 -0
- package/agent-docs/content-delivery/sdk/content-rest-error.md +46 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/resources.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/revision.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list.md +85 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/resource.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/revision.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource.md +99 -0
- package/agent-docs/content-delivery/sdk/content-result/content.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/format.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/representation.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/resource.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result.md +114 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/dispose.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/get.md +36 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/list.md +29 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot.md +123 -0
- package/agent-docs/content-delivery/sdk/exports.md +742 -0
- package/agent-docs/content-delivery/sdk/exports.sections/functions.md +30 -0
- package/agent-docs/content-delivery/sdk/exports.sections/members.md +47 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentanchor.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentasset.md +37 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentdeliveryerror.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentdeliverylimits.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contenterrorcode.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentfile.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentformat.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentlink.md +49 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentmanifest.md +65 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentmount.md +46 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentpublication.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentref.md +40 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrefkey.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrepresentation.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresource.md +62 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresourcekey.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestentry.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresterror.md +40 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresterrorcode.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestlist.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestresource.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresult.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentsnapshot.md +44 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-manifestcontentsourceoptions.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-mountcontent.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-openmanifestcontentsource.md +51 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-openrestcontentsource.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-restcontentsourceoptions.md +47 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-validatecontentmanifest.md +42 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/fetch.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/limits.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/manifest-url.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/signal.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options.md +93 -0
- package/agent-docs/content-delivery/sdk/mount-content.md +46 -0
- package/agent-docs/content-delivery/sdk/open-manifest-content-source.md +51 -0
- package/agent-docs/content-delivery/sdk/open-rest-content-source.md +39 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/base-url.md +28 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/fetch.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/limits.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/signal.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options.md +125 -0
- package/agent-docs/content-delivery/sdk/validate-content-manifest.md +38 -0
- package/agent-docs/contribute/agent-skills.md +33 -6
- package/agent-docs/documents.json +7710 -530
- package/agent-docs/features.md +20 -18
- package/agent-docs/provenance.json +6 -6
- package/agent-docs/publish/api-references.md +3 -1
- package/agent-docs/publish/api-references.sections/author-the-reference-page.md +3 -1
- package/agent-docs/publish/api-references.sections/build-and-verify-the-output.md +3 -1
- package/agent-docs/publish/api-references.sections/inspect-the-machine-readable-contract.md +3 -1
- package/agent-docs/publish/api-references.sections/next-steps.md +3 -1
- package/agent-docs/publish/api-references.sections/preview-a-small-api-reference.md +3 -1
- package/agent-docs/publish/api-references.sections/put-the-spec-in-your-project.md +3 -1
- package/agent-docs/publish/api-references.sections/register-the-operation.md +3 -1
- package/agent-docs/publish/api-references.sections/related-reading.md +3 -1
- package/agent-docs/publish/api-references.sections/review-imported-content-before-publishing.md +3 -1
- package/agent-docs/publish/api-references.sections/what-readers-get.md +3 -1
- package/agent-docs/publish/content-export.md +3 -1
- package/agent-docs/publish/content-export.sections/assets-downloads-and-notices.md +1 -1
- package/agent-docs/publish/content-export.sections/check-the-result.md +1 -1
- package/agent-docs/publish/content-export.sections/inspect-the-manifest.md +1 -1
- package/agent-docs/publish/content-export.sections/prerequisites.md +1 -1
- package/agent-docs/publish/content-export.sections/related-reading.md +1 -1
- package/agent-docs/publish/content-export.sections/review-exported-api-material.md +1 -1
- package/agent-docs/publish/content-export.sections/try-the-help-drawer-example.md +1 -1
- package/agent-docs/publish/content-export.sections/what-the-representations-retain.md +1 -1
- package/agent-docs/publish/pdf.md +2 -2
- package/agent-docs/publish/pdf.sections/apply-print-styling.md +1 -1
- package/agent-docs/publish/pdf.sections/check-the-result.md +1 -1
- package/agent-docs/publish/pdf.sections/export-a-page-or-publication.md +2 -2
- package/agent-docs/publish/pdf.sections/html-markdown-and-agents.md +1 -1
- package/agent-docs/publish/pdf.sections/offer-browser-page-printing.md +1 -1
- package/agent-docs/publish/pdf.sections/offer-direct-downloads-through-a-node-server.md +1 -1
- package/agent-docs/publish/pdf.sections/prerequisites.md +1 -1
- package/agent-docs/publish/pdf.sections/publish-an-optional-manual-download.md +1 -1
- package/agent-docs/publish/single-source-sites.md +26 -2
- package/agent-docs/publish/single-source-sites.sections/build-and-check-each-output.md +49 -0
- package/agent-docs/publish/single-source-sites.sections/html-markdown-and-agents.md +33 -0
- package/agent-docs/publish/single-source-sites.sections/include-additional-sections-in-a-build.md +47 -0
- package/agent-docs/publish/single-source-sites.sections/related-reading.md +43 -0
- package/agent-docs/publish/single-source-sites.sections/select-the-pages-for-each-site.md +74 -0
- package/agent-docs/publish/single-source-sites.sections/share-the-base-configuration.md +93 -0
- package/agent-docs/reference/agent-skills.md +2 -2
- package/agent-docs/search-index.json +1 -1
- package/agent-docs/start.md +3 -3
- package/agent-docs/start.sections/add-the-page-to-navigation.md +2 -2
- package/agent-docs/start.sections/build-and-check-both-outputs.md +2 -2
- package/agent-docs/start.sections/build-this-site.md +2 -2
- package/agent-docs/start.sections/check-writing-style.md +2 -2
- package/agent-docs/start.sections/create-a-page.md +2 -2
- package/agent-docs/start.sections/make-it-yours.md +2 -2
- package/agent-docs/start.sections/migrating-from-github-packages.md +2 -2
- package/agent-docs/start.sections/prerequisites.md +2 -2
- package/agent-docs/start.sections/related-reading.md +2 -2
- package/agent-docs/start.sections/start-your-own-project.md +3 -3
- package/agent-docs/status.md +6 -4
- package/agent-docs/styling/themes.md +7 -3
- package/agent-docs/what-is-shoalrun.md +2 -2
- package/assets/search-lexical.js +15 -4
- package/dist/artifact-bundle.d.ts +1 -0
- package/dist/artifact-bundle.js +11 -3
- package/dist/cli-discovery.d.ts +1 -1
- package/dist/cli-discovery.js +1 -0
- package/dist/cli.js +7 -0
- package/dist/code-reference-model.d.ts +85 -0
- package/dist/code-reference-model.js +73 -0
- package/dist/code-references.d.ts +23 -0
- package/dist/code-references.js +371 -0
- package/dist/compiler-config.d.ts +1 -0
- package/dist/compiler.d.ts +8 -0
- package/dist/compiler.js +14 -7
- package/dist/component-names.js +1 -1
- package/dist/component-transform.js +14 -22
- package/dist/conditional-tree.d.ts +2 -0
- package/dist/conditional-tree.js +14 -0
- package/dist/config.js +1 -1
- package/dist/content-delivery-contract.d.ts +39 -0
- package/dist/content-delivery-contract.js +2 -0
- package/dist/content-delivery-validation.d.ts +6 -0
- package/dist/content-delivery-validation.js +6 -0
- package/dist/content-delivery.d.ts +19 -1
- package/dist/content-delivery.js +10 -1
- package/dist/content-export-command.d.ts +42 -3
- package/dist/content-export.d.ts +42 -3
- package/dist/content-export.js +15 -6
- package/dist/content-filter.d.ts +2 -0
- package/dist/content-filter.js +4 -0
- package/dist/content-mount.d.ts +12 -1
- package/dist/content-mount.js +8 -1
- package/dist/content-rest-client.d.ts +11 -1
- package/dist/content-rest-client.js +4 -1
- package/dist/content-rest-contract.d.ts +5 -0
- package/dist/content-source.d.ts +2 -0
- package/dist/content-workspace.d.ts +5 -1
- package/dist/content-workspace.js +7 -2
- package/dist/deployment-profile.d.ts +3 -1
- package/dist/deployment-profile.js +18 -19
- package/dist/fonts.d.ts +9 -0
- package/dist/fonts.js +58 -3
- package/dist/page-materialization.js +3 -2
- package/dist/page-renderer.d.ts +1 -0
- package/dist/page-renderer.js +3 -1
- package/dist/palettes.d.ts +1 -1
- package/dist/publication-manifest.js +1 -1
- package/dist/publication-render.d.ts +2 -1
- package/dist/publication-render.js +2 -2
- package/dist/representation-tree.js +12 -2
- package/dist/search-query.js +13 -6
- package/dist/section-selection.d.ts +29 -0
- package/dist/section-selection.js +92 -0
- package/dist/snippets.d.ts +1 -0
- package/example-configs/facet-sections/README.md +37 -0
- package/example-configs/facet-sections/base.yaml +29 -0
- package/example-configs/facet-sections/content/billing.mdx +25 -0
- package/example-configs/facet-sections/customer.config.yaml +4 -0
- package/example-configs/facet-sections/docs.config.yaml +3 -0
- package/example-configs/faceted-sites/README.md +4 -2
- package/examples/code-references/content/start.md +53 -0
- package/examples/code-references/docs.config.yaml +262 -0
- package/examples/code-references/python/orchard/__init__.py +11 -0
- package/examples/code-references/python/orchard/client.py +212 -0
- package/examples/code-references/python/orchard/errors.py +31 -0
- package/examples/code-references/python/orchard/models.py +69 -0
- package/examples/code-references/python/orchard/pagination.py +39 -0
- package/examples/code-references/reference.json +1244 -0
- package/package.json +9 -1
- package/schemas/code-reference.schema.json +306 -0
- package/skills/shoalrun-author/SKILL.md +17 -0
- package/skills/shoalrun-author/references/code-api-references.md +19 -0
- package/skills/shoalrun-author/references/facet-selection.md +48 -0
- package/skills/shoalrun-brand/SKILL.md +9 -0
- package/skills/shoalrun-component-author/SKILL.md +9 -0
- package/skills/shoalrun-pdf/SKILL.md +9 -0
- package/skills/shoalrun-recipes/SKILL.md +9 -0
- package/skills/shoalrun-setup/SKILL.md +9 -0
- package/skills/shoalrun-walkthrough/SKILL.md +9 -0
- package/styles/site.css +61 -2
|
@@ -1,18 +1,22 @@
|
|
|
1
|
+
import { createSectionSelection } from './section-selection.js';
|
|
1
2
|
import { documentKey } from './publication-identity.js';
|
|
2
3
|
import { matchesFeatures } from './deployment-profile.js';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { readFile } from 'node:fs/promises';
|
|
5
6
|
import { parse } from './content.js';
|
|
6
7
|
import { planAuthoredDocuments } from './publication-plan.js';
|
|
8
|
+
import { materializeCodeReferences } from './code-references.js';
|
|
7
9
|
import { materializeApiReferences } from './api-publication-plan.js';
|
|
8
10
|
import { explainSegments } from './config.js';
|
|
9
11
|
import { validateSnippetConfig } from './snippets.js';
|
|
10
12
|
const keyFor = documentKey;
|
|
11
13
|
/** Shared source resolution. No website navigation, styles, hosting or provider setup. */
|
|
12
|
-
export async function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions }) {
|
|
14
|
+
export async function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions, sectionSelection: suppliedSectionSelection }) {
|
|
15
|
+
const sectionSelection = suppliedSectionSelection ?? createSectionSelection(readerFilters, contentFilter, config.publications);
|
|
13
16
|
const { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir } = await planAuthoredDocuments({
|
|
14
17
|
base, basePath, config, variants, language, readerFilters, contentFilter, featureContext: loaded.deployment?.context, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions
|
|
15
18
|
});
|
|
19
|
+
await materializeCodeReferences({ config, loaded, plan: { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir }, base, basePath, variants, language, readerFilters, contentFilter, dependencies: metadataDependencies, allowRouteCollisions });
|
|
16
20
|
if (config.snippets !== undefined && (!config.snippets || typeof config.snippets !== 'object' || Array.isArray(config.snippets)))
|
|
17
21
|
throw new Error('snippets must be a mapping');
|
|
18
22
|
const snippets = new Map();
|
|
@@ -32,6 +36,7 @@ export async function prepareContentWorkspace({ base, basePath, config, loaded,
|
|
|
32
36
|
});
|
|
33
37
|
const { api, sourceForVariant, knownOperations } = apiPlan;
|
|
34
38
|
for (const [key, doc] of docs) {
|
|
39
|
+
doc.sectionSelection = sectionSelection;
|
|
35
40
|
doc.featureContext = loaded.deployment?.context;
|
|
36
41
|
for (const operationId of doc.frontmatter.operations ?? []) {
|
|
37
42
|
const known = knownOperations.get(operationId);
|
|
@@ -82,6 +87,6 @@ export async function prepareContentWorkspace({ base, basePath, config, loaded,
|
|
|
82
87
|
throw new Error(`no OpenAPI source for ${variant.channel}/${variant.version} (${operationId})`);
|
|
83
88
|
return { ...binding, sourceOperationId: operation.sourceOperationId };
|
|
84
89
|
};
|
|
85
|
-
return { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir, snippets,
|
|
90
|
+
return { sectionSelection, docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir, snippets,
|
|
86
91
|
apiPlan, api, sourceForVariant, knownOperations, relatedApiTargets, guidesByApi, sourceForOperation };
|
|
87
92
|
}
|
|
@@ -34,7 +34,9 @@ export type ProfileResolution = {
|
|
|
34
34
|
export declare function validateFeatureClassification(source: Record<string, unknown>, context: FeatureContext | undefined, label: string): void;
|
|
35
35
|
export declare function featureRequirements(value: unknown, context: FeatureContext | undefined, label: string): FeatureRequirements | undefined;
|
|
36
36
|
export declare function matchesFeatures(value: unknown, context: FeatureContext | undefined, label: string, kind?: 'page' | 'section'): boolean;
|
|
37
|
-
/**
|
|
37
|
+
/** Evaluate a feature guard without expanding its children. */
|
|
38
|
+
export declare function evaluateFeatureGuard(node: any, context: FeatureContext | undefined, file: string, ancestorIncluded?: boolean, record?: boolean): boolean | undefined;
|
|
39
|
+
/** Compatibility entry point for consumers that only select feature grants. */
|
|
38
40
|
export declare function pruneFeatureTree(tree: any, context: FeatureContext | undefined, file: string): any;
|
|
39
41
|
/** Returned to the caller or written under .shoalrun, never a served artifact. */
|
|
40
42
|
export declare function profileSelection(resolution: ProfileResolution | undefined): {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pruneConditionalTree } from './conditional-tree.js';
|
|
1
2
|
import { resolvePublication } from './compiler-config.js';
|
|
2
3
|
import { publicationKey } from './publication-identity.js';
|
|
3
4
|
import { readFile, lstat, realpath } from 'node:fs/promises';
|
|
@@ -69,26 +70,24 @@ export function matchesFeatures(value, context, label, kind = 'page') {
|
|
|
69
70
|
context?.decisions.push({ kind, id: label, included, ...(requirement ? { requires: requirement } : {}) });
|
|
70
71
|
return included;
|
|
71
72
|
}
|
|
72
|
-
/**
|
|
73
|
+
/** Evaluate a feature guard without expanding its children. */
|
|
74
|
+
export function evaluateFeatureGuard(node, context, file, ancestorIncluded = true, record = true) {
|
|
75
|
+
if (node.name !== 'ForFeature')
|
|
76
|
+
return;
|
|
77
|
+
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFeature>`;
|
|
78
|
+
const attributes = node.attributes ?? [];
|
|
79
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || !['allOf', 'anyOf'].includes(item.name) || typeof item.value !== 'string') || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
80
|
+
throw new Error(`${label} needs block content and distinct literal allOf/anyOf attributes`);
|
|
81
|
+
const requirements = Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/).filter(Boolean)]));
|
|
82
|
+
const target = !record && context ? { ...context, decisions: [] } : context;
|
|
83
|
+
const included = matchesFeatures(requirements, target, label, 'section');
|
|
84
|
+
if (!ancestorIncluded && target?.decisions.length)
|
|
85
|
+
target.decisions[target.decisions.length - 1].included = false;
|
|
86
|
+
return included;
|
|
87
|
+
}
|
|
88
|
+
/** Compatibility entry point for consumers that only select feature grants. */
|
|
73
89
|
export function pruneFeatureTree(tree, context, file) {
|
|
74
|
-
|
|
75
|
-
if (!node || typeof node !== 'object')
|
|
76
|
-
return [node];
|
|
77
|
-
if (node.name === 'ForFeature') {
|
|
78
|
-
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFeature>`;
|
|
79
|
-
const attributes = node.attributes ?? [];
|
|
80
|
-
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || !['allOf', 'anyOf'].includes(item.name) || typeof item.value !== 'string') || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
81
|
-
throw new Error(`${label} needs block content and distinct literal allOf/anyOf attributes`);
|
|
82
|
-
const requirements = Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/).filter(Boolean)]));
|
|
83
|
-
const included = matchesFeatures(requirements, context, label, 'section');
|
|
84
|
-
if (!parentIncluded && context?.decisions.length)
|
|
85
|
-
context.decisions[context.decisions.length - 1].included = false;
|
|
86
|
-
const children = node.children.flatMap((child) => walk(child, parentIncluded && included));
|
|
87
|
-
return included && parentIncluded ? children : [];
|
|
88
|
-
}
|
|
89
|
-
return [{ ...node, ...(node.children ? { children: node.children.flatMap((child) => walk(child, parentIncluded)) } : {}) }];
|
|
90
|
-
};
|
|
91
|
-
return walk(tree)[0];
|
|
90
|
+
return pruneConditionalTree(tree, (node, ancestorIncluded) => evaluateFeatureGuard(node, context, file, ancestorIncluded));
|
|
92
91
|
}
|
|
93
92
|
/** Returned to the caller or written under .shoalrun, never a served artifact. */
|
|
94
93
|
export function profileSelection(resolution) {
|
package/dist/fonts.d.ts
CHANGED
|
@@ -6,12 +6,18 @@ export type FontFace = {
|
|
|
6
6
|
style: 'normal' | 'italic';
|
|
7
7
|
weight: string;
|
|
8
8
|
};
|
|
9
|
+
export type FontPreload = {
|
|
10
|
+
href: string;
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
9
13
|
export type SiteFonts = {
|
|
10
14
|
bundled: boolean;
|
|
11
15
|
faces: FontFace[];
|
|
12
16
|
tokens: Partial<Record<FontRole, string>>;
|
|
13
17
|
preload?: string;
|
|
18
|
+
preloadFaces?: FontFace[];
|
|
14
19
|
};
|
|
20
|
+
export declare const fontMediaType: (file: string) => string | undefined;
|
|
15
21
|
export declare const bundledFonts: readonly [{
|
|
16
22
|
readonly family: "Inter";
|
|
17
23
|
readonly file: "inter.woff2";
|
|
@@ -51,4 +57,7 @@ export declare const bundledFonts: readonly [{
|
|
|
51
57
|
}];
|
|
52
58
|
export declare const bundledFontLicenses: string[];
|
|
53
59
|
export declare function resolveFonts(value: unknown, preset: string, declaringFile: string): SiteFonts;
|
|
60
|
+
/** Pin project font URLs to the same bytes that will be emitted by this build. */
|
|
61
|
+
export declare function prepareFontAssets(fonts: SiteFonts): Promise<Map<string, Buffer>>;
|
|
62
|
+
export declare function customFontPreloads(fonts: SiteFonts): FontPreload[];
|
|
54
63
|
export declare function fontsCss(fonts: SiteFonts): string | undefined;
|
package/dist/fonts.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
export const fontMediaType = (file) => ({ '.woff2': 'font/woff2', '.woff': 'font/woff', '.ttf': 'font/ttf', '.otf': 'font/otf' }[path.extname(file).toLowerCase()]);
|
|
2
5
|
// Latin variable fonts from Fontsource, all under the SIL Open Font License. Readers download only the faces a page uses.
|
|
3
6
|
export const bundledFonts = [
|
|
4
7
|
{ family: 'Inter', file: 'inter.woff2', style: 'normal' },
|
|
@@ -22,7 +25,7 @@ const fallbackFaces = [
|
|
|
22
25
|
{ family: 'Jost', src: localSans, size: '95.84%', ascent: '111.65%', descent: '39.13%' }
|
|
23
26
|
];
|
|
24
27
|
export const bundledFontLicenses = ['inter', 'figtree', 'source-serif-4', 'jetbrains-mono', 'jost'].map(name => `${name}-LICENSE.txt`);
|
|
25
|
-
//
|
|
28
|
+
// Begin fetching the preset's body font before the browser discovers its CSS rule.
|
|
26
29
|
const presetBodyFont = { shoal: 'inter.woff2', reef: 'figtree.woff2', ledger: 'source-serif-4.woff2', vice: 'figtree.woff2' };
|
|
27
30
|
const fallbacks = {
|
|
28
31
|
body: 'ui-sans-serif, system-ui, sans-serif',
|
|
@@ -45,6 +48,8 @@ export function resolveFonts(value, preset, declaringFile) {
|
|
|
45
48
|
if (unknown.length)
|
|
46
49
|
throw new Error(`theme.fonts accepts only body, headings, and code; remove ${unknown.join(', ')}`);
|
|
47
50
|
const faces = [];
|
|
51
|
+
const preloadFaces = [];
|
|
52
|
+
const families = {};
|
|
48
53
|
const tokens = {};
|
|
49
54
|
for (const role of roles) {
|
|
50
55
|
const entry = value[role];
|
|
@@ -56,6 +61,7 @@ export function resolveFonts(value, preset, declaringFile) {
|
|
|
56
61
|
if (typeof spec.family !== 'string' || !familyName.test(spec.family))
|
|
57
62
|
throw new Error(`theme.fonts.${role}.family must be a font name using letters, numbers, spaces, dots, dashes, or underscores`);
|
|
58
63
|
const files = spec.files ?? [];
|
|
64
|
+
families[role] = spec.family;
|
|
59
65
|
if (!Array.isArray(files))
|
|
60
66
|
throw new Error(`theme.fonts.${role}.files must be a list`);
|
|
61
67
|
for (const [index, item] of files.entries()) {
|
|
@@ -74,11 +80,60 @@ export function resolveFonts(value, preset, declaringFile) {
|
|
|
74
80
|
const file = path.resolve(path.dirname(declaringFile), face.file);
|
|
75
81
|
if (!/^[\w.-]+$/.test(path.basename(file)))
|
|
76
82
|
throw new Error(`${where} file name may use only letters, numbers, dots, dashes, and underscores`);
|
|
77
|
-
|
|
83
|
+
const registration = { family: spec.family, file, route: `/assets/fonts/project/${path.basename(file)}`, style, weight };
|
|
84
|
+
faces.push(registration);
|
|
78
85
|
}
|
|
79
86
|
tokens[role] = `"${spec.family}", ${fallbacks[role]}`;
|
|
80
87
|
}
|
|
81
|
-
|
|
88
|
+
// CSS resolves style before weight and prefers the last equivalent registration.
|
|
89
|
+
const registrations = [...bundledFonts.map(font => ({ family: font.family, file: font.file, route: `/assets/fonts/${font.file}`, style: font.style, weight: '100 900' })), ...faces];
|
|
90
|
+
for (const role of ['body', 'headings']) {
|
|
91
|
+
if (!families[role])
|
|
92
|
+
continue;
|
|
93
|
+
const target = role === 'body' ? 400 : preset === 'vice' ? 800 : 700;
|
|
94
|
+
const style = role === 'headings' && preset === 'vice' ? 'italic' : 'normal';
|
|
95
|
+
const family = registrations.filter(face => face.family === families[role]);
|
|
96
|
+
const exactStyle = family.filter(face => face.style === style);
|
|
97
|
+
const rank = (face) => {
|
|
98
|
+
const [min, max = min] = face.weight.split(' ').map(Number);
|
|
99
|
+
if (min <= target && max >= target)
|
|
100
|
+
return [0, 0];
|
|
101
|
+
if (target >= 400 && target <= 500) {
|
|
102
|
+
if (min > target && min <= 500)
|
|
103
|
+
return [1, min - target];
|
|
104
|
+
return max < target ? [2, target - max] : [3, min - target];
|
|
105
|
+
}
|
|
106
|
+
if (target < 400)
|
|
107
|
+
return max < target ? [1, target - max] : [2, min - target];
|
|
108
|
+
return min > target ? [1, min - target] : [2, target - max];
|
|
109
|
+
};
|
|
110
|
+
const candidates = (exactStyle.length ? exactStyle : family).map((face, index) => ({ face, index, rank: rank(face) }));
|
|
111
|
+
candidates.sort((a, b) => a.rank[0] - b.rank[0] || a.rank[1] - b.rank[1] || b.index - a.index);
|
|
112
|
+
if (candidates[0])
|
|
113
|
+
preloadFaces.push(candidates[0].face);
|
|
114
|
+
}
|
|
115
|
+
return { bundled: true, faces, tokens, preload: tokens.body ? undefined : presetBodyFont[preset], preloadFaces };
|
|
116
|
+
}
|
|
117
|
+
/** Pin project font URLs to the same bytes that will be emitted by this build. */
|
|
118
|
+
export async function prepareFontAssets(fonts) {
|
|
119
|
+
const files = new Map();
|
|
120
|
+
const assets = new Map();
|
|
121
|
+
for (const face of fonts.faces) {
|
|
122
|
+
let bytes = files.get(face.file);
|
|
123
|
+
if (!bytes) {
|
|
124
|
+
bytes = await readFile(face.file);
|
|
125
|
+
files.set(face.file, bytes);
|
|
126
|
+
}
|
|
127
|
+
const extension = path.extname(face.file).toLowerCase();
|
|
128
|
+
const name = path.basename(face.file, path.extname(face.file));
|
|
129
|
+
const hash = createHash('sha256').update(bytes).digest('hex');
|
|
130
|
+
face.route = `/assets/fonts/project/${name}-${hash}${extension}`;
|
|
131
|
+
assets.set(face.route, bytes);
|
|
132
|
+
}
|
|
133
|
+
return assets;
|
|
134
|
+
}
|
|
135
|
+
export function customFontPreloads(fonts) {
|
|
136
|
+
return [...new Map((fonts.preloadFaces ?? []).map(face => [face.route, { href: face.route, type: fontMediaType(face.file) }])).values()];
|
|
82
137
|
}
|
|
83
138
|
const face = (family, url, style, weight, format) => `@font-face{font-family:"${family}";src:url("${url}") format("${format}");font-style:${style};font-weight:${weight};font-display:swap}`;
|
|
84
139
|
export function fontsCss(fonts) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { renderCodeReference } from './code-references.js';
|
|
1
2
|
import { documentKey, publicationKey } from './publication-identity.js';
|
|
2
3
|
import { createHash } from 'node:crypto';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -28,8 +29,8 @@ export async function materializePages({ variables, frontmatterConfig, publicati
|
|
|
28
29
|
for (const other of linkDocuments.values())
|
|
29
30
|
if (keyFor(other.frontmatter.id, doc.variant) === keyFor(other.frontmatter.id, other.variant))
|
|
30
31
|
local.set(other.frontmatter.id, other);
|
|
31
|
-
const parsed = parse.parse(doc.body);
|
|
32
|
-
const tree = await resolveApiEmbedTree(transformMdx(parsed, doc, local, snippets, variables, snippetUses, calloutTypes, base, readerFilters, frontmatterConfig, publications, badgeVariants, componentPlugins, linkDocuments), api, operationId => sourceForOperation(operationId, doc.variant), apiId => {
|
|
32
|
+
const parsed = doc.codeReference ? null : parse.parse(doc.body);
|
|
33
|
+
const tree = doc.codeReference ? renderCodeReference(doc.codeReference, doc, linkDocuments) : await resolveApiEmbedTree(transformMdx(parsed, doc, local, snippets, variables, snippetUses, calloutTypes, base, readerFilters, frontmatterConfig, publications, badgeVariants, componentPlugins, linkDocuments), api, operationId => sourceForOperation(operationId, doc.variant), apiId => {
|
|
33
34
|
if (doc.featureContext?.grants)
|
|
34
35
|
throw new Error('Standalone API schema embeds require an explicitly scoped source and are not supported in profiled builds; select an operation instead');
|
|
35
36
|
const definition = apiPlan.apiDefinitions[apiId];
|
package/dist/page-renderer.d.ts
CHANGED
package/dist/page-renderer.js
CHANGED
|
@@ -38,6 +38,8 @@ export function shareCardText(doc, config) {
|
|
|
38
38
|
return { title, summary: String(summary), type: typeLabel(doc.frontmatter.type) };
|
|
39
39
|
}
|
|
40
40
|
export function typeLabel(type) {
|
|
41
|
+
if (type === 'code-reference')
|
|
42
|
+
return 'Code API reference';
|
|
41
43
|
const words = String(type).split('-').filter(Boolean).map(word => word === 'api' ? 'API' : word);
|
|
42
44
|
const label = words.join(' ');
|
|
43
45
|
return label.charAt(0).toUpperCase() + label.slice(1);
|
|
@@ -192,6 +194,6 @@ export function buildHtmlPage(doc, tree, markdownUrl, siteTitle, navigation, exa
|
|
|
192
194
|
const menu = side || sectionNavigation ? `<a class="mobile-menu" href="#${side ? 'docs-navigation' : 'docs-sections'}">Menu</a>` : '';
|
|
193
195
|
const rail = toc || panel ? `<aside class="page-rail">${doc.endpoint ? `${panel}${toc}` : `${toc}${panel}`}</aside>` : '';
|
|
194
196
|
const breadcrumbs = (shell.breadcrumbs?.length ?? 0) > 1 && !hero ? `<nav class="doc-breadcrumbs" aria-label="Breadcrumb"><ol>${shell.breadcrumbs.map((item, index) => `<li>${index === shell.breadcrumbs.length - 1 ? `<span aria-current="page">${esc(item.label)}</span>` : item.url ? `<a href="${esc(item.url)}">${esc(item.label)}</a>` : `<span>${esc(item.label)}</span>`}</li>`).join('')}</ol></nav>` : '';
|
|
195
|
-
const markup = `<!doctype html><html lang="${esc(doc.variant.language)}"${shell.themeCss || shell.paletteCss ? ` data-theme="${esc(shell.preset ?? 'shoal')}" data-palette="${esc(shell.palette ?? '')}"` : ''}${shell.masthead ? ` data-masthead="${esc(shell.masthead)}"` : ''}${layout === 'docs' ? '' : ` data-layout="${layout}"`}><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="color-scheme" content="${shell.mode === 'system' ? 'light dark' : shell.mode ?? 'light'}">${shell.indexing === false || doc.frontmatter.seo?.noindex === true ? '<meta name="robots" content="noindex">' : ''}${shell.origin ? `<link rel="canonical" href="${esc(absolute(doc.route))}">` : ''}${shell.toggle ? '<script src="/assets/mode.js"></script>' : ''}<title>${esc(String(title))}</title>${description ? `<meta name="description" content="${esc(String(description))}">` : ''}${socialDescription ? `<meta property="og:description" content="${esc(socialDescription)}">` : ''}${social}<link rel="alternate" type="text/markdown" href="${esc(markdownUrl)}"><link rel="describedby" href="/llms.min.txt" title="Documentation index">${icons}${shell.preloadFont ? `<link rel="preload" href="/assets/fonts/${esc(shell.preloadFont)}" as="font" type="font/woff2" crossorigin>` : ''}<link rel="stylesheet" href="/assets/site.css">${article.includes('data-theme-preview') ? '<link rel="stylesheet" href="/assets/theme-preview.css">' : ''}${shell.themeCss ? '<link rel="stylesheet" href="/assets/theme.css" data-theme-link="theme">' : ''}${shell.paletteCss ? '<link rel="stylesheet" href="/assets/palette.css" data-theme-link="palette">' : ''}${shell.badgesCss ? '<link rel="stylesheet" href="/assets/badges.css">' : ''}${shell.themeSwitcher ? `<script src="/assets/theme-switcher.js" data-themes="${esc(shell.themeSwitcher)}"></script>` : ''}${shell.fontsCss ? '<link rel="stylesheet" href="/assets/fonts.css">' : ''}${customCss ? '<link rel="stylesheet" href="/assets/project.css">' : ''}</head><body><a class="skip" href="#main">Skip to content</a>${agent.mode === 'disclosure' ? '' : agentBlock}<header class="mast"><div class="mast-inner">${shell.home ? `<a class="${brandClass}" href="/">${brand}</a>` : `<span class="${brandClass}">${brand}</span>`}${publicationPicker(shell, esc)}${editionLabel && !shell.publicationChoices?.length && (shell.publicationAlternates?.length ?? 0) < 2 ? `<span class="edition">${esc(editionLabel)}</span>` : ''}${menu}${headerTools(shell, doc.variant, esc, readerConfig)}${agent.mode === 'disclosure' ? agentBlock : ''}</div></header>${sectionNavigation}${shortcuts}<div class="layout${layout === 'docs' ? '' : ` layout-${layout}`}${rail ? ' has-rail' : ''}${panel ? ' has-examples' : ''}${doc.endpoint ? ' api-reference' : ''}"><main id="main" class="content" tabindex="-1" data-document-type="${esc(doc.frontmatter.type)}"${readerConfig ? ` data-reader-page="${esc(readerFilterAttribute(doc.readerFilters ?? {}))}"` : ''}>${breadcrumbs}${hero ? '' : `<header class="page-head"><span class="eyebrow">${esc(typeLabel(doc.frontmatter.type))}</span>${doc.endpoint ? '' : badge(doc.frontmatter.subjectLifecycle)}<h1>${esc(doc.frontmatter.title)}${doc.endpoint ? badge(doc.frontmatter.subjectLifecycle) : ''}</h1>${pageHeader && !routeSummary ? `<p class="summary">${esc(pageHeader)}</p>` : ''}${pageDates}${endpoint}${audienceBadges}</header>`}${hero ? (pdfLink ? `<div class="page-formats">${pdfLink}</div>` : '') : `<div class="page-formats">${pdfAction?.placement === 'before' ? pdfLink : ''}<a class="formats" data-markdown-link href="${esc(markdownUrl)}">Read as Markdown</a><button type="button" class="formats" data-copy-markdown hidden>Copy as Markdown</button><span role="status" data-copy-markdown-status></span>${pdfAction?.placement === 'after' ? pdfLink : ''}</div>`}${toc ? '<div class="mobile-outline-slot"></div>' : ''}${jumps}${readerBanner}<article>${article}</article></main>${rail}${side}</div>${footer}${analyticsBootstrap}${readerBootstrap}${pdfAction?.mode === 'print' ? '<script type="module" src="/assets/print.js"></script>' : ''}<script type="module" src="/assets/copy-markdown.js"></script><script type="module" src="/assets/navigation.js"></script><script type="module" src="/assets/reader.js"></script><script type="module" src="/assets/tabs.js"></script>${shell.search ? '<script type="module" src="/assets/search.js"></script>' : ''}${article.includes('data-tooltip') ? '<script type="module" src="/assets/tooltips.js"></script>' : ''}${article.includes('data-component-module') ? '<script type="module" src="/assets/components.js"></script>' : ''}${article.includes('data-file-tree') ? '<script type="module" src="/assets/file-tree.js"></script>' : ''}${article.includes('data-image-expand') ? '<script type="module" src="/assets/image-viewer.js"></script>' : ''}${article.includes('data-table-filter') || article.includes('data-definition-filter') ? '<script type="module" src="/assets/table-filter.js"></script>' : ''}${article.includes('data-walkthrough') ? '<script type="module" src="/assets/walkthrough.js"></script>' : ''}${article.includes('data-cookbook-chooser') ? '<script type="module" src="/assets/cookbook-chooser.js"></script>' : ''}${article.includes('data-theme-preview') ? '<script type="module" src="/assets/theme-preview.js"></script>' : ''}${panel ? '<script type="module" src="/assets/example-panel.js"></script>' : ''}${panel.includes('data-code-samples') ? '<script type="module" src="/assets/code-samples.js"></script>' : ''}</body></html>`;
|
|
197
|
+
const markup = `<!doctype html><html lang="${esc(doc.variant.language)}"${shell.themeCss || shell.paletteCss ? ` data-theme="${esc(shell.preset ?? 'shoal')}" data-palette="${esc(shell.palette ?? '')}"` : ''}${shell.masthead ? ` data-masthead="${esc(shell.masthead)}"` : ''}${layout === 'docs' ? '' : ` data-layout="${layout}"`}><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="color-scheme" content="${shell.mode === 'system' ? 'light dark' : shell.mode ?? 'light'}">${shell.indexing === false || doc.frontmatter.seo?.noindex === true ? '<meta name="robots" content="noindex">' : ''}${shell.origin ? `<link rel="canonical" href="${esc(absolute(doc.route))}">` : ''}${shell.toggle ? '<script src="/assets/mode.js"></script>' : ''}<title>${esc(String(title))}</title>${description ? `<meta name="description" content="${esc(String(description))}">` : ''}${socialDescription ? `<meta property="og:description" content="${esc(socialDescription)}">` : ''}${social}<link rel="alternate" type="text/markdown" href="${esc(markdownUrl)}"><link rel="describedby" href="/llms.min.txt" title="Documentation index">${icons}${shell.preloadFont ? `<link rel="preload" href="/assets/fonts/${esc(shell.preloadFont)}" as="font" type="font/woff2" crossorigin>` : ''}${(shell.preloadFonts ?? []).map(font => `<link rel="preload" href="${esc(font.href)}" as="font" type="${esc(font.type)}" crossorigin>`).join('')}<link rel="stylesheet" href="/assets/site.css">${article.includes('data-theme-preview') ? '<link rel="stylesheet" href="/assets/theme-preview.css">' : ''}${shell.themeCss ? '<link rel="stylesheet" href="/assets/theme.css" data-theme-link="theme">' : ''}${shell.paletteCss ? '<link rel="stylesheet" href="/assets/palette.css" data-theme-link="palette">' : ''}${shell.badgesCss ? '<link rel="stylesheet" href="/assets/badges.css">' : ''}${shell.themeSwitcher ? `<script src="/assets/theme-switcher.js" data-themes="${esc(shell.themeSwitcher)}"></script>` : ''}${shell.fontsCss ? '<link rel="stylesheet" href="/assets/fonts.css">' : ''}${customCss ? '<link rel="stylesheet" href="/assets/project.css">' : ''}</head><body><a class="skip" href="#main">Skip to content</a>${agent.mode === 'disclosure' ? '' : agentBlock}<header class="mast"><div class="mast-inner">${shell.home ? `<a class="${brandClass}" href="/">${brand}</a>` : `<span class="${brandClass}">${brand}</span>`}${publicationPicker(shell, esc)}${editionLabel && !shell.publicationChoices?.length && (shell.publicationAlternates?.length ?? 0) < 2 ? `<span class="edition">${esc(editionLabel)}</span>` : ''}${menu}${headerTools(shell, doc.variant, esc, readerConfig)}${agent.mode === 'disclosure' ? agentBlock : ''}</div></header>${sectionNavigation}${shortcuts}<div class="layout${layout === 'docs' ? '' : ` layout-${layout}`}${rail ? ' has-rail' : ''}${panel ? ' has-examples' : ''}${doc.endpoint ? ' api-reference' : ''}"><main id="main" class="content" tabindex="-1" data-document-type="${esc(doc.frontmatter.type)}"${readerConfig ? ` data-reader-page="${esc(readerFilterAttribute(doc.readerFilters ?? {}))}"` : ''}>${breadcrumbs}${hero ? '' : `<header class="page-head"><span class="eyebrow">${esc(typeLabel(doc.frontmatter.type))}</span>${doc.endpoint ? '' : badge(doc.frontmatter.subjectLifecycle)}<h1>${esc(doc.frontmatter.title)}${doc.endpoint ? badge(doc.frontmatter.subjectLifecycle) : ''}</h1>${pageHeader && !routeSummary ? `<p class="summary">${esc(pageHeader)}</p>` : ''}${pageDates}${endpoint}${audienceBadges}</header>`}${hero ? (pdfLink ? `<div class="page-formats">${pdfLink}</div>` : '') : `<div class="page-formats">${pdfAction?.placement === 'before' ? pdfLink : ''}<a class="formats" data-markdown-link href="${esc(markdownUrl)}">Read as Markdown</a><button type="button" class="formats" data-copy-markdown hidden>Copy as Markdown</button><span role="status" data-copy-markdown-status></span>${pdfAction?.placement === 'after' ? pdfLink : ''}</div>`}${toc ? '<div class="mobile-outline-slot"></div>' : ''}${jumps}${readerBanner}<article>${article}</article></main>${rail}${side}</div>${footer}${analyticsBootstrap}${readerBootstrap}${pdfAction?.mode === 'print' ? '<script type="module" src="/assets/print.js"></script>' : ''}<script type="module" src="/assets/copy-markdown.js"></script><script type="module" src="/assets/navigation.js"></script><script type="module" src="/assets/reader.js"></script><script type="module" src="/assets/tabs.js"></script>${shell.search ? '<script type="module" src="/assets/search.js"></script>' : ''}${article.includes('data-tooltip') ? '<script type="module" src="/assets/tooltips.js"></script>' : ''}${article.includes('data-component-module') ? '<script type="module" src="/assets/components.js"></script>' : ''}${article.includes('data-file-tree') ? '<script type="module" src="/assets/file-tree.js"></script>' : ''}${article.includes('data-image-expand') ? '<script type="module" src="/assets/image-viewer.js"></script>' : ''}${article.includes('data-table-filter') || article.includes('data-definition-filter') ? '<script type="module" src="/assets/table-filter.js"></script>' : ''}${article.includes('data-walkthrough') ? '<script type="module" src="/assets/walkthrough.js"></script>' : ''}${article.includes('data-cookbook-chooser') ? '<script type="module" src="/assets/cookbook-chooser.js"></script>' : ''}${article.includes('data-theme-preview') ? '<script type="module" src="/assets/theme-preview.js"></script>' : ''}${panel ? '<script type="module" src="/assets/example-panel.js"></script>' : ''}${panel.includes('data-code-samples') ? '<script type="module" src="/assets/code-samples.js"></script>' : ''}</body></html>`;
|
|
196
198
|
return basePath ? markup.replace(/((?:href|src)=")\/(assets\/|llms(?:\.min)?\.txt|apple-touch-icon\.png)/g, `$1${basePath}/$2`).replace('href="/"', `href="${basePath}/"`) : markup;
|
|
197
199
|
}
|
package/dist/palettes.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const paletteTokens: readonly ["text", "page", "surface", "link", "link-hover", "focus", "ink", "accent", "accent-contrast", "header-muted", "header-border", "border", "border-soft", "border-nested", "field-surface", "field-border", "field-accent", "presence-bg", "presence-text", "optional-bg", "optional-text", "muted", "nav-heading", "section-heading", "nav-text", "nav-hover", "nav-active", "nav-active-text", "deprecated-bg", "deprecated-text", "beta-bg", "beta-text", "development-bg", "development-text", "experimental-bg", "experimental-text", "emphasis", "summary", "code-bg", "code-text", "code-muted", "code-border", "code-block", "callout-line", "callout-bg", ...("callout-
|
|
1
|
+
export declare const paletteTokens: readonly ["text", "page", "surface", "link", "link-hover", "focus", "ink", "accent", "accent-contrast", "header-muted", "header-border", "border", "border-soft", "border-nested", "field-surface", "field-border", "field-accent", "presence-bg", "presence-text", "optional-bg", "optional-text", "muted", "nav-heading", "section-heading", "nav-text", "nav-hover", "nav-active", "nav-active-text", "deprecated-bg", "deprecated-text", "beta-bg", "beta-text", "development-bg", "development-text", "experimental-bg", "experimental-text", "emphasis", "summary", "code-bg", "code-text", "code-muted", "code-border", "code-block", "callout-line", "callout-bg", ...("callout-warning-line" | "callout-note-line" | "callout-tip-line" | "callout-important-line" | "callout-caution-line" | "callout-warning-bg" | "callout-note-bg" | "callout-tip-bg" | "callout-important-bg" | "callout-caution-bg" | "callout-warning-text" | "callout-note-text" | "callout-tip-text" | "callout-important-text" | "callout-caution-text")[], "strong-surface", "strong-text"];
|
|
2
2
|
export type Token = typeof paletteTokens[number];
|
|
3
3
|
export type Mode = 'light' | 'dark';
|
|
4
4
|
export type Palette = {
|
|
@@ -34,7 +34,7 @@ export function buildPublicationManifest({ configPublications, fictionalDocument
|
|
|
34
34
|
...(taxonomy ? { taxonomy } : {}),
|
|
35
35
|
dependencies,
|
|
36
36
|
...(tabs.length ? { navigationTabs: tabs } : {}),
|
|
37
|
-
documents: rendered.map(({ doc, markdown, sections }) => ({ id: doc.frontmatter.id, demo: fictionalDocuments.has(doc), type: doc.frontmatter.type, title: doc.frontmatter.title, summary: doc.frontmatter.summary, subjectLifecycle: doc.frontmatter.subjectLifecycle ?? null, ...(doc.change ? { change: doc.change } : {}), ...(doc.subjectDeprecation ? { subjectDeprecation: doc.subjectDeprecation } : {}), variant: doc.variant, url: doc.route, markdownUrl: doc.markdownRoute, ...tabFor(doc), indexable: indexable(doc), ...(updatedFor(doc) ? { updated: updatedFor(doc) } : {}), ...(doc.frontmatter.availability ? { availability: doc.frontmatter.availability } : {}), ...(doc.frontmatter.verified ? { verified: doc.frontmatter.verified } : {}), contentDigest: doc.contentDigest, breadcrumbs: navigationPath(resolvedNavigation.get(publicationKey(doc.variant)) ?? [], doc.route), ...(doc.frontmatter.product !== undefined ? { product: doc.frontmatter.product } : {}), ...(doc.frontmatter.area !== undefined ? { area: doc.frontmatter.area } : {}), ...(doc.frontmatter.subarea !== undefined ? { subarea: doc.frontmatter.subarea } : {}), ...(readerFilters ? { readerFilters: doc.readerFilters ?? {} } : {}), cardTargets: cardUses.get(doc)?.targets ?? [], cardQueries: cardUses.get(doc)?.queries ?? [], snippets: [...new Set(snippetUses.filter(use => use.documentId === doc.frontmatter.id).map(use => use.id))], apiEmbeds: apiEmbedUses.filter(use => use.documentKey === keyFor(doc.frontmatter.id, doc.variant)).map(({ sourceFile, documentKey, ...request }) => request), focusedContractUrl: doc.focusedContractUrl ?? null, focusedContractBytes: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.bytes : null, focusedContractDigest: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.digest : null, sections: (sections ?? []).map(({ content, ...record }) => record), ...markdownSize(markdown), digest: digest(markdown) })),
|
|
37
|
+
documents: rendered.map(({ doc, markdown, sections }) => ({ id: doc.frontmatter.id, demo: fictionalDocuments.has(doc), type: doc.frontmatter.type, title: doc.frontmatter.title, summary: doc.frontmatter.summary, subjectLifecycle: doc.frontmatter.subjectLifecycle ?? null, ...(doc.change ? { change: doc.change } : {}), ...(doc.subjectDeprecation ? { subjectDeprecation: doc.subjectDeprecation } : {}), variant: doc.variant, url: doc.route, markdownUrl: doc.markdownRoute, ...tabFor(doc), indexable: indexable(doc), ...(updatedFor(doc) ? { updated: updatedFor(doc) } : {}), ...(doc.frontmatter.availability ? { availability: doc.frontmatter.availability } : {}), ...(doc.frontmatter.verified ? { verified: doc.frontmatter.verified } : {}), contentDigest: doc.contentDigest, breadcrumbs: navigationPath(resolvedNavigation.get(publicationKey(doc.variant)) ?? [], doc.route), ...(doc.frontmatter.product !== undefined ? { product: doc.frontmatter.product } : {}), ...(doc.frontmatter.area !== undefined ? { area: doc.frontmatter.area } : {}), ...(doc.frontmatter.subarea !== undefined ? { subarea: doc.frontmatter.subarea } : {}), ...(readerFilters ? { readerFilters: doc.readerFilters ?? {} } : {}), cardTargets: cardUses.get(doc)?.targets ?? [], cardQueries: cardUses.get(doc)?.queries ?? [], snippets: [...new Set(snippetUses.filter(use => (use.documentKey ? use.documentKey === keyFor(doc.frontmatter.id, doc.variant) : use.documentId === doc.frontmatter.id)).map(use => use.id))], apiEmbeds: apiEmbedUses.filter(use => use.documentKey === keyFor(doc.frontmatter.id, doc.variant)).map(({ sourceFile, documentKey, ...request }) => request), focusedContractUrl: doc.focusedContractUrl ?? null, focusedContractBytes: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.bytes : null, focusedContractDigest: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.digest : null, sections: (sections ?? []).map(({ content, ...record }) => record), ...markdownSize(markdown), digest: digest(markdown) })),
|
|
38
38
|
operations,
|
|
39
39
|
relationships: publishedRelationships,
|
|
40
40
|
redirects,
|
|
@@ -8,7 +8,7 @@ import type { ReaderFiltersConfig } from './reader-filters.js';
|
|
|
8
8
|
import type { CodeHighlighter } from './highlight.js';
|
|
9
9
|
import type { MaterializedPage } from './page-materialization.js';
|
|
10
10
|
import type { ResolvedCompilerConfig, CompilerSiteConfig, CompilerPublicationsConfig } from './compiler-config.js';
|
|
11
|
-
export declare function renderPublicationPages({ rendered, docs, relationships, knownOperations, cardUses, publishedRelationships, cookbooks, documentRoutes, basePath, siteOrigin, colorMode, config, highlighter, editionLabel, customStyleFile, themePreset, palette, themeStyleFile, generatedPaletteCss, generatedBadgeCss, themeSwitcherData, generatedFontsCss, fontsPreload, shareFor, faviconRoute, logoRoute, modeToggle, header, footer, search, readerFilters, variants, externalDocuments, externalSiteLinks, navigationSpec, navigationEntries, navigationTagOrder, freshness }: {
|
|
11
|
+
export declare function renderPublicationPages({ rendered, docs, relationships, knownOperations, cardUses, publishedRelationships, cookbooks, documentRoutes, basePath, siteOrigin, colorMode, config, highlighter, editionLabel, customStyleFile, themePreset, palette, themeStyleFile, generatedPaletteCss, generatedBadgeCss, themeSwitcherData, generatedFontsCss, fontsPreload, customFontPreloads, shareFor, faviconRoute, logoRoute, modeToggle, header, footer, search, readerFilters, variants, externalDocuments, externalSiteLinks, navigationSpec, navigationEntries, navigationTagOrder, freshness }: {
|
|
12
12
|
freshness?: Freshness;
|
|
13
13
|
rendered: MaterializedPage[];
|
|
14
14
|
docs: Map<string, Document>;
|
|
@@ -41,6 +41,7 @@ export declare function renderPublicationPages({ rendered, docs, relationships,
|
|
|
41
41
|
themeSwitcherData?: string;
|
|
42
42
|
generatedFontsCss?: string;
|
|
43
43
|
fontsPreload?: string;
|
|
44
|
+
customFontPreloads?: import('./fonts.js').FontPreload[];
|
|
44
45
|
shareFor: (doc: Document) => {
|
|
45
46
|
route: string;
|
|
46
47
|
generated: boolean;
|
|
@@ -12,7 +12,7 @@ import { navigationPath, navigationTab, navigationTabRecord, resolveProjectNavig
|
|
|
12
12
|
import { outputUrl, publicTree, resolveOutputLinks } from './representation-tree.js';
|
|
13
13
|
import { presetCatalog } from './palettes.js';
|
|
14
14
|
const keyFor = documentKey;
|
|
15
|
-
export function renderPublicationPages({ rendered, docs, relationships, knownOperations, cardUses, publishedRelationships, cookbooks, documentRoutes, basePath, siteOrigin, colorMode, config, highlighter, editionLabel, customStyleFile, themePreset, palette, themeStyleFile, generatedPaletteCss, generatedBadgeCss, themeSwitcherData, generatedFontsCss, fontsPreload, shareFor, faviconRoute, logoRoute, modeToggle, header, footer, search, readerFilters, variants, externalDocuments, externalSiteLinks, navigationSpec, navigationEntries, navigationTagOrder, freshness }) {
|
|
15
|
+
export function renderPublicationPages({ rendered, docs, relationships, knownOperations, cardUses, publishedRelationships, cookbooks, documentRoutes, basePath, siteOrigin, colorMode, config, highlighter, editionLabel, customStyleFile, themePreset, palette, themeStyleFile, generatedPaletteCss, generatedBadgeCss, themeSwitcherData, generatedFontsCss, fontsPreload, customFontPreloads, shareFor, faviconRoute, logoRoute, modeToggle, header, footer, search, readerFilters, variants, externalDocuments, externalSiteLinks, navigationSpec, navigationEntries, navigationTagOrder, freshness }) {
|
|
16
16
|
const resolvedNavigation = new Map();
|
|
17
17
|
const selector = config.site.publicationSelector;
|
|
18
18
|
if (selector !== undefined && (!isConfigMapping(selector) || Object.keys(selector).some(key => key !== 'showLanguage') || (selector.showLanguage !== undefined && typeof selector.showLanguage !== 'boolean')))
|
|
@@ -102,7 +102,7 @@ export function renderPublicationPages({ rendered, docs, relationships, knownOpe
|
|
|
102
102
|
const group = variant.product === undefined ? config.site.title : config.publications.products?.[variant.product]?.label ?? variant.product;
|
|
103
103
|
return [{ group, label: `${group} · ${variant.channel} · ${variant.version}${showLanguage ? ` · ${variant.language}` : ''}`, url: target.route, current: samePublication(page.doc.variant, variant) }];
|
|
104
104
|
}) : [];
|
|
105
|
-
page.html = buildHtmlPage(page.doc, page.htmlTree, page.doc.markdownRoute, config.site.title, navigation, page.pageExamples, page.pageShapes, highlighter, editionLabel(page.doc.variant), !!customStyleFile, { preset: themePreset, palette: palette.name, themeCss: !!themeStyleFile, paletteCss: !!generatedPaletteCss, badgesCss: !!generatedBadgeCss, themeSwitcher: themeSwitcherData, fontsCss: !!generatedFontsCss, preloadFont: fontsPreload, masthead: presetCatalog.find(preset => preset.name === themePreset)?.masthead, share: shareFor(page.doc), favicon: faviconRoute, logo: logoRoute, touchIcon: !faviconRoute.endsWith('.png'), origin: siteOrigin, indexing: config.site.indexing !== false, home: hasHome, mode: colorMode, toggle: modeToggle, header, footer, search: search.provider !== 'none', publicationChoices, publicationAlternates, breadcrumbs }, page.pageCurl, page.pageSamples, { ...config, readerFilters });
|
|
105
|
+
page.html = buildHtmlPage(page.doc, page.htmlTree, page.doc.markdownRoute, config.site.title, navigation, page.pageExamples, page.pageShapes, highlighter, editionLabel(page.doc.variant), !!customStyleFile, { preset: themePreset, palette: palette.name, themeCss: !!themeStyleFile, paletteCss: !!generatedPaletteCss, badgesCss: !!generatedBadgeCss, themeSwitcher: themeSwitcherData, fontsCss: !!generatedFontsCss, preloadFont: fontsPreload, preloadFonts: customFontPreloads, masthead: presetCatalog.find(preset => preset.name === themePreset)?.masthead, share: shareFor(page.doc), favicon: faviconRoute, logo: logoRoute, touchIcon: !faviconRoute.endsWith('.png'), origin: siteOrigin, indexing: config.site.indexing !== false, home: hasHome, mode: colorMode, toggle: modeToggle, header, footer, search: search.provider !== 'none', publicationChoices, publicationAlternates, breadcrumbs }, page.pageCurl, page.pageSamples, { ...config, readerFilters });
|
|
106
106
|
}
|
|
107
107
|
return resolvedNavigation;
|
|
108
108
|
}
|
|
@@ -20,8 +20,14 @@ export function publicTree(tree, representation, documentRoutes, mode = 'light',
|
|
|
20
20
|
element('div', { 'data-component-content': '' }, children)
|
|
21
21
|
])];
|
|
22
22
|
}
|
|
23
|
-
if (node.type === 'docRepresentation')
|
|
24
|
-
|
|
23
|
+
if (node.type === 'docRepresentation') {
|
|
24
|
+
if (node.representation !== representation)
|
|
25
|
+
return [];
|
|
26
|
+
const children = node.children.flatMap(walk);
|
|
27
|
+
// Mark HTML-only content so agent-parity checks can distinguish intentional
|
|
28
|
+
// format-specific prose from accidental content loss in the Markdown twin.
|
|
29
|
+
return representation === 'html' ? [element('div', { 'data-markdown-ignore': '' }, children)] : children;
|
|
30
|
+
}
|
|
25
31
|
if (node.type === 'docCookbookChooser') {
|
|
26
32
|
const prompt = node.mode === 'single' ? 'Choose one recipe.' : 'Choose one or more recipes.';
|
|
27
33
|
const details = (option) => [option.when ? `Use when: ${option.when}` : option.summary, option.needs ? `You need: ${option.needs}` : '', option.outcome ? `You will have: ${option.outcome}` : ''].filter(Boolean);
|
|
@@ -66,6 +72,10 @@ export function publicTree(tree, representation, documentRoutes, mode = 'light',
|
|
|
66
72
|
if (node.type === 'docReaderFilter') {
|
|
67
73
|
return representation === 'markdown' ? [] : [element('div', { className: ['reader-filter-slot'], 'data-reader-filter': JSON.stringify(node.control) }, [])];
|
|
68
74
|
}
|
|
75
|
+
if (node.type === 'table' && node.data?.referenceTableLabel && representation === 'html') {
|
|
76
|
+
const table = { ...node, children: node.children.flatMap(walk) };
|
|
77
|
+
return [element('div', { className: ['code-reference-table-scroll'], role: 'region', 'aria-label': node.data.referenceTableLabel, tabIndex: 0 }, [table])];
|
|
78
|
+
}
|
|
69
79
|
if (node.type === 'docTable') {
|
|
70
80
|
const table = node.children.flatMap(walk);
|
|
71
81
|
if (representation === 'markdown')
|
package/dist/search-query.js
CHANGED
|
@@ -64,7 +64,7 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
64
64
|
return [];
|
|
65
65
|
const termScore = (term) => weight(title, term, title.startsWith(term.term) ? 12 : 8, true) || weight(summary, term, 4) || (headings.some(heading => match(heading, term)) ? 3 : 0) || weight(body, term, 1);
|
|
66
66
|
let score = terms.reduce((total, term) => total + termScore(term), 0);
|
|
67
|
-
|
|
67
|
+
let contentScore = terms.filter(term => !fallbackStopWords.has(term.term)).reduce((total, term) => total + termScore(term), 0);
|
|
68
68
|
const prominentMatches = terms.filter(term => !fallbackStopWords.has(term.term) && (matchTitle(title, term) || match(summary, term) || headings.some(heading => match(heading, term)))).length;
|
|
69
69
|
const section = terms.every(term => matchTitle(title, term)) ? undefined : doc.headings.find((heading, at) => terms.every(term => match(headings[at], term)));
|
|
70
70
|
// Use only query terms with meaning, and require a unique matching section.
|
|
@@ -77,8 +77,10 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
77
77
|
// older indexes and unreviewed sections conservatively retain the full page.
|
|
78
78
|
const selected = candidates.length === 1 && candidates[0].standalone === true ? candidates[0] : undefined;
|
|
79
79
|
// A complete multiword section-title match outranks incidental page-title words.
|
|
80
|
-
if (meaningful.length >= 2 && candidates.some(candidate => meaningful.every(term => match(candidate.title.toLocaleLowerCase(), term))))
|
|
80
|
+
if (meaningful.length >= 2 && candidates.some(candidate => meaningful.every(term => match(candidate.title.toLocaleLowerCase(), term)))) {
|
|
81
81
|
score += 20;
|
|
82
|
+
contentScore += 20;
|
|
83
|
+
}
|
|
82
84
|
const { product, channel, version, language } = parsePublicationKey(doc.variant);
|
|
83
85
|
const tokens = selected?.markdownTokens ?? doc.markdownTokens;
|
|
84
86
|
const read = { tool: selected ? 'get_section' : 'get_page', arguments: {
|
|
@@ -87,15 +89,20 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
87
89
|
} };
|
|
88
90
|
return [{ score, contentScore, prominentMatches, matched: matched.length, partialMatched: matched.filter(term => !fallbackStopWords.has(term.term)).length, id: doc.id, type: doc.type, title: doc.title, summary: doc.summary, url: section ? `${doc.url}#${section.id}` : doc.url, markdownUrl: selected?.markdownUrl ?? doc.markdownUrl, pageMarkdownUrl: doc.markdownUrl, read, ...(tokens !== undefined ? { markdownTokens: tokens, markdownBytes: selected?.markdownBytes ?? doc.markdownBytes, markdownTokenEncoding: doc.markdownTokenEncoding } : {}), ...(selected || section ? { section: selected?.title ?? section?.title } : {}), snippet: excerpt(doc.text, terms.flatMap(unit => [unit.term, ...unit.alternatives])) }];
|
|
89
91
|
});
|
|
90
|
-
const
|
|
92
|
+
const contentTerms = terms.filter(term => !fallbackStopWords.has(term.term)).length;
|
|
93
|
+
// Filler words shape the sentence, not the subject. A page that covers every
|
|
94
|
+
// content term is complete even when it omits "how", "do", or "the"; otherwise
|
|
95
|
+
// a page that happens to repeat filler words can hide the focused result.
|
|
96
|
+
const complete = contentTerms === 0
|
|
97
|
+
? hits.filter(hit => hit.matched === terms.length)
|
|
98
|
+
: hits.filter(hit => hit.partialMatched === contentTerms);
|
|
91
99
|
// Relax the all-words gate only when complete matches are entirely incidental
|
|
92
100
|
// body matches. A near-complete result must cover all but one content term and
|
|
93
101
|
// have a stronger non-filler field score. Title/summary/heading matches on any
|
|
94
102
|
// complete result preserve the original preference; filler cannot earn promotion.
|
|
95
|
-
const contentTerms = terms.filter(term => !fallbackStopWords.has(term.term)).length;
|
|
96
103
|
const bestCompleteContent = Math.max(...complete.map(hit => hit.contentScore));
|
|
97
104
|
const stronger = complete.length && contentTerms >= 3 && complete.every(hit => hit.prominentMatches === 0)
|
|
98
|
-
? hits.filter(hit => hit.
|
|
105
|
+
? hits.filter(hit => hit.partialMatched < contentTerms && hit.partialMatched >= contentTerms - 1
|
|
99
106
|
&& hit.prominentMatches > 0 && hit.contentScore > bestCompleteContent) : [];
|
|
100
107
|
const ranked = complete.length ? [...complete, ...stronger] : hits.filter(hit => hit.partialMatched > 0);
|
|
101
108
|
// In partial fallback, one extra incidental word must not outweigh a focused
|
|
@@ -114,7 +121,7 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
114
121
|
if (aNear && a.contentScore !== b.contentScore)
|
|
115
122
|
return b.contentScore - a.contentScore;
|
|
116
123
|
}
|
|
117
|
-
return (complete.length ? b.
|
|
124
|
+
return (complete.length ? b.contentScore - a.contentScore : b.partialMatched - a.partialMatched) || b.score - a.score || a.title.localeCompare(b.title) || a.id.localeCompare(b.id);
|
|
118
125
|
});
|
|
119
126
|
const publication = parsePublicationKey(variants[0]);
|
|
120
127
|
return { status: 'ok', query: query.trim(), publication, total: ranked.length, matchMode: stronger.length ? 'mixed' : complete.length ? 'all' : 'partial', results: ranked.slice(0, limit).map(({ matched, partialMatched, contentScore, prominentMatches, ...result }) => result) };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ReaderFiltersConfig, type ReaderSelection } from './reader-filters.js';
|
|
2
|
+
import type { CompilerPublicationsConfig } from './compiler-config.js';
|
|
3
|
+
import type { Document } from './content-source.js';
|
|
4
|
+
export type SectionSelection = {
|
|
5
|
+
facets?: ReaderFiltersConfig;
|
|
6
|
+
selection?: ReaderSelection;
|
|
7
|
+
decisions: Map<string, Record<string, unknown>>;
|
|
8
|
+
warnings: Map<string, {
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
}>;
|
|
12
|
+
hasConditions: boolean;
|
|
13
|
+
publications?: CompilerPublicationsConfig;
|
|
14
|
+
};
|
|
15
|
+
export declare function createSectionSelection(facets?: ReaderFiltersConfig, selection?: ReaderSelection, publications?: CompilerPublicationsConfig): SectionSelection;
|
|
16
|
+
/** Share publication validation with pruning so receipts reflect every build-time ancestor. */
|
|
17
|
+
export declare function evaluatePublicationGuard(node: any, doc: Document, file: string, publications?: CompilerPublicationsConfig): boolean | undefined;
|
|
18
|
+
export declare function pruneSelectedTree(tree: any, doc: Document, file?: string, record?: boolean): any;
|
|
19
|
+
export declare function warnReaderSection(doc: Document, file: string, line: number, requirements: ReaderSelection): void;
|
|
20
|
+
export declare function sectionSelectionReport(context: SectionSelection): {
|
|
21
|
+
selection: ReaderSelection | null;
|
|
22
|
+
decisions: Record<string, unknown>[];
|
|
23
|
+
warnings: {
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
28
|
+
/** Keep receipts private, atomic, and keyed by artifact so nested exports can't replace a site's record. */
|
|
29
|
+
export declare function writeSectionSelectionReport(base: string, context: SectionSelection, artifact: Record<string, unknown>): Promise<void>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, writeFile, rename, rm } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { pruneConditionalTree } from './conditional-tree.js';
|
|
5
|
+
import { evaluateFeatureGuard } from './deployment-profile.js';
|
|
6
|
+
import { matchesSectionContentFilter } from './content-filter.js';
|
|
7
|
+
import { validateReaderSelection } from './reader-filters.js';
|
|
8
|
+
import { documentKey } from './publication-identity.js';
|
|
9
|
+
export function createSectionSelection(facets, selection, publications) {
|
|
10
|
+
return { facets, selection, publications, decisions: new Map(), warnings: new Map(), hasConditions: false };
|
|
11
|
+
}
|
|
12
|
+
/** Share publication validation with pruning so receipts reflect every build-time ancestor. */
|
|
13
|
+
export function evaluatePublicationGuard(node, doc, file, publications) {
|
|
14
|
+
if (node.name !== 'ForPublication')
|
|
15
|
+
return;
|
|
16
|
+
const attributes = node.attributes ?? [];
|
|
17
|
+
const allowed = ['product', 'channel', 'version', 'language'];
|
|
18
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || typeof item.value !== 'string' || !allowed.includes(item.name) || !item.value.trim()) || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
19
|
+
throw new Error(`${file}: <ForPublication> needs block content and distinct literal product, channel, version, or language attributes`);
|
|
20
|
+
const product = attributes.find((item) => item.name === 'product')?.value ?? doc.variant.product;
|
|
21
|
+
for (const item of attributes) {
|
|
22
|
+
const catalog = item.name === 'product' ? publications?.products : item.name === 'channel' ? publications?.channels : item.name === 'version' ? (product ? publications?.products?.[product]?.versions : publications?.versions) : undefined;
|
|
23
|
+
if (publications && item.name !== 'language' && (!catalog || !Object.hasOwn(catalog, item.value)))
|
|
24
|
+
throw new Error(`${file}: <ForPublication> names unknown ${item.name} ${item.value}`);
|
|
25
|
+
}
|
|
26
|
+
return !attributes.some((item) => doc.variant[item.name] !== item.value);
|
|
27
|
+
}
|
|
28
|
+
export function pruneSelectedTree(tree, doc, file = doc.file, record = true) {
|
|
29
|
+
const context = doc.sectionSelection;
|
|
30
|
+
return pruneConditionalTree(tree, (node, ancestorIncluded) => {
|
|
31
|
+
if (node.name === 'ForPublication')
|
|
32
|
+
return evaluatePublicationGuard(node, doc, file, context?.publications);
|
|
33
|
+
if (node.name === 'ForFeature')
|
|
34
|
+
return evaluateFeatureGuard(node, doc.featureContext, file, ancestorIncluded, record);
|
|
35
|
+
if (node.name !== 'ForFacet')
|
|
36
|
+
return;
|
|
37
|
+
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFacet>`;
|
|
38
|
+
const attributes = node.attributes ?? [];
|
|
39
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || typeof item.value !== 'string' || !item.value.trim()) || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
40
|
+
throw new Error(`${label} needs block content and distinct nonempty literal facet attributes`);
|
|
41
|
+
if (!context?.facets)
|
|
42
|
+
throw new Error(`${label} needs configured readerFilters.facets`);
|
|
43
|
+
const requirements = validateReaderSelection(Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/)])), context.facets, label);
|
|
44
|
+
context.hasConditions = true;
|
|
45
|
+
const match = matchesSectionContentFilter(requirements, context.selection);
|
|
46
|
+
if (record) {
|
|
47
|
+
const line = node.position?.start?.line ?? 1;
|
|
48
|
+
const key = JSON.stringify([documentKey(doc.frontmatter.id, doc.variant), file, line, requirements, ancestorIncluded]);
|
|
49
|
+
context.decisions.set(key, { documentId: doc.frontmatter.id, publication: doc.variant, source: file, line, requirements, localMatch: match, included: ancestorIncluded && match, reason: !ancestorIncluded ? 'ancestor-excluded' : match ? 'matched' : 'facet-mismatch' });
|
|
50
|
+
}
|
|
51
|
+
return match;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function warnReaderSection(doc, file, line, requirements) {
|
|
55
|
+
const context = doc.sectionSelection;
|
|
56
|
+
if (!context?.selection)
|
|
57
|
+
return;
|
|
58
|
+
const overlap = Object.keys(requirements).filter(facet => context.selection?.[facet]);
|
|
59
|
+
if (!overlap.length)
|
|
60
|
+
return;
|
|
61
|
+
const key = JSON.stringify([file, line, overlap]);
|
|
62
|
+
if (context.warnings.has(key))
|
|
63
|
+
return;
|
|
64
|
+
const message = `${file}:${line}: <ReaderSection> uses build-selected facet(s) ${overlap.join(', ')} but only changes reader visibility; its content remains in the output. Use <ForFacet> to omit unmatched content during this build.`;
|
|
65
|
+
context.warnings.set(key, { code: 'reader-section-build-facet', message });
|
|
66
|
+
process.stderr.write(`warning [reader-section-build-facet] ${message}\n`);
|
|
67
|
+
}
|
|
68
|
+
export function sectionSelectionReport(context) {
|
|
69
|
+
return { selection: context.selection ?? null, decisions: [...context.decisions.values()], warnings: [...context.warnings.values()] };
|
|
70
|
+
}
|
|
71
|
+
/** Keep receipts private, atomic, and keyed by artifact so nested exports can't replace a site's record. */
|
|
72
|
+
export async function writeSectionSelectionReport(base, context, artifact) {
|
|
73
|
+
const folder = path.join(base, '.shoalrun');
|
|
74
|
+
await mkdir(folder, { recursive: true });
|
|
75
|
+
const file = path.join(folder, 'content-selection.json');
|
|
76
|
+
const key = createHash('sha256').update(JSON.stringify(artifact.target)).digest('hex');
|
|
77
|
+
const receipt = { schemaVersion: 1, ...artifact, ...sectionSelectionReport(context) };
|
|
78
|
+
const receipts = path.join(folder, 'content-selection');
|
|
79
|
+
await mkdir(receipts, { recursive: true });
|
|
80
|
+
const atomic = async (destination, value) => {
|
|
81
|
+
const temporary = path.join(folder, `.content-selection-${randomUUID()}.json`);
|
|
82
|
+
try {
|
|
83
|
+
await writeFile(temporary, JSON.stringify(value, null, 2) + '\n');
|
|
84
|
+
await rename(temporary, destination);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
await rm(temporary, { force: true });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
await atomic(path.join(receipts, key + '.json'), receipt);
|
|
91
|
+
await atomic(file, { ...receipt, receipt: `content-selection/${key}.json` });
|
|
92
|
+
}
|
package/dist/snippets.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type SnippetUse = {
|
|
|
13
13
|
id: string;
|
|
14
14
|
file: string;
|
|
15
15
|
documentId: string;
|
|
16
|
+
documentKey?: string;
|
|
16
17
|
};
|
|
17
18
|
export declare function validateSnippetConfig(id: string, definition: any): Record<string, SnippetVariable>;
|
|
18
19
|
export declare function snippetAttribute(attribute: any, label: string): unknown;
|