@@ -6,7 +6,12 @@ import { findProjectRootOfFileInDir } from "./utils";
6
6
export async function registerDynamicJsonValidation (
7
7
outputChannel ?: vscode . OutputChannel ,
8
8
) : Promise < vscode . Disposable > {
9
- // Use workspace text document change events to detect when ReScript config files are opened
9
+ // Ensure JSON extension is activated (so jsonDefaults is available)
10
+ const jsonExt = vscode . extensions . getExtension (
11
+ "vscode.json-language-features" ,
12
+ ) ;
13
+ await jsonExt ?. activate ( ) ;
14
+
10
15
const disposable = vscode . workspace . onDidOpenTextDocument (
11
16
async ( document ) => {
12
17
if ( document . languageId === "json" ) {
@@ -18,9 +23,8 @@ export async function registerDynamicJsonValidation(
18
23
} ,
19
24
) ;
20
25
21
- // Also check for already open documents
22
- const openDocuments = vscode . workspace . textDocuments ;
23
- for ( const document of openDocuments ) {
26
+ // Also check already open documents
27
+ for ( const document of vscode . workspace . textDocuments ) {
24
28
if ( document . languageId === "json" ) {
25
29
const fileName = path . basename ( document . uri . fsPath ) ;
26
30
if ( fileName === "rescript.json" || fileName === "bsconfig.json" ) {
@@ -38,60 +42,80 @@ async function tryEnableValidationForFile(
38
42
) : Promise < void > {
39
43
try {
40
44
const projectRootDir = findProjectRootOfFileInDir ( uri . fsPath ) ;
45
+ if ( ! projectRootDir ) {
46
+ return ;
47
+ }
41
48
42
- if ( projectRootDir ) {
43
- const schemaPath = path . join (
44
- projectRootDir ,
45
- "node_modules" ,
46
- "rescript" ,
47
- "docs" ,
48
- "docson" ,
49
- "build-schema.json" ,
50
- ) ;
49
+ const schemaPath = path . join (
50
+ projectRootDir ,
51
+ "node_modules" ,
52
+ "rescript" ,
53
+ "docs" ,
54
+ "docson" ,
55
+ "build-schema.json" ,
56
+ ) ;
57
+
58
+ if ( ! fs . existsSync ( schemaPath ) ) {
59
+ return ;
60
+ }
61
+
62
+ const absoluteSchemaPath = "file://" + schemaPath ;
63
+ const fileName = path . basename ( uri . fsPath ) ;
64
+
65
+ const jsonExt = vscode . extensions . getExtension (
66
+ "vscode.json-language-features" ,
67
+ ) ;
51
68
52
- if ( fs . existsSync ( schemaPath ) ) {
53
- const absoluteSchemaPath = "file://" + schemaPath ;
54
- const fileName = path . basename ( uri . fsPath ) ;
55
-
56
- // Add this schema to the user's JSON validation settings
57
- const config = vscode . workspace . getConfiguration ( ) ;
58
- const jsonSchemas =
59
- config . get < Array < { fileMatch : string [ ] ; url : string } > > (
60
- "json.schemas" ,
61
- ) || [ ] ;
62
-
63
- // Remove existing ReScript schemas for this specific file
64
- const filteredSchemas = jsonSchemas . filter (
65
- ( schema ) => ! schema . fileMatch || ! schema . fileMatch . includes ( fileName ) ,
66
- ) ;
67
-
68
- // Add our new schema configuration
69
- const updatedSchemas = [
70
- ...filteredSchemas ,
69
+ const jsonApi : any = await jsonExt ?. activate ( ) ;
70
+
71
+ if ( jsonApi ?. jsonDefaults ) {
72
+ // Preferred path: directly update JSON diagnostics options
73
+ jsonApi . jsonDefaults . setDiagnosticsOptions ( {
74
+ validate : true ,
75
+ schemas : [
71
76
{
72
77
fileMatch : [ fileName ] ,
73
- url : absoluteSchemaPath ,
78
+ uri : absoluteSchemaPath ,
74
79
} ,
75
- ] ;
80
+ ] ,
81
+ } ) ;
76
82
77
- // Update the configuration globally to avoid workspace pollution
78
- await config . update (
83
+ outputChannel ?. appendLine (
84
+ `Dynamic JSON schema applied for ${ fileName } : ${ absoluteSchemaPath } ` ,
85
+ ) ;
86
+ } else {
87
+ // Fallback: update workspace settings if jsonDefaults not available
88
+ const config = vscode . workspace . getConfiguration ( ) ;
89
+ const jsonSchemas =
90
+ config . get < Array < { fileMatch : string [ ] ; url : string } > > (
79
91
"json.schemas" ,
80
- updatedSchemas ,
81
- vscode . ConfigurationTarget . Global ,
82
- ) ;
92
+ ) || [ ] ;
83
93
84
- if ( outputChannel ) {
85
- outputChannel . appendLine ( `JSON validation enabled for ${ fileName } ` ) ;
86
- }
87
- }
88
- }
89
- } catch ( error ) {
90
- // Silently ignore errors to avoid annoying the user
91
- if ( outputChannel ) {
92
- outputChannel . appendLine (
93
- `Failed to enable JSON validation for ${ uri . fsPath } : ${ error } ` ,
94
+ const filteredSchemas = jsonSchemas . filter (
95
+ ( schema ) => ! schema . fileMatch || ! schema . fileMatch . includes ( fileName ) ,
96
+ ) ;
97
+
98
+ const updatedSchemas = [
99
+ ...filteredSchemas ,
100
+ {
101
+ fileMatch : [ fileName ] ,
102
+ url : absoluteSchemaPath ,
103
+ } ,
104
+ ] ;
105
+
106
+ await config . update (
107
+ "json.schemas" ,
108
+ updatedSchemas ,
109
+ vscode . ConfigurationTarget . Workspace ,
110
+ ) ;
111
+
112
+ outputChannel ?. appendLine (
113
+ `Fallback JSON schema configured for ${ fileName } via settings: ${ absoluteSchemaPath } ` ,
94
114
) ;
95
115
}
116
+ } catch ( error ) {
117
+ outputChannel ?. appendLine (
118
+ `Failed to enable JSON validation for ${ uri . fsPath } : ${ error } ` ,
119
+ ) ;
96
120
}
97
121
}
0 commit comments