Skip to content

Commit 77808f4

Browse files
committed
correction in the extractSubschema.js
1 parent 2e9930e commit 77808f4

File tree

1 file changed

+42
-24
lines changed

1 file changed

+42
-24
lines changed

language-server/src/features/codeAction/extractSubschema.js

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import {
44
} from "vscode-languageserver";
55
import * as SchemaDocument from "../../model/schema-document.js";
66
import * as SchemaNode from "../../model/schema-node.js";
7-
8-
7+
import * as jsoncParser from "jsonc-parser";
98
/**
10-
* @import { Schemas } from "../../services/schemas.js";
11-
* @import { Server } from "../../services/server.js";
12-
* @import {CodeAction} from "vscode-languageserver";
9+
* @import { Server } from "../../services/server.js"
10+
* @import { Schemas } from "../../services/schemas.js"
11+
* @import { CodeAction } from "vscode-languageserver";
1312
*/
1413
export class ExtractSubSchemaToDefs {
1514
/**
@@ -25,7 +24,18 @@ export class ExtractSubSchemaToDefs {
2524
}
2625
}));
2726

28-
server.onCodeAction(async ({textDocument, range}) => {
27+
// Helper function to format new def using jsonc-parser
28+
const formatNewDef = (/** @type {string} */ newDefText) => {
29+
try {
30+
/** @type {unknown} */
31+
const parsedDef = jsoncParser.parse(newDefText);
32+
return JSON.stringify(parsedDef, null, 2).replace(/\n/g, "\n ");
33+
} catch {
34+
return newDefText;
35+
}
36+
};
37+
38+
server.onCodeAction(async ({ textDocument, range }) => {
2939
const uri = textDocument.uri;
3040
let schemaDocument = await schemas.getOpen(uri);
3141
if (!schemaDocument) {
@@ -37,22 +47,30 @@ export class ExtractSubSchemaToDefs {
3747
if (!node?.isSchema) {
3848
return [];
3949
}
40-
41-
// Finding the $defs node
42-
let findDef;
50+
let definitionsNode;
4351
for (const schemaNode of SchemaNode.allNodes(node.root)) {
4452
if (schemaNode.keywordUri === "https://json-schema.org/keyword/definitions") {
45-
findDef = schemaNode;
53+
definitionsNode = schemaNode;
4654
break;
4755
}
4856
}
49-
50-
// Getting the name from pointer
51-
let newDefName = "unknown";
52-
if (node.pointer) {
53-
const parts = node.pointer.split("/");
54-
newDefName = parts[parts.length - 1] || "unknown";
57+
let highestDefNumber = 0;
58+
if (definitionsNode) {
59+
const defsContent = schemaDocument.textDocument.getText().slice(
60+
definitionsNode.offset,
61+
definitionsNode.offset + definitionsNode.textLength
62+
);
63+
const defMatches = [...defsContent.matchAll(/"def(\d+)":/g)];
64+
defMatches.forEach((match) =>
65+
highestDefNumber = Math.max(highestDefNumber, parseInt(match[1], 10))
66+
);
5567
}
68+
let newDefName = `def${highestDefNumber + 1}`;
69+
const extractedDef = schemaDocument.textDocument.getText(range);
70+
const newFormattedDef = formatNewDef(extractedDef);
71+
let defName = (node.root.dialectUri === "https://json-schema.org/draft/2020-12/schema"
72+
|| node.root.dialectUri === "https://json-schema.org/draft/2019-09/schema")
73+
? "$defs" : "definitions";
5674

5775
/** @type {CodeAction} */
5876
const codeAction = {
@@ -63,22 +81,22 @@ export class ExtractSubSchemaToDefs {
6381
TextDocumentEdit.create({ uri: textDocument.uri, version: null }, [
6482
{
6583
range: range,
66-
newText: `{ "$ref": "#/$defs/${newDefName}" }`
84+
newText: `{ "$ref": "#/${defName}/${newDefName}" }`
6785
},
68-
findDef
86+
definitionsNode
6987
? {
7088
range: {
71-
start: schemaDocument.textDocument.positionAt(findDef.offset + 1),
72-
end: schemaDocument.textDocument.positionAt(findDef.offset + 1)
89+
start: schemaDocument.textDocument.positionAt(definitionsNode.offset + 1),
90+
end: schemaDocument.textDocument.positionAt(definitionsNode.offset + 1)
7391
},
74-
newText: `\n "${newDefName}":${schemaDocument.textDocument.getText(range)},`
92+
newText: `\n "${newDefName}": ${newFormattedDef},`
7593
}
7694
: {
7795
range: {
78-
start: { line: 1, character: 0 },
79-
end: { line: 1, character: 0 }
96+
start: schemaDocument.textDocument.positionAt(node.root.offset + node.root.textLength - 2),
97+
end: schemaDocument.textDocument.positionAt(node.root.offset + node.root.textLength - 2)
8098
},
81-
newText: ` "$defs": {\n "${newDefName}":${schemaDocument.textDocument.getText(range)}\n },\n`
99+
newText: `,\n "${defName}": {\n "${newDefName}": ${newFormattedDef}\n }`
82100
}
83101
])
84102
]

0 commit comments

Comments
 (0)