Skip to content

Commit 8a75af8

Browse files
vepanimasintellij-monorepo-bot
authored andcommitted
[graphql] WEB-68173 remove legacy settings
GitOrigin-RevId: dde64a9fa5bd7afee6e97d711147e4082ace57da
1 parent 4ffc455 commit 8a75af8

File tree

10 files changed

+152
-171
lines changed

10 files changed

+152
-171
lines changed

resources/META-INF/plugin.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,15 @@
226226
<registryKey key="graphql.introspection.detect.schema.capabilities"
227227
defaultValue="[Adaptive*|Latest|Legacy]"
228228
description="Enables preliminary request to detect GraphQL server capabilities before schema introspection"/>
229+
<registryKey key="graphql.introspection.custom.query"
230+
defaultValue=""
231+
description="Defines a custom query for server introspection, overriding the default behavior"/>
232+
<registryKey key="graphql.introspection.skip.default.values"
233+
defaultValue="false"
234+
description="Improves compatibility with non-compliant endpoints by skipping default values, though this removes default value information from the schema"/>
235+
<registryKey key="graphql.introspection.include.empty.types"
236+
defaultValue="false"
237+
description="Determines whether empty types are included in the introspection result"/>
229238

230239
<!-- Inspections -->
231240
<localInspection language="GraphQL" key="graphql.inspection.display.name.unresolved.reference"

resources/messages/GraphQLBundle.properties

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ graphql.notification.introspection.unable.to.build.path=Unable to build a file p
1414
graphql.notification.error.title=GraphQL error
1515
graphql.notification.ssl.cert.error.title=SSL certificate error
1616
graphql.notification.show.query.error.details.action=Show error
17-
graphql.notification.retry.without.defaults=Retry (skip default values from now on)
1817
graphql.notification.retry=Retry
1918
graphql.notification.content.request.to.url.failed=GraphQL request to {0} failed.
2019
graphql.notification.unable.to.open.editor=Unable to open an editor for ''{0}''
@@ -177,13 +176,6 @@ graphql.inspection.group.schema=Schema
177176
graphql.settings.frameworks=Frameworks
178177

179178
graphql.settings.introspection=Introspection
180-
graphql.settings.introspection.query.label=Query
181-
graphql.settings.introspection.query.empty.text=Leave blank for default
182-
graphql.settings.introspection.query.tooltip=Use a different introspection query for cases where the GraphQL endpoint is incompatible with the plugin introspection query
183-
graphql.settings.introspection.default.values.label=Include argument default values in schema introspection
184-
graphql.settings.introspection.default.values.tooltip=Skipping default values improves interoperability with endpoints that don't follow the GraphQL specification for default values. The schema can still be used, but information about the default values will be unavailable
185-
graphql.settings.introspection.repeatable.directives.label=Request the "repeatable" property for directives
186-
graphql.settings.introspection.repeatable.directives.tooltip=Repeatable directives are a relatively new feature and may not be supported by some GraphQL implementations
187179
graphql.settings.introspection.open.editor.label=Open introspection results in the editor
188180

189181
# Libraries

src/main/com/intellij/lang/jsgraphql/GraphQLSettings.kt

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,6 @@ class GraphQLSettings : PersistentStateComponent<GraphQLSettingsState> {
2828

2929
/* Introspection */
3030

31-
var introspectionQuery: String
32-
get() = state.introspectionQuery
33-
set(introspectionQuery) {
34-
state.introspectionQuery = introspectionQuery
35-
}
36-
37-
var isEnableIntrospectionDefaultValues: Boolean
38-
get() = state.enableIntrospectionDefaultValues
39-
set(enableIntrospectionDefaultValues) {
40-
state.enableIntrospectionDefaultValues = enableIntrospectionDefaultValues
41-
}
42-
4331
var isOpenEditorWithIntrospectionResult: Boolean
4432
get() = state.openEditorWithIntrospectionResult
4533
set(openEditorWithIntrospectionResult) {
@@ -67,8 +55,6 @@ class GraphQLSettings : PersistentStateComponent<GraphQLSettingsState> {
6755
}
6856

6957
class GraphQLSettingsState {
70-
var introspectionQuery: String = ""
71-
var enableIntrospectionDefaultValues: Boolean = true
7258
var openEditorWithIntrospectionResult: Boolean = true
7359

7460
var enableRelayModernFrameworkSupport: Boolean = false

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionJsonToSDLLineMarkerProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public final class GraphQLIntrospectionJsonToSDLLineMarkerProvider implements Li
8585
NotificationType.ERROR
8686
).setImportant(true);
8787

88-
GraphQLNotificationUtil.addRetryQueryForPossiblyInvalidIntrospectionSchemaAction(project, notification, e, generateAction.get());
88+
GraphQLNotificationUtil.notifyAboutPossiblyInvalidIntrospectionSchema(notification, e);
8989
GraphQLNotificationUtil.addShowQueryErrorDetailsAction(project, notification, e);
9090
Notifications.Bus.notify(notification);
9191
}

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionQuery.kt

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@
22

33
package com.intellij.lang.jsgraphql.ide.introspection
44

5-
import com.google.gson.JsonArray
6-
import com.google.gson.JsonElement
7-
import com.google.gson.JsonObject
8-
import com.intellij.lang.jsgraphql.GraphQLBundle
95
import com.intellij.lang.jsgraphql.ide.introspection.GraphQLSchemaCapability.*
106
import java.util.*
117

@@ -145,77 +141,3 @@ val INTROSPECTION_SCHEMA_CAPABILITIES_QUERY: String = """
145141
}
146142
}
147143
""".trimIndent()
148-
149-
150-
internal fun parseSchemaCapabilities(introspectionResponse: JsonObject): EnumSet<GraphQLSchemaCapability> {
151-
val responseObject = if (introspectionResponse.has("data"))
152-
introspectionResponse.getAsJsonObject("data")!!
153-
else
154-
introspectionResponse
155-
156-
if (introspectionResponse.has("errors")) {
157-
throw IllegalArgumentException(
158-
GraphQLBundle.message(
159-
"graphql.introspection.capabilities.detection.failed.errors",
160-
introspectionResponse.get("errors")?.toString() ?: "[]"
161-
)
162-
)
163-
}
164-
165-
val typeDefinition = responseObject.getTypeNonNull("__Type")
166-
val fieldDefinition = responseObject.getTypeNonNull("__Field")
167-
val directiveDefinition = responseObject.getTypeNonNull("__Directive")
168-
val inputValueDefinition = responseObject.getTypeNonNull("__InputValue")
169-
170-
val capabilities = EnumSet.noneOf(GraphQLSchemaCapability::class.java)
171-
if (typeDefinition.hasArgument("inputFields", "includeDeprecated")) {
172-
capabilities.add(INCLUDE_DEPRECATED_INPUT_FIELDS)
173-
}
174-
if (fieldDefinition.hasArgument("args", "includeDeprecated")) {
175-
capabilities.add(INCLUDE_DEPRECATED_FIELD_ARGS)
176-
}
177-
if (directiveDefinition.hasArgument("args", "includeDeprecated")) {
178-
capabilities.add(INCLUDE_DEPRECATED_DIRECTIVE_ARGS)
179-
}
180-
if (inputValueDefinition.hasField("isDeprecated")) {
181-
capabilities.add(INPUT_VALUE_IS_DEPRECATED)
182-
}
183-
if (inputValueDefinition.hasField("deprecationReason")) {
184-
capabilities.add(INPUT_VALUE_DEPRECATION_REASON)
185-
}
186-
if (inputValueDefinition.hasField("defaultValue")) {
187-
capabilities.add(INPUT_VALUE_DEFAULT_VALUE)
188-
}
189-
if (directiveDefinition.hasField("isRepeatable")) {
190-
capabilities.add(DIRECTIVE_IS_REPEATABLE)
191-
}
192-
return capabilities
193-
}
194-
195-
private fun JsonElement.getTypeNonNull(typeName: String): JsonObject =
196-
getType(typeName) ?: throw IllegalArgumentException("Missing $typeName type definition in introspection response")
197-
198-
private fun JsonElement.getType(typeName: String): JsonObject? {
199-
if (!isJsonObject) return null
200-
val schema = asJsonObject.get("__schema") as? JsonObject
201-
val typesElement = schema?.get("types") as? JsonArray
202-
return typesElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == typeName } as? JsonObject
203-
}
204-
205-
private fun JsonElement.getField(fieldName: String): JsonObject? {
206-
if (!isJsonObject) return null
207-
val fieldsElement = asJsonObject.get("fields") as? JsonArray
208-
return fieldsElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == fieldName } as? JsonObject
209-
}
210-
211-
private fun JsonElement.getArgument(fieldName: String, argName: String): JsonObject? {
212-
val typeField = getField(fieldName)
213-
val argsElement = typeField?.get("args") as? JsonArray
214-
return argsElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == argName } as? JsonObject
215-
}
216-
217-
private fun JsonElement.hasField(fieldName: String): Boolean =
218-
getField(fieldName) != null
219-
220-
private fun JsonElement.hasArgument(fieldName: String, argName: String): Boolean =
221-
getArgument(fieldName, argName) != null

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionQueryExecutor.kt

Lines changed: 81 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.intellij.lang.jsgraphql.ide.introspection
22

3+
import com.google.gson.JsonArray
4+
import com.google.gson.JsonElement
5+
import com.google.gson.JsonObject
36
import com.intellij.lang.jsgraphql.GraphQLBundle
4-
import com.intellij.lang.jsgraphql.GraphQLSettings
5-
import com.intellij.lang.jsgraphql.GraphQLSettings.Companion.getSettings
67
import com.intellij.lang.jsgraphql.ide.config.model.GraphQLConfigEndpoint
78
import com.intellij.lang.jsgraphql.ide.introspection.GraphQLQueryRunner.Companion.parseResponseJson
89
import com.intellij.lang.jsgraphql.ide.introspection.GraphQLQueryRunner.Companion.prepareQueryPayload
10+
import com.intellij.lang.jsgraphql.ide.introspection.GraphQLSchemaCapability.*
911
import com.intellij.lang.jsgraphql.ide.notifications.handleIntrospectionError
1012
import com.intellij.openapi.application.EDT
1113
import com.intellij.openapi.components.Service
@@ -54,7 +56,7 @@ class GraphQLIntrospectionQueryExecutor(private val project: Project, private va
5456
LOG.warn("Unable to request schema capabilities for endpoint '${endpoint.url ?: "null"}'")
5557
return@withBackgroundProgress
5658
}
57-
val introspectionQuery = composeIntrospectionQuery(capabilities, getSettings(project))
59+
val introspectionQuery = composeIntrospectionQuery(capabilities)
5860
val rawIntrospectionResponse = withContext(Dispatchers.IO) {
5961
val queryRunner = GraphQLQueryRunner.getInstance(project)
6062
queryRunner.sendRequest(endpoint, prepareQueryPayload(introspectionQuery), retry)
@@ -134,20 +136,93 @@ class GraphQLIntrospectionQueryExecutor(private val project: Project, private va
134136
}
135137
}
136138

137-
private fun composeIntrospectionQuery(capabilities: EnumSet<GraphQLSchemaCapability>, settings: GraphQLSettings): String {
138-
val query = settings.introspectionQuery
139+
private fun composeIntrospectionQuery(capabilities: EnumSet<GraphQLSchemaCapability>): String {
140+
val query = Registry.stringValue("graphql.introspection.custom.query")
139141
if (query.isNotBlank()) {
140142
return query
141143
}
142144

143145
// this is still needed since we can have an issue with parsing values returned from server,
144146
// especially for custom JSON types, more https://github.com/JetBrains/js-graphql-intellij-plugin/issues/217
145-
if (!settings.isEnableIntrospectionDefaultValues) {
147+
if (Registry.`is`("graphql.introspection.skip.default.values")) {
146148
capabilities.remove(GraphQLSchemaCapability.INPUT_VALUE_DEFAULT_VALUE)
147149
}
148150

149151
return buildIntrospectionQueryFromTemplate(capabilities)
150152
}
153+
154+
private fun parseSchemaCapabilities(introspectionResponse: JsonObject): EnumSet<GraphQLSchemaCapability> {
155+
val responseObject = if (introspectionResponse.has("data"))
156+
introspectionResponse.getAsJsonObject("data")!!
157+
else
158+
introspectionResponse
159+
160+
if (introspectionResponse.has("errors")) {
161+
throw IllegalArgumentException(
162+
GraphQLBundle.message(
163+
"graphql.introspection.capabilities.detection.failed.errors",
164+
introspectionResponse.get("errors")?.toString() ?: "[]"
165+
)
166+
)
167+
}
168+
169+
val typeDefinition = responseObject.getTypeNonNull("__Type")
170+
val fieldDefinition = responseObject.getTypeNonNull("__Field")
171+
val directiveDefinition = responseObject.getTypeNonNull("__Directive")
172+
val inputValueDefinition = responseObject.getTypeNonNull("__InputValue")
173+
174+
val capabilities = EnumSet.noneOf(GraphQLSchemaCapability::class.java)
175+
if (typeDefinition.hasArgument("inputFields", "includeDeprecated")) {
176+
capabilities.add(INCLUDE_DEPRECATED_INPUT_FIELDS)
177+
}
178+
if (fieldDefinition.hasArgument("args", "includeDeprecated")) {
179+
capabilities.add(INCLUDE_DEPRECATED_FIELD_ARGS)
180+
}
181+
if (directiveDefinition.hasArgument("args", "includeDeprecated")) {
182+
capabilities.add(INCLUDE_DEPRECATED_DIRECTIVE_ARGS)
183+
}
184+
if (inputValueDefinition.hasField("isDeprecated")) {
185+
capabilities.add(INPUT_VALUE_IS_DEPRECATED)
186+
}
187+
if (inputValueDefinition.hasField("deprecationReason")) {
188+
capabilities.add(INPUT_VALUE_DEPRECATION_REASON)
189+
}
190+
if (inputValueDefinition.hasField("defaultValue")) {
191+
capabilities.add(INPUT_VALUE_DEFAULT_VALUE)
192+
}
193+
if (directiveDefinition.hasField("isRepeatable")) {
194+
capabilities.add(DIRECTIVE_IS_REPEATABLE)
195+
}
196+
return capabilities
197+
}
198+
199+
private fun JsonElement.getTypeNonNull(typeName: String): JsonObject =
200+
getType(typeName) ?: throw IllegalArgumentException("Missing $typeName type definition in introspection response")
201+
202+
private fun JsonElement.getType(typeName: String): JsonObject? {
203+
if (!isJsonObject) return null
204+
val schema = asJsonObject.get("__schema") as? JsonObject
205+
val typesElement = schema?.get("types") as? JsonArray
206+
return typesElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == typeName } as? JsonObject
207+
}
208+
209+
private fun JsonElement.getField(fieldName: String): JsonObject? {
210+
if (!isJsonObject) return null
211+
val fieldsElement = asJsonObject.get("fields") as? JsonArray
212+
return fieldsElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == fieldName } as? JsonObject
213+
}
214+
215+
private fun JsonElement.getArgument(fieldName: String, argName: String): JsonObject? {
216+
val typeField = getField(fieldName)
217+
val argsElement = typeField?.get("args") as? JsonArray
218+
return argsElement?.find { it.isJsonObject && it.asJsonObject.get("name")?.asString == argName } as? JsonObject
219+
}
220+
221+
private fun JsonElement.hasField(fieldName: String): Boolean =
222+
getField(fieldName) != null
223+
224+
private fun JsonElement.hasArgument(fieldName: String, argName: String): Boolean =
225+
getArgument(fieldName, argName) != null
151226
}
152227

153228
private enum class GraphQLSchemaCapabilitiesDetectionStrategy {

src/main/com/intellij/lang/jsgraphql/ide/introspection/GraphQLIntrospectionService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.intellij.openapi.project.Project;
4848
import com.intellij.openapi.util.Ref;
4949
import com.intellij.openapi.util.io.FileUtil;
50+
import com.intellij.openapi.util.registry.Registry;
5051
import com.intellij.openapi.util.text.StringUtil;
5152
import com.intellij.openapi.vfs.LocalFileSystem;
5253
import com.intellij.openapi.vfs.VirtualFile;
@@ -199,7 +200,7 @@ private boolean isEndpointConfigurationValid(GraphQLConfigEndpoint endpoint) {
199200
public static @NotNull String printIntrospectionAsGraphQL(@NotNull Project project, @NotNull Map<String, Object> introspection) {
200201
introspection = getIntrospectionSchemaDataFromParsedResponse(introspection);
201202

202-
if (!GraphQLSettings.getSettings(project).isEnableIntrospectionDefaultValues()) {
203+
if (Registry.is("graphql.introspection.skip.default.values")) {
203204
// strip out the defaultValues that are potentially non-spec compliant
204205
Ref<Consumer<Object>> defaultValueVisitJson = Ref.create();
205206
defaultValueVisitJson.set((value) -> {
@@ -219,6 +220,7 @@ else if (value instanceof Map) {
219220
.defaultOptions()
220221
.includeScalarTypes(true)
221222
.includeSchemaDefinition(true)
223+
.includeEmptyTypes(false)
222224
.includeDirectives(directive -> !GraphQLKnownTypes.DEFAULT_DIRECTIVES.contains(directive.getName()));
223225

224226
GraphQLRegistryInfo registryInfo = new GraphQLRegistryInfo(new SchemaParser().buildRegistry(schemaDefinition), false);

src/main/com/intellij/lang/jsgraphql/ide/notifications/GraphQLNotificationUtil.kt

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package com.intellij.lang.jsgraphql.ide.notifications
44

55
import com.intellij.lang.jsgraphql.GraphQLBundle
66
import com.intellij.lang.jsgraphql.GraphQLConstants
7-
import com.intellij.lang.jsgraphql.GraphQLSettings
87
import com.intellij.lang.jsgraphql.ide.config.model.GraphQLConfigEndpoint
98
import com.intellij.lang.jsgraphql.ide.introspection.GraphQLIntrospectionService
109
import com.intellij.lang.jsgraphql.types.GraphQLException
@@ -14,7 +13,6 @@ import com.intellij.notification.NotificationAction
1413
import com.intellij.notification.NotificationType
1514
import com.intellij.notification.Notifications
1615
import com.intellij.openapi.actionSystem.AnActionEvent
17-
import com.intellij.openapi.application.ApplicationManager
1816
import com.intellij.openapi.diagnostic.fileLogger
1917
import com.intellij.openapi.fileEditor.FileEditorManager
2018
import com.intellij.openapi.fileEditor.OpenFileDescriptor
@@ -72,35 +70,9 @@ fun addShowQueryErrorDetailsAction(project: Project, notification: Notification,
7270
})
7371
}
7472

75-
fun addRetryQueryForPossiblyInvalidIntrospectionSchemaAction(
76-
project: Project,
77-
notification: Notification,
78-
e: Exception,
79-
retry: Runnable,
80-
) {
81-
if (e !is GraphQLException) return
82-
notification.setContent(GraphQLBundle.message("graphql.notification.introspection.spec.error.body"))
83-
addRetryQueryWithoutDefaultValuesAction(notification, GraphQLSettings.getSettings(project), retry)
84-
}
85-
86-
private fun addRetryQueryWithoutDefaultValuesAction(
87-
notification: Notification,
88-
settings: GraphQLSettings,
89-
retry: Runnable,
90-
) {
91-
if (settings.isEnableIntrospectionDefaultValues) {
92-
// suggest retrying without the default values as they're a common cause of spec compliance issues
93-
val retryWithoutDefaultValues: NotificationAction = object : NotificationAction(
94-
GraphQLBundle.message("graphql.notification.retry.without.defaults")
95-
) {
96-
override fun actionPerformed(e: AnActionEvent, notification: Notification) {
97-
settings.isEnableIntrospectionDefaultValues = false
98-
ApplicationManager.getApplication().saveSettings()
99-
notification.expire()
100-
retry.run()
101-
}
102-
}
103-
notification.addAction(retryWithoutDefaultValues)
73+
internal fun notifyAboutPossiblyInvalidIntrospectionSchema(notification: Notification, e: Exception) {
74+
if (e is GraphQLException) {
75+
notification.setContent(GraphQLBundle.message("graphql.notification.introspection.spec.error.body"))
10476
}
10577
}
10678

@@ -168,9 +140,7 @@ fun handleIntrospectionError(
168140
addRetryQueryAction(notification) {
169141
GraphQLIntrospectionService.getInstance(project).performIntrospectionQuery(endpoint)
170142
}
171-
addRetryQueryForPossiblyInvalidIntrospectionSchemaAction(project, notification, e) {
172-
GraphQLIntrospectionService.getInstance(project).performIntrospectionQuery(endpoint)
173-
}
143+
notifyAboutPossiblyInvalidIntrospectionSchema(notification, e)
174144
addShowQueryErrorDetailsAction(project, notification, e)
175145
Notifications.Bus.notify(notification, project)
176146

0 commit comments

Comments
 (0)