Skip to content

Linter: implement the rule to update definitions to $defs #1911

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Karan-Palan
Copy link
Contributor

No description provided.

Signed-off-by: karan-palan <karanpalan007@gmail.com>
@Karan-Palan
Copy link
Contributor Author

@jviotti , for this rule I have used the rereference method. Ptal if you have any comments

@Karan-Palan Karan-Palan changed the title Linter: implement the rule to update definitions to Linter: implement the rule to update definitions to $defs Aug 4, 2025
@Karan-Palan Karan-Palan marked this pull request as draft August 4, 2025 11:24
DefinitionsToDefs()
: SchemaTransformRule{
"definitions_to_defs",
"`definitions` is superseded by `$defs` starting in draft-2019-09. "
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"`definitions` is superseded by `$defs` starting in draft-2019-09. "
"`definitions` was superseded by `$defs` in 2019-09 and later versions. "

return contains_any(vocabularies,
{"https://json-schema.org/draft/2020-12/vocab/core",
"https://json-schema.org/draft/2019-09/vocab/core"}) &&
schema.is_object() && schema.defines("definitions") &&
Copy link
Member

Choose a reason for hiding this comment

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

Not for this rule, but another rule that just occurred to me is that you can detect schemas in definitions or $defs that the rest of the schema is never referencing. It would be an unused schema definition. That also means we can check for empty definitions or $defs and remove those

"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/uuid"
Copy link
Member

Choose a reason for hiding this comment

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

Can you try a more complicated pointer? Like a schema that has a nested schema that defines $defs and then it is referenced from the top as #/foo/bar/$defs/baz or something?

Copy link
Member

@jviotti jviotti Aug 4, 2025

Choose a reason for hiding this comment

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

Also with a nested schema resource maybe. Like

{
    ...
    "$ref": "nested#/definitions/foo",
    ...
    "$defs": {
      "nested": {
        "$id": "nested",
        ...
        "definitions": {
          "foo": {
            "type": "string"
          }
        }
      }
    }  
}


[[nodiscard]] auto rereference(const std::string &reference, const Pointer &,
const Pointer &, const Pointer &) const
-> Pointer override {
Copy link
Member

Choose a reason for hiding this comment

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

I think your implementation is too complicated. I looked around, and I remembered I did something like this (definitions to $defs) internally in the test suite of the transformer. You can steal the logic from there:

class ExampleRuleDefinitionsToDefsWithRereference final
: public sourcemeta::core::SchemaTransformRule {
public:
ExampleRuleDefinitionsToDefsWithRereference()
: sourcemeta::core::SchemaTransformRule(
"example_rule_definitions_to_defs_with_rereference",
"Rename `definitions` to `$defs`") {};
[[nodiscard]] auto condition(const sourcemeta::core::JSON &schema,
const sourcemeta::core::JSON &,
const sourcemeta::core::Vocabularies &,
const sourcemeta::core::SchemaFrame &,
const sourcemeta::core::SchemaFrame::Location &,
const sourcemeta::core::SchemaWalker &,
const sourcemeta::core::SchemaResolver &) const
-> sourcemeta::core::SchemaTransformRule::Result override {
return schema.defines("definitions") && !schema.defines("$defs");
}
auto transform(sourcemeta::core::JSON &schema) const -> void override {
schema.rename("definitions", "$defs");
}
[[nodiscard]] auto rereference(const std::string &,
const sourcemeta::core::Pointer &,
const sourcemeta::core::Pointer &target,
const sourcemeta::core::Pointer &current) const
-> sourcemeta::core::Pointer override {
return target.rebase(current.concat({"definitions"}),
current.concat({"$defs"}));
}
};

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