Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed extra:analytics schema for custom providers #6361

Merged
merged 2 commits into from
Nov 19, 2023

Conversation

sisp
Copy link
Contributor

@sisp sisp commented Nov 18, 2023

I've fixed the JSON schema for specifying custom providers which don't use the property property like Google Analytics and/or have additional properties.

This is a set of test cases that show the current validation results in VS Code:

site_name: Docs with analytics

theme:
  name: material

extra:
  # expected: ✅ / actual ✅
  analytics:
    provider: google
    property: G-XXXXXXXXXX

  # expected: ✅ / actual ✅
  analytics:
    provider: google
    property: G-XXXXXXXXXX
    feedback:
      title: Was this page helpful?

  # expected: ❌ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: google
    property2: G-XXXXXXXXXX # 🚩 Property property2 is not allowed. yaml-schema: Analytics provider

  # expected: ❌ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: google
    property2: G-XXXXXXXXXX # 🚩 Property property2 is not allowed. yaml-schema: Analytics provider
    feedback:
      title: Was this page helpful?

  # expected: ✅ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: custom

  # expected: ✅ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: custom
    feedback:
      title: Was this page helpful?

  # expected: ✅ / actual: ✅
  analytics:
    provider: custom
    property: custom-property

  # expected: ✅ / actual: ✅
  analytics:
    provider: custom
    property: custom-property
    feedback:
      title: Was this page helpful?

  # expected: ✅ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: plausible
    domain: example.com # 🚩 Property domain is not allowed. yaml-schema: Analytics provider

  # expected: ✅ / actual: ❌
  analytics: # 🚩 Missing property "property". yaml-schema: Analytics provider
    provider: plausible
    domain: example.com # 🚩 Property domain is not allowed. yaml-schema: Analytics provider
    feedback:
      title: Was this page helpful?

With the changed schema in this PR, all test cases yield the expected results.

Before, the schema didn't couple provider: google with making property required, and as a side-effect, property was always defined using a schema specific to Google Analytics. Further, additionalProperties: false prevented any other custom properties that may be needed for some analytics solution.

Now, provider: google, property with the Google-specific schema, declaring both as required properties, and disallowing additional properties are all coupled. For any other provider: <string>, additional properties are allowed without defined schemas. The probably obvious approaches to express this with JSON Schema are to use

  • oneOf, which doesn't work because the schema for provider: <string> is a superset of provider: google, so more than one schema matches, or
  • anyOf as an attempt at fixing the problem with oneOf, but then the provider: <string> schema matches always and the additional constraints from the provider: google schema don't apply.

The solution I've implemented uses a combination of allOf and if-then (without else), such that any valid config of a defined provider (only Google Analytics at the moment) matches both the corresponding schema and the provider: <string> schema, whereas a config of a custom provider matches only the provider: <string> schema. Note that it's important to declare also the feedback property in each allOf schema of a specific provider because additionalProperties: false limits the set of valid properties only to those defined in the same schema and doesn't recognize the feedback property schema in the parent schema of allOf. But for clarity, I've also declared the feedback property in the provider: <string> schema, although it isn't necessary as the missing additionalProperties implies true, so feedback would be allowed anyway.

I hope the rationale of the solution, combined with the PR diff, is somewhat clear, although I'm not sure I was able to explain it so well.

WDYT, @squidfunk?

Copy link
Owner

@squidfunk squidfunk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, only some minor changes. I think it is a good idea to make this more flexible!

docs/schema/extra.json Outdated Show resolved Hide resolved
docs/schema/extra.json Outdated Show resolved Hide resolved
@sisp sisp force-pushed the fix/analytics-schema branch from b9e6694 to 73ec703 Compare November 19, 2023 09:07
@sisp
Copy link
Contributor Author

sisp commented Nov 19, 2023

Thanks for the feedback! I've updated the PR as you requested.

@sisp sisp force-pushed the fix/analytics-schema branch from 73ec703 to f528598 Compare November 19, 2023 09:11
@sisp
Copy link
Contributor Author

sisp commented Nov 19, 2023

Just made the second commit message past tense since that's how you do it. 😉

@squidfunk
Copy link
Owner

Just made the second commit message past tense since that's how you do it. 😉

Thanks for sticking closely to our conventions! In fact, I'm using present tense on new projects, but I keep them past for consistency here, since that's how we roll since many years.

@squidfunk squidfunk merged commit 1cc4aca into squidfunk:master Nov 19, 2023
@sisp sisp deleted the fix/analytics-schema branch November 19, 2023 09:23
@sisp sisp mentioned this pull request Nov 21, 2023
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants