Skip to content

Extract subschema (to definitions) #132

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

Open
jdesrosiers opened this issue Feb 6, 2025 · 8 comments
Open

Extract subschema (to definitions) #132

jdesrosiers opened this issue Feb 6, 2025 · 8 comments
Assignees

Comments

@jdesrosiers
Copy link
Collaborator

SchemaNodes have an isSchema property that can be used to know if something is a subschema. SchemaNode also has a keywordUri property. The keyword URI can be used to find the SchemaNode for the definitions object. The keyword URI for definitions is https://json-schema.org/keyword/definitions regardless of the draft. So, don't look for a property called definitions/$defs in the schema, look for the node with with the https://json-schema.org/keyword/definitions keyword URI.

Example:

Before refactoring:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",

  "type": "object",
  "properties": {
    "foo": { "$ref": "#/$defs/number" },
    "bar": { "type": "boolean" }
  },

  "$defs": {
    "number": { "type": "number" }
  }
}

There should be a code action on the subschema at /properties/bar to extract the subschema to $defs and replace it with a reference ($ref) to the subschema in $defs.

After refactoring:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",

  "type": "object",
  "properties": {
    "foo": { "$ref": "#/$defs/number" }
    "bar": { "$ref": "#/$defs/boolean" },
  },

  "$defs": {
    "number": { "type": "number" },
    "boolean": { "type": "boolen" }
  }
}
@jdesrosiers
Copy link
Collaborator Author

@arpitkuriyal, Github won't let me assign you until you make a comment on the issue. So, please say hi or something and I'll assign you this issue.

@arpitkuriyal
Copy link

hello @jdesrosiers, looking forward to working on it.

@arpitkuriyal
Copy link

Hello @jdesrosiers, could you suggest any prerequisites I should go through before working on this to better understand the task? I am currently reading the VS Code Language Server Extension guide for reference.

@jdesrosiers
Copy link
Collaborator Author

There's not much. I've found the resources on writing language servers to be quite bad.

In general, you might find this youtube video helpful to get a feel for how language servers work.

More specifically, The documentation for Code Actions should be helpful. I'm pretty sure Code Actions are what we'll use for this.

The implementation will be in a new file in the features folder.

@arpitkuriyal
Copy link

arpitkuriyal commented Feb 7, 2025 via email

@arpitkuriyal
Copy link

Hello @jdesrosiers,
I’m stuck on one part of my implementation. As you mentioned, I’m trying to find the node with the https://json-schema.org/keyword/definitions keywordUri, but I’m running into an issue.

When I attempt this:
Image
It returns defsNode = undefined. Since the node only returns the one where the cursor is pointing, I tried using node.root so i can get the root node , but it’s not working. I also tried node.parent and node.parent.parent, but still no luck.
Until now, I’ve set up the boilerplate structure for the CodeAction . Video below:

Screen.Recording.2025-02-19.at.1.19.06.AM.mov

@jdesrosiers
Copy link
Collaborator Author

Wow, looks like great progress! If I understand your question correctly, I think you're looking for the allNodes function available from model/schema-node.js. It will iterate over all the nodes in the tree automatically following array items and object properties. If you pass the root to allNodes, you should be able to use that to find the node you're looking for anywhere in the schema resource.

@arpitkuriyal
Copy link

Thanks! I didn’t know about allNodes function , but that sounds perfect.

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

No branches or pull requests

2 participants